Merge "Use MediaWiki\SuppressWarnings around trigger_error('') instead @"
[lhc/web/wiklou.git] / includes / specials / SpecialBlock.php
index ea4cd22..67d1873 100644 (file)
@@ -66,7 +66,6 @@ class SpecialBlock extends FormSpecialPage {
         */
        protected function checkExecutePermissions( User $user ) {
                parent::checkExecutePermissions( $user );
-
                # T17810: blocked admins should have limited access here
                $status = self::checkUnblockSelf( $this->target, $user );
                if ( $status !== true ) {
@@ -74,6 +73,15 @@ class SpecialBlock extends FormSpecialPage {
                }
        }
 
+       /**
+        * We allow certain special cases where user is blocked
+        *
+        * @return bool
+        */
+       public function requiresUnblock() {
+               return false;
+       }
+
        /**
         * Handle some magic here
         *
@@ -386,6 +394,7 @@ class SpecialBlock extends FormSpecialPage {
         * @return string
         */
        protected function preText() {
+               $this->getOutput()->addModuleStyles( 'mediawiki.widgets.TagMultiselectWidget.styles' );
                $this->getOutput()->addModules( [ 'mediawiki.special.block' ] );
 
                $blockCIDRLimit = $this->getConfig()->get( 'BlockCIDRLimit' );
@@ -1021,19 +1030,24 @@ class SpecialBlock extends FormSpecialPage {
         * T17810: blocked admins should not be able to block/unblock
         * others, and probably shouldn't be able to unblock themselves
         * either.
-        * @param User|int|string $user
+        *
+        * Exception: Users can block the user who blocked them, to reduce
+        * advantage of a malicious account blocking all admins (T150826)
+        *
+        * @param User|int|string|null $target Target to block or unblock; could be a User object,
+        *   or a user ID or username, or null when the target is not known yet (e.g. when
+        *   displaying Special:Block)
         * @param User $performer User doing the request
         * @return bool|string True or error message key
         */
-       public static function checkUnblockSelf( $user, User $performer ) {
-               if ( is_int( $user ) ) {
-                       $user = User::newFromId( $user );
-               } elseif ( is_string( $user ) ) {
-                       $user = User::newFromName( $user );
+       public static function checkUnblockSelf( $target, User $performer ) {
+               if ( is_int( $target ) ) {
+                       $target = User::newFromId( $target );
+               } elseif ( is_string( $target ) ) {
+                       $target = User::newFromName( $target );
                }
-
                if ( $performer->isBlocked() ) {
-                       if ( $user instanceof User && $user->getId() == $performer->getId() ) {
+                       if ( $target instanceof User && $target->getId() == $performer->getId() ) {
                                # User is trying to unblock themselves
                                if ( $performer->isAllowed( 'unblockself' ) ) {
                                        return true;
@@ -1043,6 +1057,19 @@ class SpecialBlock extends FormSpecialPage {
                                } else {
                                        return 'ipbnounblockself';
                                }
+                       } elseif (
+                               $target instanceof User &&
+                               $performer->getBlock() instanceof Block &&
+                               $performer->getBlock()->getBy() &&
+                               $performer->getBlock()->getBy() === $target->getId()
+                       ) {
+                               // Allow users to block the user that blocked them.
+                               // This is to prevent a situation where a malicious user
+                               // blocks all other users. This way, the non-malicious
+                               // user can block the malicious user back, resulting
+                               // in a stalemate.
+                               return true;
+
                        } else {
                                # User is trying to block/unblock someone else
                                return 'ipbblocked';