Perhaps of interest to others. The use cases for partial blocks with which I'm most familiar are on ENWP, which is why I'm including the ENWP and Wikipedia mailing lists in this forward.
Pine ( https://meta.wikimedia.org/wiki/User:Pine )
---------- Forwarded message --------- From: Alex Ezell aezell@wikimedia.org Date: Fri, Nov 2, 2018 at 7:58 PM Subject: [Wikitech-l] Changes to User Blocking To: wikitech-l@lists.wikimedia.org
Hi all, I'm Alex Ezell and I'm the Engineering Manager for the Anti-Harassment Tools team at the WMF. I have some details about user blocking that I'd like to share.
*tl:dr;* On a wiki with the new Partial Blocks enabled (currently only testwiki), if the code is checking User::isBlocked() to determine edit rights, it should instead check User::isBlockedFrom( Title ). The code could also check isBlocked() && $block->isSitewide(). If it doesn’t, the code may block users that shouldn’t be blocked.
*More details:* Recently, the Anti-Harassment Tools team merged code to enable a new feature called Partial Blocks. This feature lets admins block users from editing particular pages instead of only being able to block users from the entire site. It is currently enabled on testwiki.
This means that there are now multiple types of blocks (and more to come in the future, ie namespace blocks). The specific new types are “partial” as opposed to “sitewide” and some non-editing types of blocks (send email, edit talk page, etc.) Previously, a developer could assume that if a user was “blocked” that meant the user couldn’t do much of anything because that was a “sitewide” block and the only kind of block. Now, there are more cases to be concerned about.
Specifically, we’ve seen some extensions using User::isBlocked() and then assuming that a user can’t edit the particular page that the extension might be concerned with. User::isBlockedFrom( Title ) with a Title object will be the more correct way to check because of the possibility that a user might not be blocked from that particular page. If the code isn’t concerned with editing, it would be appropriate to use User::isAllowed() which will determine blocked status by way of User::getRights().
There is also a new method Block::isSitewide() which can help a developer determine if the block is “sitewide” or some other type. This is useful if the code doesn’t care about anything but the “sitewide” block type.
We believe that keeping User::isBlocked() in its current state is the safer way to proceed because in cases where it’s being used incorrectly it would result in over-enforcing blocks rather than under-enforcing them. A user who is partially blocked might be treated like a sitewide block by an extension. That seems safer to us than potentially allowing a user more freedom than an admin intended with a partial block.
We found at least one extension using User::getRights() in a way that would over-enforce on a partially blocked user. We created a patch to change how User::getRights() works https://gerrit.wikimedia.org/r/c/mediawiki/core/+/471210. In addition to checking that a block exists, it will also ensure that the block is a sitewide block. This will spare the partially blocked user from being blocked in these cases.
In summary, all MediaWiki code (especially extension code) that is concerned with checking user blocks should be aware of the distinction between User::isBlocked() and User::isBlockedFrom( Title ) and use the appropriate method for the kind of blocking the code is concerned with. Additionally, using the helper method Block::isSitewide() is handy for certain usages.
Alex Ezell Engineering Manager, Anti-Harassment Tools Team (WMF) _______________________________________________ Wikitech-l mailing list Wikitech-l@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/wikitech-l