Page MenuHomePhabricator

Block API: Add support for multiblocks
Closed, ResolvedPublic

Description

Background

The Block API currently assumes $wgEnableMultiBlocks is false, and provides no means to modify a specific block, and a means to add an additional block to a user.

For the Unblock API, see T378148.

Acceptance criteria

Request with id param
If set then the block with this ID is updated with the new data.
If a user param is also sent, error
If the block ID doesn't exist, error
If newblock or reblock is passed, error

Request with no id param
If no block exists for the user, then add a new block
If one block exists for the user and the reblock param is true, update the user's block
If >=1 blocks exist for the user and the newblock param is unset, error
If >=1 blocks exist for the user and the newblock param is set, add a new block
If >=1 blocks exist for the user and the newblock param is set, and an existing block with the identical details exists, error (nice to have)

We need reblock for backward compatibility. We also need newblock for this, because otherwise 3rd-party users who are depending on getting an error when they add >1 block might inadvertently add multiple blocks when they didn't intend to

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

Is this suggesting an admin can search a block via blockID?

Is this suggesting an admin can search a block via blockID?

I am only suggesting being able to provide it in the URL, so not quite a "search" per-se. Most admins won't know the block ID, and nor should they have to. Instead, you'll see "change block" links such as at the top of Special:Contribs/BlockedUser, and that link will have the ?blockid=123 in the URL.

Cparle updated the task description. (Show Details)
Cparle updated the task description. (Show Details)

We talked a bit the other day about how to interpret having both a user and blockid param, and I think we decided to throw an error if both are provided. The description currently says "No need for a username/ip", but I don't think we want to support changing the target of a block, so I'll change that.

Change #1099149 had a related patch set uploaded (by Samwilson; author: Samwilson):

[mediawiki/core@master] ApiBlock: Start adding multiblocks support to the action=block API

https://gerrit.wikimedia.org/r/1099149

I thought about adding the new parameters conditionally based on $wgEnableMultiBlocks. But they all have a fairly obvious interpretation with multiblocks disabled. I think it will make things easier for clients if we accept the new parameters unconditionally.

Change #1102468 had a related patch set uploaded (by Tim Starling; author: Tim Starling):

[mediawiki/core@master] block: Multiblocks block API

https://gerrit.wikimedia.org/r/1102468

Change #1099149 abandoned by Samwilson:

[mediawiki/core@master] ApiBlock: Start adding multiblocks support to the action=block API

Reason:

https://gerrit.wikimedia.org/r/c/mediawiki/core/+/1102468

https://gerrit.wikimedia.org/r/1099149

Change #1102468 merged by jenkins-bot:

[mediawiki/core@master] block: Multiblocks block API

https://gerrit.wikimedia.org/r/1102468

I'm getting this exception when I make an action=block request passing in only values for user and expiry (and token of course):

