Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
94.44% |
17 / 18 |
|
50.00% |
1 / 2 |
CRAP | |
0.00% |
0 / 1 |
ReadingListsTokenAwareHandlerTrait | |
94.44% |
17 / 18 |
|
50.00% |
1 / 2 |
6.01 | |
0.00% |
0 / 1 |
getReadingListsTokenParamDefinition | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
getToken | |
90.91% |
10 / 11 |
|
0.00% |
0 / 1 |
5.02 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\ReadingLists\Rest; |
4 | |
5 | use LogicException; |
6 | use MediaWiki\Rest\Handler; |
7 | use MediaWiki\Rest\TokenAwareHandlerTrait; |
8 | use Wikimedia\ParamValidator\ParamValidator; |
9 | |
10 | /** |
11 | * Adds csrf token handling for Reading Lists. |
12 | * |
13 | * The Reading Lists REST endpoints replaced endpoints of the same contract in RESTBase. |
14 | * They therefore have to accept csrf tokens in an unusual way: as a query parameter |
15 | * named "csrf_token". They will also accept tokens in the usual way: as a body |
16 | * parameter named "token". If callers can eventually convert to the usual way, then this |
17 | * class can be removed in favor of using only the core TokenAwareHandlerTrait. |
18 | * |
19 | * Handlers that use this trait should: |
20 | * 1) override getBodyValidator() to use getTokenParamDefinition() |
21 | * 2) extend validate() to call validateToken() |
22 | * 3) extend getParamSettings() to include the return value from getTokenParamSettings() |
23 | * |
24 | * @see Handler::requireSafeAgainstCsrf() |
25 | * @see TokenAwareHandlerTrait |
26 | * |
27 | * @package MediaWiki\Rest |
28 | */ |
29 | trait ReadingListsTokenAwareHandlerTrait { |
30 | use TokenAwareHandlerTrait; |
31 | |
32 | /** |
33 | * Returns the definition for the token parameter, to be used in getParamSettings(). |
34 | * |
35 | * @return array[] |
36 | */ |
37 | public function getReadingListsTokenParamDefinition() { |
38 | return [ |
39 | 'csrf_token' => [ |
40 | Handler::PARAM_SOURCE => 'query', |
41 | ParamValidator::PARAM_TYPE => 'string', |
42 | ParamValidator::PARAM_REQUIRED => false, |
43 | ] |
44 | ]; |
45 | } |
46 | |
47 | /** |
48 | * Determines the CSRF token to be used, possibly taking it from the request. |
49 | * |
50 | * Returns an empty string if the request isn't known to be safe and |
51 | * no token was supplied by the client. |
52 | * Returns null if the session provider is safe against CSRF (and thus no token |
53 | * is needed) |
54 | * |
55 | * @return string|null |
56 | */ |
57 | protected function getToken(): ?string { |
58 | if ( !$this instanceof Handler ) { |
59 | throw new LogicException( 'This trait must be used on handler classes.' ); |
60 | } |
61 | |
62 | if ( $this->getSession()->getProvider()->safeAgainstCsrf() ) { |
63 | return null; |
64 | } |
65 | |
66 | $body = $this->getValidatedBody(); |
67 | if ( !empty( $body['token'] ) ) { |
68 | return $body['token']; |
69 | } |
70 | |
71 | $params = $this->getValidatedParams(); |
72 | if ( isset( $params['csrf_token'] ) ) { |
73 | return $params['csrf_token']; |
74 | } |
75 | |
76 | return ''; |
77 | } |
78 | } |