Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
21 / 21 |
|
100.00% |
4 / 4 |
CRAP | |
100.00% |
1 / 1 |
RestAuthorizeTrait | |
100.00% |
21 / 21 |
|
100.00% |
4 / 4 |
9 | |
100.00% |
1 / 1 |
authorizeActionOrThrow | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
authorizeReadOrThrow | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
authorizeWriteOrThrow | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
handleStatus | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Rest\Handler\Helper; |
4 | |
5 | use MediaWiki\Page\PageIdentity; |
6 | use MediaWiki\Permissions\Authority; |
7 | use MediaWiki\Permissions\PermissionStatus; |
8 | use MediaWiki\Rest\HttpException; |
9 | use Wikimedia\Message\MessageValue; |
10 | |
11 | trait RestAuthorizeTrait { |
12 | use RestStatusTrait; |
13 | |
14 | /** |
15 | * Authorize an action |
16 | * |
17 | * @see Authroity::authorizeWrite |
18 | * @throws HttpException |
19 | */ |
20 | private function authorizeActionOrThrow( |
21 | Authority $authority, |
22 | string $action |
23 | ): void { |
24 | $status = PermissionStatus::newEmpty(); |
25 | if ( !$authority->authorizeAction( $action, $status ) ) { |
26 | $this->handleStatus( $status ); |
27 | } |
28 | } |
29 | |
30 | /** |
31 | * Authorize a read operation |
32 | * |
33 | * @see Authroity::authorizeWrite |
34 | * @throws HttpException |
35 | */ |
36 | private function authorizeReadOrThrow( |
37 | Authority $authority, |
38 | string $action, |
39 | PageIdentity $target |
40 | ): void { |
41 | $status = PermissionStatus::newEmpty(); |
42 | if ( !$authority->authorizeRead( $action, $target, $status ) ) { |
43 | $this->handleStatus( $status ); |
44 | } |
45 | } |
46 | |
47 | /** |
48 | * Authorize a write operation |
49 | * |
50 | * @see Authroity::authorizeWrite |
51 | * @throws HttpException |
52 | */ |
53 | private function authorizeWriteOrThrow( |
54 | Authority $authority, |
55 | string $action, |
56 | PageIdentity $target |
57 | ): void { |
58 | $status = PermissionStatus::newEmpty(); |
59 | if ( !$authority->authorizeWrite( $action, $target, $status ) ) { |
60 | $this->handleStatus( $status ); |
61 | } |
62 | } |
63 | |
64 | /** |
65 | * Throw an exception if the status contains an error. |
66 | * |
67 | * @throws HttpException |
68 | * @return never |
69 | */ |
70 | private function handleStatus( PermissionStatus $status ): void { |
71 | // The permission name should always be set, but don't explode if it isn't. |
72 | $permission = $status->getPermission() ?: '(unknown)'; |
73 | |
74 | if ( $status->isRateLimitExceeded() ) { |
75 | $this->throwExceptionForStatus( |
76 | $status, |
77 | MessageValue::new( 'rest-rate-limit-exceeded', [ $permission ] ), |
78 | 429 // See https://www.rfc-editor.org/rfc/rfc6585#section-4 |
79 | ); |
80 | } |
81 | |
82 | $this->throwExceptionForStatus( |
83 | $status, |
84 | MessageValue::new( 'rest-permission-error', [ $permission ] ), |
85 | 403 |
86 | ); |
87 | } |
88 | |
89 | } |