MediaWiki  master
UserAuthority.php
Go to the documentation of this file.
1 <?php
21 namespace MediaWiki\Permissions;
22 
23 use InvalidArgumentException;
28 use TitleValue;
29 use User;
30 
45 class UserAuthority implements Authority {
46 
51 
55  private $actor;
56 
62  private $userBlock = null;
63 
68  public function __construct(
69  User $user,
71  ) {
72  $this->permissionManager = $permissionManager;
73  $this->actor = $user;
74  }
75 
81  public function getUser(): UserIdentity {
82  return $this->actor;
83  }
84 
92  public function isAllowed( string $permission ): bool {
93  return $this->permissionManager->userHasRight( $this->actor, $permission );
94  }
95 
103  public function isAllowedAny( ...$permissions ): bool {
104  if ( !$permissions ) {
105  throw new InvalidArgumentException( 'At least one permission must be specified' );
106  }
107 
108  foreach ( $permissions as $perm ) {
109  if ( $this->isAllowed( $perm ) ) {
110  return true;
111  }
112  }
113 
114  return false;
115  }
116 
124  public function isAllowedAll( ...$permissions ): bool {
125  if ( !$permissions ) {
126  throw new InvalidArgumentException( 'At least one permission must be specified' );
127  }
128 
129  foreach ( $permissions as $perm ) {
130  if ( !$this->isAllowed( $perm ) ) {
131  return false;
132  }
133  }
134 
135  return true;
136  }
137 
147  public function probablyCan(
148  string $action,
149  PageIdentity $target,
150  PermissionStatus $status = null
151  ): bool {
152  return $this->internalCan(
153  PermissionManager::RIGOR_QUICK,
154  $action,
155  $target,
156  $status
157  );
158  }
159 
169  public function definitelyCan(
170  string $action,
171  PageIdentity $target,
172  PermissionStatus $status = null
173  ): bool {
174  // Note that we do not use RIGOR_SECURE to avoid hitting the primary
175  // database for read operations. RIGOR_FULL performs the same checks,
176  // but is subject to replication lag.
177  return $this->internalCan(
178  PermissionManager::RIGOR_FULL,
179  $action,
180  $target,
181  $status
182  );
183  }
184 
194  public function authorizeRead(
195  string $action,
196  PageIdentity $target,
197  PermissionStatus $status = null
198  ): bool {
199  // Any side-effects can be added here.
200 
201  // Note that we do not use RIGOR_SECURE to avoid hitting the primary
202  // database for read operations. RIGOR_FULL performs the same checks,
203  // but is subject to replication lag.
204  return $this->internalCan(
205  PermissionManager::RIGOR_FULL,
206  $action,
207  $target,
208  $status
209  );
210  }
211 
221  public function authorizeWrite(
222  string $action,
223  PageIdentity $target,
224  PermissionStatus $status = null
225  ): bool {
226  // Any side-effects can be added here.
227 
228  // Note that we need to use RIGOR_SECURE here to ensure that we do not
229  // miss a user block or page protection due to replication lag.
230  return $this->internalCan(
231  PermissionManager::RIGOR_SECURE,
232  $action,
233  $target,
234  $status
235  );
236  }
237 
246  private function internalCan(
247  string $rigor,
248  string $action,
249  PageIdentity $target,
250  PermissionStatus $status = null
251  ): bool {
252  if ( !( $target instanceof LinkTarget ) ) {
253  // FIXME: PermissionManager should accept PageIdentity!
254  $target = TitleValue::newFromPage( $target );
255  }
256 
257  if ( $status ) {
258  $errors = $this->permissionManager->getPermissionErrors(
259  $action,
260  $this->actor,
261  $target,
262  $rigor
263  );
264 
265  $blockError = false;
266  foreach ( $errors as $err ) {
267  $status->fatal( ...$err );
268 
269  // HACK: Detect whether the permission was denied because the user is blocked.
270  // A similar hack exists in ApiBase::$blockMsgMap.
271  // When permission checking logic is moved out of PermissionManager,
272  // we can record the block info directly when first checking the block,
273  // rather than doing that here.
274  if ( strpos( $err[0], 'blockedtext' ) !== false ) {
275  $block = $this->getBlock();
276 
277  if ( $block ) {
278  $status->setBlock( $block );
279  }
280  }
281  }
282 
283  return $status->isOK();
284  } else {
285  // allow PermissionManager to short-circuit
286  return $this->permissionManager->userCan(
287  $action,
288  $this->actor,
289  $target,
290  $rigor
291  );
292  }
293  }
294 
304  public function getBlock( int $freshness = self::READ_NORMAL ): ?Block {
305  // Cache block info, so we don't have to fetch it again unnecessarily.
306  if ( $this->userBlock === null || $freshness === self::READ_LATEST ) {
307  $this->userBlock = $this->actor->getBlock( $freshness );
308 
309  // if we got null back, remember this as "false"
310  $this->userBlock = $this->userBlock ?: false;
311  }
312 
313  // if we remembered "false", return null
314  return $this->userBlock ?: null;
315  }
316 
317 }
Page\PageIdentity
Interface for objects (potentially) representing an editable wiki page.
Definition: PageIdentity.php:64
MediaWiki\Permissions\UserAuthority\internalCan
internalCan(string $rigor, string $action, PageIdentity $target, PermissionStatus $status=null)
Definition: UserAuthority.php:246
MediaWiki\Permissions\UserAuthority
Represents the authority of a given User.
Definition: UserAuthority.php:45
MediaWiki\Permissions\UserAuthority\authorizeRead
authorizeRead(string $action, PageIdentity $target, PermissionStatus $status=null)
Authorize read access.This should be used immediately before performing read access on restricted inf...
Definition: UserAuthority.php:194
MediaWiki\User\UserIdentity
Interface for objects representing user identity.
Definition: UserIdentity.php:39
MediaWiki\Permissions\UserAuthority\__construct
__construct(User $user, PermissionManager $permissionManager)
Definition: UserAuthority.php:68
TitleValue\newFromPage
static newFromPage(PageReference $page)
Constructs a TitleValue from a local PageReference.
Definition: TitleValue.php:119
MediaWiki\Permissions\UserAuthority\$actor
User $actor
Definition: UserAuthority.php:55
MediaWiki\Permissions\UserAuthority\$permissionManager
PermissionManager $permissionManager
Definition: UserAuthority.php:50
MediaWiki\Permissions\UserAuthority\isAllowedAll
isAllowedAll(... $permissions)
Checks whether this authority has any of the given permissions in general.Implementations must ensure...
Definition: UserAuthority.php:124
MediaWiki\Block\Block
Represents a block that may prevent users from performing specific operations.
Definition: Block.php:37
MediaWiki\Permissions\Authority
This interface represents the authority associated the current execution context, such as a web reque...
Definition: Authority.php:37
MediaWiki\Permissions\PermissionManager
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
Definition: PermissionManager.php:53
MediaWiki\Permissions\UserAuthority\$userBlock
Block false null $userBlock
Local cache for user block information.
Definition: UserAuthority.php:62
MediaWiki\Permissions\UserAuthority\getUser
getUser()
Returns the performer of the actions associated with this authority.Actions performed under this auth...
Definition: UserAuthority.php:81
MediaWiki\Permissions\UserAuthority\getBlock
getBlock(int $freshness=self::READ_NORMAL)
Returns any user block affecting the Authority.
Definition: UserAuthority.php:304
MediaWiki\Permissions\PermissionStatus
A StatusValue for permission errors.
Definition: PermissionStatus.php:35
MediaWiki\$action
string $action
Cache what action this request is.
Definition: MediaWiki.php:45
MediaWiki\Permissions\UserAuthority\isAllowed
isAllowed(string $permission)
Checks whether this authority has the given permission in general.For some permissions,...
Definition: UserAuthority.php:92
MediaWiki\Permissions\UserAuthority\probablyCan
probablyCan(string $action, PageIdentity $target, PermissionStatus $status=null)
Checks whether this authority can probably perform the given action on the given target page....
Definition: UserAuthority.php:147
MediaWiki\Permissions\UserAuthority\definitelyCan
definitelyCan(string $action, PageIdentity $target, PermissionStatus $status=null)
Checks whether this authority can perform the given action on the given target page....
Definition: UserAuthority.php:169
MediaWiki\Permissions\UserAuthority\isAllowedAny
isAllowedAny(... $permissions)
Checks whether this authority has any of the given permissions in general.Implementations must ensure...
Definition: UserAuthority.php:103
MediaWiki\Linker\LinkTarget
Definition: LinkTarget.php:26
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:68
MediaWiki\Permissions\UserAuthority\authorizeWrite
authorizeWrite(string $action, PageIdentity $target, PermissionStatus $status=null)
Authorize write access.This should be used immediately before updating persisted information....
Definition: UserAuthority.php:221
MediaWiki\Permissions
Definition: Authority.php:21
TitleValue
Represents a page (or page fragment) title within MediaWiki.
Definition: TitleValue.php:40