*/
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 ) {
}
}
+ /**
+ * We allow certain special cases where user is blocked
+ *
+ * @return bool
+ */
+ public function requiresUnblock() {
+ return false;
+ }
+
/**
* Handle some magic here
*
* @return string
*/
protected function preText() {
+ $this->getOutput()->addModuleStyles( 'mediawiki.widgets.TagMultiselectWidget.styles' );
$this->getOutput()->addModules( [ 'mediawiki.special.block' ] );
$blockCIDRLimit = $this->getConfig()->get( 'BlockCIDRLimit' );
* 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;
} 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';