Page MenuHomePhabricator

Investigation for blocking page creation with partial blocks
Closed, ResolvedPublic

Description

Goal

It is a commonly requested Partial Blocks feature to allow blocking a user only from creating pages. This task is to investigate some open product questions that will help decide the scope of the work we do.

What do we want to know:
  • How much work would be involved in adding this feature? (i.e. would we need a new database table/column etc.?)
  • How much work would be involved if we were to allow blocking page creation by namespace?
  • Can we include blocking re-creation of previously deleted pages?
  • Will blocking page creation also impact file uploads?
Related tasks:

Event Timeline

Niharika triaged this task as Medium priority.May 10 2020, 9:14 PM
Niharika created this task.

Is T5595 ("New logo for Udmurt Wikipedia") intentionally listed as related?

DannyS712 subscribed.

General notes for partial blocks against actions, not just page creation (this does not take into account blocking page creation by namespace or the interaction between creating file pages and uploading new files):

Current table
CREATE TABLE /*_*/ipblocks_restrictions (
  -- The ipb_id from ipblocks
  ir_ipb_id int NOT NULL,
  -- The restriction type id.
  ir_type tinyint(1) NOT NULL,
  -- The restriction id that corrposponds to the type. Typically a Page ID or a
  -- Namespace ID.
  ir_value int NOT NULL,
  PRIMARY KEY (ir_ipb_id, ir_type, ir_value)
) /*$wgDBTableOptions*/;
Example query
MariaDB [enwiki_p]> SELECT ir_ipb_id, CASE WHEN ( ir_type = 1 ) THEN 'page' ELSE 'namespace' END AS 'type', ir_value FROM ipblocks_restrictions LIMIT 25;
+-----------+-----------+----------+
| ir_ipb_id | type      | ir_value |
+-----------+-----------+----------+
|   9435157 | namespace |        4 |
|   9495590 | page      | 57861199 |
|   9497043 | page      | 30859855 |
|   9498101 | page      |  2333491 |
|   9498101 | page      | 42165878 |
|   9517403 | page      | 28280067 |
|   9517475 | page      |    50803 |
|   9517475 | page      |    87276 |
|   9517475 | page      | 19629641 |
|   9517475 | page      | 21347867 |
|   9517475 | page      | 23871476 |
|   9517475 | page      | 25169060 |
|   9517475 | page      | 61818020 |
|   9531962 | page      | 24758230 |
|   9533323 | page      |   497526 |
|   9536130 | page      |  2015570 |
|   9540101 | namespace |        0 |
|   9542727 | page      |   165094 |
|   9559276 | namespace |        0 |
|   9559540 | page      |   654157 |
|   9561071 | page      | 59625567 |
|   9561107 | page      | 62990726 |
|   9562223 | page      |   585629 |
|   9562223 | page      | 21486360 |
|   9563237 | page      | 34355486 |
+-----------+-----------+----------+

Note that:
ir_type is either 1 or 2, shown as page or namespace to ease understanding
ir_value can only be an int, meaning that it cannot hold the action as a string
Multiple rows for a single block with multiple restrictions

Potential implementation:
ActionRestriction, like for namespace / page

type: 3
ir_value - constant mapping with string to int, more added by extension some other way (for thanks)

ActionRestriction::ACTION_CREATE_VALUE => 1
ActionRestriction::ACTION_UPLOAD_VALUE => 2
ActionRestriction::ACTION_MOVE_VALUE => 3

run hook? retrieve attributes from extension registration?

ACTION_THANK_VALUE = 101

Hook requires that no values override existing mapping
Values 1-100 (or some high number that core will never reach, 1000?) are reserved for core

Action blocks
+-----------+-----------+----------+
| ir_ipb_id | type      | ir_value |
+-----------+-----------+----------+
|   9562223 | action    |        1 |
|   9562223 | action    |        2 |
|   9563237 | action    |      101 |
+-----------+-----------+----------+

^ 1 block from creating and uploading, and another block from thanks

