Page MenuHomePhabricator

Allow partial blocks against specified actions
Open, Needs TriagePublicFeature

Description

The partial blocking interface is able to specify blocks against lists of namespaces and pages, and has a limited number of selectors to block specific actions.

This request is to evaluate converting the action blocking from selectors to a list as well, allowing blocking of actions such as upload/move/etc.

This may consume or replace some related tasks:

Event Timeline

Xaosflux created this task.Jan 12 2020, 4:35 PM
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptJan 12 2020, 4:35 PM
Xaosflux changed the subtype of this task from "Task" to "Feature Request".Jan 12 2020, 4:35 PM
Xaosflux added a project: Anti-Harassment.
Restricted Application added a subscriber: MGChecker. · View Herald TranscriptJan 12 2020, 4:37 PM
Ammarpad updated the task description. (Show Details)Jan 12 2020, 4:37 PM
Xaosflux updated the task description. (Show Details)Jan 12 2020, 5:42 PM
Xaosflux updated the task description. (Show Details)
Xaosflux updated the task description. (Show Details)Jan 12 2020, 5:46 PM
Xaosflux updated the task description. (Show Details)Jan 14 2020, 7:37 PM
Xaosflux updated the task description. (Show Details)Jan 15 2020, 2:35 PM

It would be really great if we could design a general solution to blocking actions before we start implementing any particular action block - i.e. do this task before any of the linked tasks. If we had a framework in place for blocking actions in general, then we could respond a lot more easily to community requests for new types of action-blocking partial blocks, and also prevent further complication of an already-fragile system.

I think there are some questions we should answer first.

What do we mean by a partial action block?

We should define this before we design the system.

From the discussions on T194529, it seems that two types of partial action block are being proposed:

  1. partial block that blocks a particular action on a sitewide basis (e.g. blocking a user from moving any pages)
  2. partial block that blocks a particular action on a partial basis (e.g. blocking a user from moving particular pages, or pages within a particular namespace)

I'd really like to know how popular #2 is, since the system would be simpler without it.

Should we make assumptions about blocked actions?

Note that #1 does actually exist already for some actions: it is possible to block someone from account creation only, or from email only. These action blocks are implemented as boolean flags on a block (ipb_create_account and ipb_block_email). Clearly this is not a sustainable way to do action blocks - we don't want to add a new boolean flag for each new action to be blocked.

For other actions, whether they are blocked is currently defined on enforcement of the block. If we implement action blocks, should we still make these assumptions?

Examples of assumptions we currently make on enforcement:

  • If the block is partial and there are no restrictions, editing is not blocked
  • If the block is partial, uploading is not blocked
  • If the block is partial, an admin can still tag (T221444), delete (T219305) and block (T208965)

Next steps

Once we've answered these (and any other) questions, we should design a system that would work for all the existing partial block proposals, and in theory the existing action blocks. (It would be great to be in a position to get rid of those boolean flags from ipblocks and migrate the existing blocks over to the new system. Whether we'd have the resources to do that migration any time soon is another matter, but we should at least have the framework ready.)

@DannyS712 has made some suggestions in T194529#6210790, which look promising.

Copying Danny's comments here:

For page creation, I think it makes sense to continue with the current schema of ipblocks_restrictions with a new type for creating pages in a namespace (i.e. separate restrictions for creating pages in a namespace and editing in a namespace, but both can be applied per-namespace)

For the other actions (upload/move/thank), agree that it would be more future-proof for a separate table. Perhaps (haven't looked into if it would work):

block_actions
CREATE TABLE /*_*/block_action (
  baction_id smallint PRIMARY KEY AUTO_INCREMENT,
  baction_name varbinary(64) NOT NULL
) /*$wgDBTableOptions*/;
CREATE UNIQUE INDEX /*i*/baction_name ON /*_*/block_action (baction_name);

This would follow the same schema of the existing name tables (https://www.mediawiki.org/wiki/Multi-Content_Revisions/Database_Schema#Name_Tables)

we would then have a new ir_type for actions (if 3 is for page creation by namespace, then 4), and would check

Query
SELECT baction_name AS `action`
FROM ipblocks_restrictions
JOIN block_action
ON baction_id = ir_value
WHERE ir_type = 4
AND ir_ipb_id = $blockId

to get a list of actions (as strings) that are blocked (i.e. move, upload, thank)

FYI: MediaWiki has a concept of Actions (see EditAction class) I wonder if it would be possible to collect actions (and maybe rights as well?) and present a MultiSelectWidget allowing the admin to restrict any right or action? (I realize that might be two different form fields / tables). It might make more sense to allow the admins to restrict "anything" rather building restrictions one at a time.

Change 615837 had a related patch set uploaded (by Tchanders; owner: Tchanders):
[mediawiki/core@master] WIP Demonstration of partial blocks for actions

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

I've uploaded a patch to demonstrate how we might do this. It makes a few proposals, discussed below.

Which actions/rights should we block?

The patch proposes defining a curated list of "blockable actions" and adding to it when there's a new feature request.

Although we could systematically get rights from PermissionManager::getAllPermissions or check for classes that extend Action: https://doc.wikimedia.org/mediawiki-core/master/php/classAction.html , this wouldn't be exhaustive. E.g. this wouldn't even find create - a string action, corresponding to createpage and createtalk rights. There are also rights and actions that we'd probably never want to block, e.g. read, history, etc.

It looks like action blocks would be enforced by checking them in PermissionManager::checkUserBlock. That would mean that any "blockable action" would need to be one of the strings passed in as the $action parameter. (The alternative would be checking for each action in the peripheral component - e.g. the way Special:EmailUser checks for email blocks - but I think that would add a lot of special casing and complexity.)

Where should we define blockable actions?

The patch suggests defining blockable actions in a service instead of in a database table. Thinking again, a table could be unnecessary overhead: it would need to be updated whenever we want to change the list. Instead, blockable actions could be handled a bit like namespaces: extensions could add actions via a hook; a config could customize actions per wiki.

How should we define partial vs sitewide blocks?

The patch uses definition (1) of actions blocks from T242541#6211581: each action block blocks that action everywhere, rather than on a specific page.

Note that:

  • Many actions never relate to a particular page
  • The currently-existing action blocks (create account, email) don't relate to a page

Our current definition of sitewide/partial blocks only really relates to how editing is blocked:

What the block blocksWhat we call it
All editing, no actionsSitewide
All editing, some actionsSitewide
Some editing, no actionsPartial
Some editing, some actionsPartial
No editing, some actionsPartial

We should clarify our definition of sitewide/partial if we implement action restrictions, and we should make this definition clear to users (e.g. in the block form, block log, etc).