Page MenuHomePhabricator

Use of userrights-interwiki is no longer possible through the API after 1.41
Closed, ResolvedPublicBUG REPORT

Description

Steps to replicate the issue (include links if applicable):

  • Attempt to modify userrights on a different wiki using the API, for example:
{
  "action": "userrights",
  "format": "json",
  "user": "Void@loginwiki",
  "add": "sysop",
  "expiry": "1 minute",
  "reason": "testing API"
}

What happens?:

The API request fails with the contents:

{
    "error": {
        "code": "internal_api_error_Wikimedia\\Assert\\PreconditionException",
        "info": "[c21a9dd7975bac4712ea8f68] Caught exception of type Wikimedia\\Assert\\PreconditionException",
        "errorclass": "Wikimedia\\Assert\\PreconditionException"
    },
    "servedby": "mw"
}

The stack trace from the logs is:

Expected MediaWiki\User\UserIdentityValue to belong to the local wiki, but it belongs to 'loginwiki'
from /srv/mediawiki/1.41/includes/dao/WikiAwareEntityTrait.php(59)
#0 /srv/mediawiki/1.41/includes/user/UserIdentityValue.php(139): MediaWiki\User\UserIdentityValue->assertWiki(boolean)
#1 /srv/mediawiki/1.41/includes/api/ApiUserrights.php(142): MediaWiki\User\UserIdentityValue->getId()
#2 /srv/mediawiki/1.41/includes/api/ApiMain.php(1936): ApiUserrights->execute()
#3 /srv/mediawiki/1.41/includes/api/ApiMain.php(912): ApiMain->executeAction()
#4 /srv/mediawiki/1.41/includes/api/ApiMain.php(883): ApiMain->executeActionWithErrorHandling()
#5 /srv/mediawiki/1.41/api.php(95): ApiMain->execute()
#6 /srv/mediawiki/1.41/api.php(48): wfApiMain()
#7 /srv/mediawiki/config/initialise/entrypoints/api.php(3): require(string)
#8 {main}

What should have happened instead?:

The API request should have succeeded and modified the user groups of the user on the remote wiki.

Software version (on Special:Version page; skip for WMF-hosted wikis like Wikipedia):

1.41.0 (5498056)

Comments

Looks like this is related to the replacement of UserRightsProxy in SpecialUserRights::fetchUser with UserIdentityValue. UserRightsProxy::getId takes an optional $wikiId parameter that it simply discards, returning the ID of the remote user. On the other hand, UserIdentityValue::getId takes the same optional parameter, failing if the specified wikiId is different from the wikiId of the user identity. However, the default wikiId is the local wiki, which means that calling getId with no parameters for a remote user will always fail. I'm not sure if the proper handling is to alter ApiUserrights to do $user->getId( $user->getWikiId() ); or to have UserIdentityValue::getId default to the identity's own wikiId.

Related Objects

Event Timeline

Change #1020921 had a related patch set uploaded (by Umherirrender; author: Umherirrender):

[mediawiki/core@master] api: Pass wikiId to UserIdentity instance for action=userrights

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

Change #1020921 merged by jenkins-bot:

[mediawiki/core@master] api: Pass wikiId to UserIdentity instance for action=userrights

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

Change #1021792 had a related patch set uploaded (by Zabe; author: Umherirrender):

[mediawiki/core@REL1_41] api: Pass wikiId to UserIdentity instance for action=userrights

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

Change #1021793 had a related patch set uploaded (by Zabe; author: Umherirrender):

[mediawiki/core@REL1_42] api: Pass wikiId to UserIdentity instance for action=userrights

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

Change #1021792 merged by jenkins-bot:

[mediawiki/core@REL1_41] api: Pass wikiId to UserIdentity instance for action=userrights

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

Change #1021793 merged by jenkins-bot:

[mediawiki/core@REL1_42] api: Pass wikiId to UserIdentity instance for action=userrights

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