Restriction::matches only receives a title - use the special page? Or don't use, and instead implement some other way?
Special:MovePage and Special:Upload (and Special:Thanks) exist, but there isn't one for page creation. Hack Special:CreatePage?

AbstractBlock::appliesToRight
/**
 * Determine whether the block prevents a given right. A right
 * may be blacklisted or whitelisted, or determined from a
 * property on the block object. For certain rights, the property
 * may be overridden according to global configs.
 *
 * @since 1.33
 * @param string $right
 * @return bool|null The block applies to the right, or null if
 *  unsure (e.g. unrecognized right or unset property)
 */
public function appliesToRight( $right ) {
	$config = RequestContext::getMain()->getConfig();
	$blockDisablesLogin = $config->get( 'BlockDisablesLogin' );

	$res = null;
	switch ( $right ) {
		case 'edit':
			// TODO: fix this case to return proper value
			$res = true;
			break;
		case 'createaccount':
			$res = $this->isCreateAccountBlocked();
			break;
		case 'sendemail':
			$res = $this->isEmailBlocked();
			break;
		case 'upload':
			// Until T6995 is completed
			$res = $this->isSitewide();
			break;
		case 'read':
			$res = false;
			break;
		case 'purge':
			$res = false;
			break;
	}
	if ( !$res && $blockDisablesLogin ) {
		// If a block would disable login, then it should
		// prevent any right that all users cannot do
		$permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
		$anon = new User;
		$res = $permissionManager->userHasRight( $anon, $right ) ? $res : true;
	}

	return $res;
}

Should work for create, move, and upload - no right is needed for thanks?

Implementing an ActionRestriction as described somewhat haphazardly above would mean that no new database table or column is needed, and that this feature should be fully backwards compatible

Is T5595 ("New logo for Udmurt Wikipedia") intentionally listed as related?

Hah good catch, I meant T6995: Allow users to be blocked from uploading files only.

TIL there is an Udmurt wikipedia!

@DannyS712 the restrictions table wasn't intended to be a generic restriction store, I think it would be "better" to create a new (boolean?) column on ipblocks to indicate that page creation is being blocked. Though this opens up a ton of questions though. Is blocking page creation mutually exclusive? Let's say I block a user from two namespaces, should I be able to block one for page creation only and the other for all edits? Or Can I only block creation (i.e. unblock editing) for the entire block?

@DannyS712 the restrictions table wasn't intended to be a generic restriction store, I think it would be "better" to create a new (boolean?) column on ipblocks to indicate that page creation is being blocked. Though this opens up a ton of questions though. Is blocking page creation mutually exclusive? Let's say I block a user from two namespaces, should I be able to block one for page creation only and the other for all edits? Or Can I only block creation (i.e. unblock editing) for the entire block?

Taking into account restriction page creation by namespace, would the restriction table be appropriate? Just have 2 different namespace block types - 2 (current) is editing in a namespace, 3 (proposed) is creating pages in a namespace

Taking into account restriction page creation by namespace, would the restriction table be appropriate? Just have 2 different namespace block types - 2 (current) is editing in a namespace, 3 (proposed) is creating pages in a namespace

That makes a lot of sense to me! :)

On Special:Block we may need to change Editing to something else... or create a new checkbox for Page Creation that would allow you to specify namespaces or something. I imagine @Prtksxna might have some ideas. :)

On Special:Block we may need to change Editing to something else... or create a new checkbox for Page Creation that would allow you to specify namespaces or something. I imagine @Prtksxna might have some ideas. :)

Making sure I understand this correctly: this is block page creation when setting up a partial block, right?
Once we have a few of these extra options we can group them together:

  • (From parent)
    Use case issue brought up on wiki:

    IF A User is blocked from EDITING a page
    THEN
    page is DELETED
    User may now create/edit the page. So perhaps make the "edit block" become an edit OR create block (and not be dependent on the page title existing?)

    Tchanders claimed this task.