Page MenuHomePhabricator

Add ArchivedRevisionHandler endpoint for use with deleted revisions
Closed, ResolvedPublic

Description

This is separated out from T318463: IP Info accordion should show up on the Special:DeletedContributions.

ArchivedRevisionHandler should return IP information, given an ID for a deleted revision.

Since there is already a lot of duplication between LogHandler and RevisionHandler, this would be a good time to refactor those classes and extract common permission checks, data filtering and logging into a parent class.

Event Timeline

Change 867203 had a related patch set uploaded (by Tchanders; author: Tchanders):

[mediawiki/extensions/IPInfo@master] Introduce ArchivedRevisionHandler for SpecialDeletedContributions

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

Change 867203 merged by jenkins-bot:

[mediawiki/extensions/IPInfo@master] Introduce ArchivedRevisionHandler for SpecialDeletedContributions

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

Change 868642 had a related patch set uploaded (by Tchanders; author: Tchanders):

[mediawiki/extensions/IPInfo@master] Add permissions check to ArchivedRevisionHandler

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

Change 868642 merged by jenkins-bot:

[mediawiki/extensions/IPInfo@master] Add permissions check to ArchivedRevisionHandler

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

@Tchanders If I pass a non-archived revision to the archivedrevision endpoint (for example https://en.wikipedia.beta.wmflabs.org/w/rest.php/ipinfo/v0/archivedrevision/569579?dataContext=infobox), I get the exception:

{
  "message": "Error: exception of type TypeError: Argument 1 passed to MediaWiki\\Revision\\RevisionStore::newRevisionFromArchiveRowAndSlots() must be an instance of stdClass, bool given, called in /srv/mediawiki/php-master/includes/Revision/RevisionStore.php on line 1586",
  "exception": {
    "id": "Y6LDy0OCiGHCGVgQwVrKwgAAAA8",
    "type": "TypeError",
    "file": "/srv/mediawiki/php-master/includes/Revision/RevisionStore.php",
    "line": 1629,
    "message": "Argument 1 passed to MediaWiki\\Revision\\RevisionStore::newRevisionFromArchiveRowAndSlots() must be an instance of stdClass, bool given, called in /srv/mediawiki/php-master/includes/Revision/RevisionStore.php on line 1586",
    "code": 0,
    "url": "/w/rest.php/ipinfo/v0/archivedrevision/569579?dataContext=infobox",
    "caught_by": "other",
    "backtrace": [
      {
        "file": "/srv/mediawiki/php-master/includes/Revision/RevisionStore.php",
        "line": 1586,
        "function": "newRevisionFromArchiveRowAndSlots",
        "class": "MediaWiki\\Revision\\RevisionStore",
        "type": "->",
        "args": [
          "boolean",
          "NULL",
          "integer",
          "NULL",
          "array"
        ]
      },
      {
        "file": "/srv/mediawiki/php-master/extensions/IPInfo/src/Rest/Handler/ArchivedRevisionHandler.php",
        "line": 119,
        "function": "newRevisionFromArchiveRow",
        "class": "MediaWiki\\Revision\\RevisionStore",
        "type": "->",
        "args": [
          "boolean"
        ]
      },
      {
        "file": "/srv/mediawiki/php-master/extensions/IPInfo/src/Rest/Handler/AbstractRevisionHandler.php",
        "line": 16,
        "function": "getRevision",
        "class": "MediaWiki\\IPInfo\\Rest\\Handler\\ArchivedRevisionHandler",
        "type": "->",
        "args": [
          "integer"
        ]
      },
      {
        "file": "/srv/mediawiki/php-master/extensions/IPInfo/src/Rest/Handler/IPInfoHandler.php",
        "line": 151,
        "function": "getInfo",
        "class": "MediaWiki\\IPInfo\\Rest\\Handler\\AbstractRevisionHandler",
        "type": "->",
        "args": [
          "integer"
        ]
      },
      {
        "file": "/srv/mediawiki/php-master/includes/Rest/SimpleHandler.php",
        "line": 38,
        "function": "run",
        "class": "MediaWiki\\IPInfo\\Rest\\Handler\\IPInfoHandler",
        "type": "->",
        "args": [
          "integer"
        ]
      },
      {
        "file": "/srv/mediawiki/php-master/includes/Rest/Router.php",
        "line": 487,
        "function": "execute",
        "class": "MediaWiki\\Rest\\SimpleHandler",
        "type": "->",
        "args": []
      },
      {
        "file": "/srv/mediawiki/php-master/includes/Rest/Router.php",
        "line": 406,
        "function": "executeHandler",
        "class": "MediaWiki\\Rest\\Router",
        "type": "->",
        "args": [
          "MediaWiki\\IPInfo\\Rest\\Handler\\ArchivedRevisionHandler"
        ]
      },
      {
        "file": "/srv/mediawiki/php-master/includes/Rest/EntryPoint.php",
        "line": 191,
        "function": "execute",
        "class": "MediaWiki\\Rest\\Router",
        "type": "->",
        "args": [
          "MediaWiki\\Rest\\RequestFromGlobals"
        ]
      },
      {
        "file": "/srv/mediawiki/php-master/includes/Rest/EntryPoint.php",
        "line": 131,
        "function": "execute",
        "class": "MediaWiki\\Rest\\EntryPoint",
        "type": "->",
        "args": []
      },
      {
        "file": "/srv/mediawiki/php-master/rest.php",
        "line": 31,
        "function": "main",
        "class": "MediaWiki\\Rest\\EntryPoint",
        "type": "::",
        "args": []
      },
      {
        "file": "/srv/mediawiki/w/rest.php",
        "line": 3,
        "args": [
          "string"
        ],
        "function": "require"
      }
    ]
  },
  "httpCode": 500,
  "httpReason": "Internal Server Error"
}

I tested that permissions were appropriately being checked by comparing the IPInfo archivedrevision endpoint with the ?action=query&prop=deletedrevisions API. If the editor/IP of a revision is hidden from the user in the API request they should not be able to look up IPInfo for that revision nor be told the IP address.

Instead, they get a 403 Forbidden error (English message: Your account does not have access to view the author of the revision).

I partitioned the revisions in the revision and archive table based on their permissions/visibility and chose a random sample from each partition. I believe each possible visibility combination a revision can have was tested on my local wiki. I also did it on dewiki, enwikisource, zhwiki and commons beta (although not all combinations were available on beta).

Test environments:

  • local wiki IP Info 0.0.0 (e25c22f) 08:15, 21 December 2022.
  • beta wikis IP Info 0.0.0 (7ae7f99) 08:43, 2 January 2023.