Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
RestAuthorizeTrait
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
4 / 4
9
100.00% covered (success)
100.00%
1 / 1
 authorizeActionOrThrow
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 authorizeReadOrThrow
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 authorizeWriteOrThrow
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 handleStatus
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace MediaWiki\Rest\Handler\Helper;
4
5use MediaWiki\Page\PageIdentity;
6use MediaWiki\Permissions\Authority;
7use MediaWiki\Permissions\PermissionStatus;
8use MediaWiki\Rest\HttpException;
9use Wikimedia\Message\MessageValue;
10
11trait 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}