MediaWiki master
ApiUnblock.php
Go to the documentation of this file.
1<?php
9namespace MediaWiki\Api;
10
23use RuntimeException;
26
33class ApiUnblock extends ApiBase {
34
37
38 public function __construct(
39 ApiMain $main,
40 string $action,
41 private readonly BlockPermissionCheckerFactory $permissionCheckerFactory,
42 private readonly UnblockUserFactory $unblockUserFactory,
43 private readonly UserIdentityLookup $userIdentityLookup,
44 WatchedItemStoreInterface $watchedItemStore,
45 WatchlistManager $watchlistManager,
46 UserOptionsLookup $userOptionsLookup,
47 private readonly DatabaseBlockStore $blockStore,
48 private readonly BlockTargetFactory $blockTargetFactory,
49 ) {
50 parent::__construct( $main, $action );
51
52 $this->watchedItemStore = $watchedItemStore;
53
54 // Variables needed in ApiWatchlistTrait trait
55 $this->watchlistExpiryEnabled = $this->getConfig()->get( MainConfigNames::WatchlistExpiry );
56 $this->watchlistMaxDuration =
58 $this->watchlistManager = $watchlistManager;
59 $this->userOptionsLookup = $userOptionsLookup;
60 }
61
65 public function execute() {
66 $performer = $this->getUser();
67 $params = $this->extractRequestParams();
68
69 $this->requireOnlyOneParameter( $params, 'id', 'user', 'userid' );
70
71 if ( !$this->getAuthority()->isAllowed( 'block' ) ) {
72 $this->dieWithError( 'apierror-permissiondenied-unblock', 'permissiondenied' );
73 }
74
75 if ( $params['userid'] !== null ) {
76 $identity = $this->userIdentityLookup->getUserIdentityByUserId( $params['userid'] );
77 if ( !$identity ) {
78 $this->dieWithError( [ 'apierror-nosuchuserid', $params['userid'] ], 'nosuchuserid' );
79 }
80 $params['user'] = $identity;
81 }
82
83 $blockToRemove = null;
84 if ( $params['id'] !== null ) {
85 $blockToRemove = $this->blockStore->newFromID( $params['id'], true );
86 if ( !$blockToRemove ) {
87 $this->dieWithError(
88 [ 'apierror-nosuchblockid', $params['id'] ],
89 'nosuchblockid' );
90 }
91 $target = $blockToRemove->getRedactedTarget();
92 if ( !$target ) {
93 throw new RuntimeException( 'Block has no target' );
94 }
95 } else {
96 $target = $this->blockTargetFactory->newFromUser( $params['user'] );
97 }
98
99 # T17810: blocked admins should have limited access here
100 $status = $this->permissionCheckerFactory
101 ->newChecker(
102 $this->getAuthority()
103 )->checkBlockPermissions( $target );
104
105 if ( $status !== true ) {
106 $this->dieWithError(
107 $status,
108 null,
109 // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null
110 [ 'blockinfo' => $this->getBlockDetails( $performer->getBlock() ) ]
111 );
112 }
113
114 if ( $blockToRemove !== null ) {
115 $status = $this->unblockUserFactory->newRemoveBlock(
116 $blockToRemove,
117 $this->getAuthority(),
118 $params['reason'],
119 $params['tags'] ?? []
120 )->unblock();
121 } else {
122 $status = $this->unblockUserFactory->newUnblockUser(
123 $target,
124 $this->getAuthority(),
125 $params['reason'],
126 $params['tags'] ?? []
127 )->unblock();
128 }
129
130 if ( !$status->isOK() ) {
131 $this->dieStatus( $status );
132 }
133
134 $block = $status->getValue();
135 $targetType = $block->getType();
136 $targetName = $targetType === Block::TYPE_AUTO ? '' : $block->getTargetName();
137 $targetUserId = $block->getTargetUserIdentity() ? $block->getTargetUserIdentity()->getId() : 0;
138
139 $userPage = Title::makeTitle( NS_USER, $targetName );
140 $watchlistExpiry = $this->getExpiryFromParams( $params, $userPage, $this->getUser() );
141 $watchuser = $params['watchuser'];
142 if ( $watchuser && $targetType !== Block::TYPE_RANGE && $targetType !== Block::TYPE_AUTO ) {
143 $this->setWatch( 'watch', $userPage, $this->getUser(), null, $watchlistExpiry );
144 } else {
145 $watchuser = false;
146 $watchlistExpiry = null;
147 }
148
149 $res = [
150 'id' => $block->getId(),
151 'user' => $targetName,
152 'userid' => $targetUserId,
153 'reason' => $params['reason'],
154 'watchuser' => $watchuser,
155 ];
156
157 if ( $watchlistExpiry !== null ) {
158 $res['watchlistexpiry'] = $this->getWatchlistExpiry(
159 $this->watchedItemStore,
160 $userPage,
161 $this->getUser()
162 );
163 }
164
165 $this->getResult()->addValue( null, $this->getModuleName(), $res );
166 }
167
169 public function mustBePosted() {
170 return true;
171 }
172
174 public function isWriteMode() {
175 return true;
176 }
177
179 public function getAllowedParams() {
180 $params = [
181 'id' => [
182 ParamValidator::PARAM_TYPE => 'integer',
183 ],
184 'user' => [
185 ParamValidator::PARAM_TYPE => 'user',
186 UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name', 'ip', 'temp', 'cidr', 'id' ],
187 UserDef::PARAM_RETURN_OBJECT => true,
188 ],
189 'userid' => [
190 ParamValidator::PARAM_TYPE => 'integer',
191 ParamValidator::PARAM_DEPRECATED => true,
192 ],
193 'reason' => '',
194 'tags' => [
195 ParamValidator::PARAM_TYPE => 'tags',
196 ParamValidator::PARAM_ISMULTI => true,
197 ],
198 'watchuser' => false,
199 ];
200
201 // Params appear in the docs in the order they are defined,
202 // which is why this is here and not at the bottom.
203 // @todo Find better way to support insertion at arbitrary position
204 if ( $this->watchlistExpiryEnabled ) {
205 $params += [
206 'watchlistexpiry' => [
207 ParamValidator::PARAM_TYPE => 'expiry',
208 ExpiryDef::PARAM_MAX => $this->watchlistMaxDuration,
209 ExpiryDef::PARAM_USE_MAX => true,
210 ]
211 ];
212 }
213
214 return $params;
215 }
216
218 public function needsToken() {
219 return 'csrf';
220 }
221
223 protected function getExamplesMessages() {
224 return [
225 'action=unblock&id=105'
226 => 'apihelp-unblock-example-id',
227 'action=unblock&user=Bob&reason=Sorry%20Bob'
228 => 'apihelp-unblock-example-user',
229 ];
230 }
231
233 public function getHelpUrls() {
234 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Block';
235 }
236}
237
239class_alias( ApiUnblock::class, 'ApiUnblock' );
const NS_USER
Definition Defines.php:53
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:60
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1506
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:542
getResult()
Get the result object.
Definition ApiBase.php:681
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition ApiBase.php:1557
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:822
requireOnlyOneParameter( $params,... $required)
Die if 0 or more than one of a certain set of parameters is set and not false.
Definition ApiBase.php:960
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:67
API module that facilitates the unblocking of users.
mustBePosted()
Indicates whether this module must be called with a POST request.Implementations of this method must ...
needsToken()
Returns the token type this module requires in order to execute.Modules are strongly encouraged to us...
execute()
Unblocks the specified user or provides the reason the unblock failed.
isWriteMode()
Indicates whether this module requires write access to the wiki.API modules must override this method...
__construct(ApiMain $main, string $action, private readonly BlockPermissionCheckerFactory $permissionCheckerFactory, private readonly UnblockUserFactory $unblockUserFactory, private readonly UserIdentityLookup $userIdentityLookup, WatchedItemStoreInterface $watchedItemStore, WatchlistManager $watchlistManager, UserOptionsLookup $userOptionsLookup, private readonly DatabaseBlockStore $blockStore, private readonly BlockTargetFactory $blockTargetFactory,)
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
getHelpUrls()
Return links to more detailed help pages about the module.1.25, returning boolean false is deprecated...
getExamplesMessages()
Returns usage examples for this module.Return value has query strings as keys, with values being eith...
Factory for BlockTarget objects.
makeTitle( $linkId)
Convert a link ID to a Title.to override Title
A class containing constants representing the names of configuration variables.
const WatchlistExpiry
Name constant for the WatchlistExpiry setting, for use with Config::get()
const WatchlistExpiryMaxDuration
Name constant for the WatchlistExpiryMaxDuration setting, for use with Config::get()
Type definition for user types.
Definition UserDef.php:27
Represents a title within MediaWiki.
Definition Title.php:69
Provides access to user options.
Service for formatting and validating API parameters.
Type definition for expiry timestamps.
Definition ExpiryDef.php:18
trait ApiWatchlistTrait
An ApiWatchlistTrait adds class properties and convenience methods for APIs that allow you to watch a...
Represents a block that may prevent users from performing specific operations.
Definition Block.php:31
Service for looking up UserIdentity.
setWatch(string $watch, PageIdentity $page, User $user, ?string $userOption=null, ?string $expiry=null)
Set a watch (or unwatch) based the based on a watchlist parameter.
getExpiryFromParams(array $params, ?PageIdentity $page=null, ?UserIdentity $user=null, string $userOption='watchdefault-expiry')
Get formatted expiry from the given parameters.
getWatchlistExpiry(WatchedItemStoreInterface $store, PageIdentity $page, UserIdentity $user)
Get existing expiry from the database.