{
    "error": {
        "code": "internal_api_error_InvalidArgumentException",
        "info": "[fe50ccb370f83414ee088277] Exception caught: Wikimedia\\Rdbms\\Platform\\SQLPlatform::makeList: empty input for field bt_id",
        "errorclass": "InvalidArgumentException",
        "trace": "InvalidArgumentException at /var/www/html/w/includes/libs/rdbms/platform/SQLPlatform.php(257)\nfrom /var/www/html/w/includes/libs/rdbms/platform/SQLPlatform.php(257)\n#0 /var/www/html/w/includes/libs/rdbms/platform/SQLPlatform.php(1634): Wikimedia\\Rdbms\\Platform\\SQLPlatform->makeList()\n#1 /var/www/html/w/includes/libs/rdbms/database/Database.php(1525): Wikimedia\\Rdbms\\Platform\\SQLPlatform->updateSqlText()\n#2 /var/www/html/w/includes/libs/rdbms/database/DBConnRef.php(127): Wikimedia\\Rdbms\\Database->update()\n#3 /var/www/html/w/includes/libs/rdbms/database/DBConnRef.php(413): Wikimedia\\Rdbms\\DBConnRef->__call()\n#4 /var/www/html/w/includes/libs/rdbms/querybuilder/UpdateQueryBuilder.php(335): Wikimedia\\Rdbms\\DBConnRef->update()\n#5 /var/www/html/w/includes/block/DatabaseBlockStore.php(899): Wikimedia\\Rdbms\\UpdateQueryBuilder->execute()\n#6 /var/www/html/w/includes/block/DatabaseBlockStore.php(872): MediaWiki\\Block\\DatabaseBlockStore->releaseTargets()\n#7 /var/www/html/w/includes/block/DatabaseBlockStore.php(1049): MediaWiki\\Block\\DatabaseBlockStore->deleteBlockRows()\n#8 /var/www/html/w/includes/block/DatabaseBlockStore.php(962): MediaWiki\\Block\\DatabaseBlockStore->purgeExpiredConflicts()\n#9 /var/www/html/w/includes/block/BlockUser.php(668): MediaWiki\\Block\\DatabaseBlockStore->insertBlock()\n#10 /var/www/html/w/includes/block/BlockUser.php(583): MediaWiki\\Block\\BlockUser->placeBlockInternal()\n#11 /var/www/html/w/includes/block/BlockUser.php(509): MediaWiki\\Block\\BlockUser->placeBlockUnsafe()\n#12 /var/www/html/w/includes/api/ApiBlock.php(306): MediaWiki\\Block\\BlockUser->placeBlock()\n#13 /var/www/html/w/includes/api/ApiBlock.php(142): MediaWiki\\Api\\ApiBlock->insertBlock()\n#14 /var/www/html/w/includes/api/ApiMain.php(1976): MediaWiki\\Api\\ApiBlock->execute()\n#15 /var/www/html/w/includes/api/ApiMain.php(944): MediaWiki\\Api\\ApiMain->executeAction()\n#16 /var/www/html/w/includes/api/ApiMain.php(915): MediaWiki\\Api\\ApiMain->executeActionWithErrorHandling()\n#17 /var/www/html/w/includes/api/ApiEntryPoint.php(153): MediaWiki\\Api\\ApiMain->execute()\n#18 /var/www/html/w/includes/MediaWikiEntryPoint.php(201): MediaWiki\\Api\\ApiEntryPoint->execute()\n#19 /var/www/html/w/api.php(44): MediaWiki\\MediaWikiEntryPoint->run()\n#20 {main}"
    },
    "servedby": "996db08415e7"
}

The account I tested on was unblocked, but had been previously multi-blocked. I may have corrupt data on my machine, as I can't seem to repro with a fresh account, even if they are/were multiblocked. I thought I'd still share this in case the error sounds familiar or something worth guarding against.

dom_walden subscribed.

I have tested raising various blocks with different parameters. The blocks appears to be correctly created and the validation seems sensible and consistent.

I can confirm all the acceptance criteria have been satisfied.

If >=1 blocks exist for the user and the newblock param is set, and an existing block with the identical details exists, error (nice to have)

This has been implemented. You can sort of get around it, though, if you have two existing blocks you can use the id parameter to update one block to have the exact same parameters as the other block. I don't know if this is a big enough problem to be worth guarding against.

I mostly tested this on my local docker with $wgEnableMultiBlocks = true;. I haven't done much testing with multiblocks disabled, except that I note that the id parameter allows you to update an existing block when multiblocks is disabled.

I'm getting this exception when I make an action=block request passing in only values for user and expiry (and token of course):

I guess this is the same bug as T382881.

Change #1124917 had a related patch set uploaded (by Tim Starling; author: Tim Starling):

[mediawiki/core@master] block: Hard-deprecate BlockUser::placeBlock(true)

https://gerrit.wikimedia.org/r/1124917

Change #1124917 abandoned by Tim Starling:

[mediawiki/core@master] block: Hard-deprecate BlockUser::placeBlock(true)

Reason:

Has to wait until $wgEnableMultiBlocks defaults to true since it's still being called by the old Special:Block

https://gerrit.wikimedia.org/r/1124917