aboutsummaryrefslogtreecommitdiffstats
path: root/includes/block/UnblockUser.php
diff options
context:
space:
mode:
authorDayllan Maza <dmaza@wikimedia.org>2024-12-11 17:13:55 -0500
committerDayllan Maza <dmaza@wikimedia.org>2025-01-14 12:06:33 -0500
commit37f44a0a3ec9ffd741a464abd6c9959982d045e9 (patch)
tree1cfd5f98192d41b9f87bb2245267a8ca00c3e8bd /includes/block/UnblockUser.php
parent5bb154a8780989d379741cf4dad11b3b0f3fa58f (diff)
downloadmediawikicore-37f44a0a3ec9ffd741a464abd6c9959982d045e9.tar.gz
mediawikicore-37f44a0a3ec9ffd741a464abd6c9959982d045e9.zip
ApiUnblock: Add support for multiblocks
* Re-purpose the existing id parameter to support block ID. If both id, and username are provided the request will fail * If a target has more than one block and a specific block is not provided it will fail with ipb_cant_unblock_multiple_blocks Bug: T378148 Change-Id: I04928d989e6764ac93ec243a5fec9c7fe2b0b9b0
Diffstat (limited to 'includes/block/UnblockUser.php')
-rw-r--r--includes/block/UnblockUser.php79
1 files changed, 63 insertions, 16 deletions
diff --git a/includes/block/UnblockUser.php b/includes/block/UnblockUser.php
index fa3d01cbb49d..b3532e2f9e90 100644
--- a/includes/block/UnblockUser.php
+++ b/includes/block/UnblockUser.php
@@ -25,6 +25,7 @@ use ChangeTags;
use ManualLogEntry;
use MediaWiki\HookContainer\HookContainer;
use MediaWiki\HookContainer\HookRunner;
+use MediaWiki\Message\Message;
use MediaWiki\Permissions\Authority;
use MediaWiki\Status\Status;
use MediaWiki\Title\TitleValue;
@@ -50,8 +51,9 @@ class UnblockUser {
/** @var int */
private $targetType;
- /** @var DatabaseBlock|null */
- private $block;
+ private ?DatabaseBlock $block;
+
+ private ?DatabaseBlock $blockToRemove = null;
/** @var Authority */
private $performer;
@@ -68,7 +70,8 @@ class UnblockUser {
* @param BlockUtils $blockUtils
* @param UserFactory $userFactory
* @param HookContainer $hookContainer
- * @param UserIdentity|string $target
+ * @param DatabaseBlock|null $blockToRemove
+ * @param UserIdentity|string|null $target
* @param Authority $performer
* @param string $reason
* @param string[] $tags
@@ -79,6 +82,7 @@ class UnblockUser {
BlockUtils $blockUtils,
UserFactory $userFactory,
HookContainer $hookContainer,
+ ?DatabaseBlock $blockToRemove,
$target,
Authority $performer,
string $reason,
@@ -96,15 +100,22 @@ class UnblockUser {
$this->hookRunner = new HookRunner( $hookContainer );
// Process params
- [ $this->target, $this->targetType ] = $this->blockUtils->parseBlockTarget( $target );
- if (
- $this->targetType === AbstractBlock::TYPE_AUTO &&
- is_numeric( $this->target )
- ) {
- // Needed, because BlockUtils::parseBlockTarget will strip the # from autoblocks.
- $this->target = '#' . $this->target;
+ if ( $blockToRemove !== null ) {
+ $this->blockToRemove = $blockToRemove;
+ $this->target = $blockToRemove->getTargetUserIdentity()
+ ?? $blockToRemove->getTargetName();
+ $this->targetType = $blockToRemove->getType() ?? -1;
+ } else {
+ [ $this->target, $this->targetType ] = $this->blockUtils->parseBlockTarget( $target );
+ if (
+ $this->targetType === AbstractBlock::TYPE_AUTO &&
+ is_numeric( $this->target )
+ ) {
+ // Needed, because BlockUtils::parseBlockTarget will strip the # from autoblocks.
+ $this->target = '#' . $this->target;
+ }
}
- $this->block = $this->blockStore->newFromTarget( $this->target );
+
$this->performer = $performer;
$this->reason = $reason;
$this->tags = $tags;
@@ -118,11 +129,9 @@ class UnblockUser {
public function unblock(): Status {
$status = Status::newGood();
- $basePermissionCheckResult = $this->blockPermissionChecker->checkBasePermissions(
- $this->block instanceof DatabaseBlock && $this->block->getHideName()
- );
- if ( $basePermissionCheckResult !== true ) {
- return $status->fatal( $basePermissionCheckResult );
+ $this->block = $this->getBlockToRemove( $status );
+ if ( !$status->isOK() ) {
+ return $status;
}
$blockPermissionCheckResult = $this->blockPermissionChecker->checkBlockPermissions();
@@ -130,6 +139,14 @@ class UnblockUser {
return $status->fatal( $blockPermissionCheckResult );
}
+ $basePermissionCheckResult = $this->blockPermissionChecker->checkBasePermissions(
+ $this->block instanceof DatabaseBlock && $this->block->getHideName()
+ );
+
+ if ( $basePermissionCheckResult !== true ) {
+ return $status->fatal( $basePermissionCheckResult );
+ }
+
if ( count( $this->tags ) !== 0 ) {
$status->merge(
ChangeTags::canAddTagsAccompanyingChange(
@@ -142,6 +159,7 @@ class UnblockUser {
if ( !$status->isOK() ) {
return $status;
}
+
return $this->unblockUnsafe();
}
@@ -154,6 +172,11 @@ class UnblockUser {
public function unblockUnsafe(): Status {
$status = Status::newGood();
+ $this->block ??= $this->getBlockToRemove( $status );
+ if ( !$status->isOK() ) {
+ return $status;
+ }
+
if ( $this->block === null ) {
return $status->fatal( 'ipb_cant_unblock', $this->target );
}
@@ -218,4 +241,28 @@ class UnblockUser {
$logEntry->publish( $logId );
}
+ private function getBlockToRemove( Status $status ): ?DatabaseBlock {
+ if ( $this->blockToRemove !== null ) {
+ return $this->blockToRemove;
+ }
+
+ $activeBlocks = $this->blockStore->newListFromTarget( $this->target );
+ if ( !$activeBlocks ) {
+ $status->fatal( 'ipb_cant_unblock', $this->target );
+ return null;
+ }
+
+ if ( count( $activeBlocks ) > 1 ) {
+ $status->fatal( 'ipb_cant_unblock_multiple_blocks',
+ count( $activeBlocks ), Message::listParam(
+ array_map(
+ static function ( $block ) {
+ return $block->getId();
+ }, $activeBlocks )
+ )
+ );
+ }
+
+ return $activeBlocks[0];
+ }
}