Do not ignore the 'Prevent this user from editing his own talk page while
authorDavid Barratt <dbarratt@wikimedia.org>
Tue, 27 Nov 2018 06:43:21 +0000 (01:43 -0500)
committerDavid Barratt <dbarratt@wikimedia.org>
Tue, 27 Nov 2018 15:30:21 +0000 (10:30 -0500)
blocked' option on partial blocks.

Partial blocks currently ignore this option as it gets into an edge case. The
option should take precidence if it is true, but should be ignored if it is
false. On sitewide blocks, the option should always be honored.

Bug: T210475
Change-Id: I33177b48a5c261ec3f510ce01998c1b096077b85

includes/user/User.php
tests/phpunit/includes/user/UserTest.php

index 5f772a4..40511cf 100644 (file)
@@ -2304,16 +2304,18 @@ class User implements IDBAccessObject, UserIdentity {
                if ( !$blocked ) {
                        $block = $this->getBlock( $fromReplica );
                        if ( $block ) {
-                               // A sitewide block covers everything except maybe the user's
-                               // talk page. A partial block covering the user's talk page
-                               // overrides the editownusertalk flag, however.
-                               // TODO: Do we really want a partial block on the user talk
-                               //  namespace to ignore editownusertalk?
-                               $blocked = $block->isSitewide();
-                               if ( $blocked && $title->equals( $this->getTalkPage() ) ) {
-                                       $blocked = $block->prevents( 'editownusertalk' );
-                               }
-                               if ( !$block->isSitewide() ) {
+                               // Special handling for a user's own talk page. The block is not aware
+                               // of the user, so this must be done here.
+                               if ( $title->equals( $this->getTalkPage() ) ) {
+                                       // If the block is sitewide, then whatever is set is what is honored.
+                                       if ( $block->isSitewide() ) {
+                                               $blocked = $block->prevents( 'editownusertalk' );
+                                       } else {
+                                               // If the block is partial, then only a true value is honored,
+                                               // otherwise fallback to the partial block settings.
+                                               $blocked = $block->prevents( 'editownusertalk' ) ?: $block->appliesToTitle( $title );
+                                       }
+                               } else {
                                        $blocked = $block->appliesToTitle( $title );
                                }
                        }
index f1c049b..b9289db 100644 (file)
@@ -1285,8 +1285,17 @@ class UserTest extends MediaWikiTestCase {
                                'pageRestrictions' => [ 'Test page' ],
                        ] ],
                        'Partial block, overriding allowUsertalk' => [ self::USER_TALK_PAGE, true, [
+                               'allowUsertalk' => false,
                                'pageRestrictions' => [ self::USER_TALK_PAGE ],
                        ] ],
+                       'Partial block, allowing user talk' => [ self::USER_TALK_PAGE, false, [
+                               'allowUsertalk' => true,
+                               'pageRestrictions' => [ 'Test page' ],
+                       ] ],
+                       'Partial block, not allowing user talk' => [ self::USER_TALK_PAGE, true, [
+                               'allowUsertalk' => false,
+                               'pageRestrictions' => [ 'Test page' ],
+                       ] ],
                ];
        }