Greetings,

Have you written code that deals with or depends on user blocks? Read on.

= TL;DR: =

The new “Partial Blocks” feature has fundamentally changed the way MediaWiki considers what “block” means; any code that handles blocks should consider whether the questions it is asking are still valid or should adjust its expectations. Please read for more details.

= Preamble =

A couple of months ago, as part of the Anti Harassment Tools team’s continued work on improving the general experience of our users and providing more robust tools to administrators, an RFC to enable “Partial Blocks[1]” has passed and has been implemented in MediaWiki, affecting the way blocking users operates.

While the actual feature, enabling the blocking of users for specific pages and namespaces, will be slowly rolled out as part of our rollout and testing plans, the change has resulted in a complete change of paradigm for what “block” means throughout our code.

= Change of paradigm =

Until recently, Block was fairly straight forward; whether a block was done on an IP range or a specific user, the question the code would ask is “is the user blocked from this action” and the answer will be a boolean yes or no, depending on whether the user was blocked from the wiki and whether the action was a blockable action.

With the new Partial Blocks feature, that question is now more elaborate. We are giving admins and wikis in general much more robust options when deciding to block IPs or users. “Sitewide” block is no longer the only option. Now, a user can be blocked from editing a specific page, and soon from a specific namespace. There are also blocks that prevent a specific action, such as uploading files or creating new pages.

This means that the question “is the user blocked” is no longer accurate. In most cases, the question should be “is the user blocked from the action on this page”, because users may receive a block that is not sitewide, but from a specific page or set of pages.

= What we worked on =

The Anti Harassment Tools team has been working diligently on making sure that the new blocking behavior does not produce obvious regressions in production, and does not add to any still existing inconsistencies. In cases where we identified a clear mismatch, we’ve tried to either fix it outright or alert the code owners to adjust.

If we have missed any iteration or use-case, please open a Phabricator ticket and add the ‘anti-harassment’[2] tag to it. If the use-case is sensitive or identifies a current loop-hole in the way blocks work, please make it a security ticket and alert us and the relevant team immediately.

= General steps forward =

While the team is following up on making the code clear and robust and fixing what we’ve identified as paradigm-changes to deal with, there are still many instances where the changes required to the code are not straight-forward or clear. Some extensions ask whether a user is blocked and may need to change the way that the product’s “business logic” behaves. 

These are cases where we cannot make the decision for the codebase. We encourage you to look at your product and consider adjusting if necessary.

= General guidance =

We’ve identified some areas that may help code owners adjust their products to properly take advantage of the new feature and adjust to the new paradigm change. This list is not exhaustive, but may help you spot areas in your code that can easily be changed:

* User::isBlocked() has changed its meaning, and its use cases should be re-examined depending on what your code intends to check. 
For the most part, if there’s a Title object available, User::isBlockedFrom() is a good option. Otherwise, consider using User::getBlock() and Block::isSitewide()
* Block::prevents( ‘edit’ ) is an operation that doesn’t make sense anymore, because a block on the ‘edit’ action now depends on context (the title).
* Determining whether a block prevents a user from editing their own user talk page has changed. 
For a sitewide block, if the $wgBlockAllowsUTEdit config is false, then the block prevents the user editing their user talk page, but if it is true, then whether they can edit their user talk page depends on the ipb_allow_usertalk flag on the block. For a partial block to a page or pages, these flags are not taken into account: if the user’s talk page is specified as a blocked page, then they cannot edit their user talk page; if it is not, then they can edit it. Block::prevents( ‘editownuserpage’ ) should therefore not be checked for a partial page block[3].  We plan to deprecate that parameter officially, please consider if this affects your code. 
* Please check that any classes that extend Action or FormSpecialPage return the correct value for requiresUnblock().

To summarize, in general, the meaning of asking whether a block exists has changed, and any code piece that needs this information should adjust itself to account for partial blocks, depending on its goals.

Thank you,

Moriel, on behalf of the Anti Harassment Tools Team

References:
[1] Partial blocks: https://meta.wikimedia.org/wiki/Community_health_initiative/Per-user_page,_namespace,_and_upload_blocking
[2] Anti Harassment tools board: https://phabricator.wikimedia.org/project/view/2660/
[3] For a discussion of this, see: https://phabricator.wikimedia.org/T210475




--

Moriel Schottlender (she/her)

Senior Software Engineer, Tech Lead

Community Tech and Anti Harassment Tools

@mooeypoo (IRC / Phabricator)