Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
85.14% |
63 / 74 |
|
60.00% |
3 / 5 |
CRAP | |
0.00% |
0 / 1 |
AccessToken | |
85.14% |
63 / 74 |
|
60.00% |
3 / 5 |
12.47 | |
0.00% |
0 / 1 |
getSupportedRequestTypes | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
execute | |
62.50% |
10 / 16 |
|
0.00% |
0 / 1 |
4.84 | |||
getBodyParamSettings | |
100.00% |
46 / 46 |
|
100.00% |
1 / 1 |
1 | |||
getGrantType | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getGrantClass | |
28.57% |
2 / 7 |
|
0.00% |
0 / 1 |
14.11 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\OAuth\Rest\Handler; |
4 | |
5 | use GuzzleHttp\Psr7\ServerRequest; |
6 | use League\OAuth2\Server\Exception\OAuthServerException; |
7 | use MediaWiki\Extension\OAuth\AuthorizationProvider\Grant\AuthorizationCodeAccessTokens; |
8 | use MediaWiki\Extension\OAuth\AuthorizationProvider\Grant\ClientCredentials; |
9 | use MediaWiki\Extension\OAuth\AuthorizationProvider\Grant\RefreshToken; |
10 | use MediaWiki\Extension\OAuth\Response; |
11 | use MWExceptionHandler; |
12 | use Throwable; |
13 | use Wikimedia\ParamValidator\ParamValidator; |
14 | |
15 | /** |
16 | * Handles the oauth2/access_token endpoint, which can be used after the user has returned from |
17 | * the authorization dialog to trade the off the received authorization code for an access token. |
18 | */ |
19 | class AccessToken extends AuthenticationHandler { |
20 | |
21 | private const GRANT_TYPE_CLIENT_CREDENTIALS = 'client_credentials'; |
22 | private const GRANT_TYPE_AUTHORIZATION_CODE = 'authorization_code'; |
23 | private const GRANT_TYPE_REFRESH_TOKEN = 'refresh_token'; |
24 | |
25 | /** |
26 | * Support x-www-form-urlencoded (and nothing else), as required by RFC 6749. |
27 | * @return string[] |
28 | */ |
29 | public function getSupportedRequestTypes(): array { |
30 | return [ |
31 | 'application/x-www-form-urlencoded', |
32 | ]; |
33 | } |
34 | |
35 | /** |
36 | * @inheritDoc |
37 | */ |
38 | public function execute() { |
39 | $response = new Response(); |
40 | |
41 | try { |
42 | if ( $this->queuedError ) { |
43 | throw $this->queuedError; |
44 | } |
45 | $request = ServerRequest::fromGlobals()->withParsedBody( |
46 | $this->getValidatedBody() |
47 | ); |
48 | |
49 | $authProvider = $this->getAuthorizationProvider(); |
50 | return $authProvider->getAccessTokens( $request, $response ); |
51 | } catch ( OAuthServerException $exception ) { |
52 | return $this->errorResponse( $exception, $response ); |
53 | } catch ( Throwable $exception ) { |
54 | MWExceptionHandler::logException( $exception ); |
55 | return $this->errorResponse( |
56 | OAuthServerException::serverError( $exception->getMessage(), $exception ), |
57 | $response |
58 | ); |
59 | } |
60 | } |
61 | |
62 | /** |
63 | * @inheritDoc |
64 | */ |
65 | public function getBodyParamSettings(): array { |
66 | return [ |
67 | 'grant_type' => [ |
68 | self::PARAM_SOURCE => 'body', |
69 | ParamValidator::PARAM_TYPE => [ |
70 | self::GRANT_TYPE_CLIENT_CREDENTIALS, |
71 | self::GRANT_TYPE_AUTHORIZATION_CODE, |
72 | self::GRANT_TYPE_REFRESH_TOKEN, |
73 | ], |
74 | ParamValidator::PARAM_REQUIRED => true, |
75 | ], |
76 | 'client_id' => [ |
77 | self::PARAM_SOURCE => 'body', |
78 | ParamValidator::PARAM_TYPE => 'string', |
79 | ParamValidator::PARAM_REQUIRED => false, |
80 | ], |
81 | 'client_secret' => [ |
82 | self::PARAM_SOURCE => 'body', |
83 | ParamValidator::PARAM_TYPE => 'string', |
84 | ParamValidator::PARAM_REQUIRED => false, |
85 | ], |
86 | 'redirect_uri' => [ |
87 | self::PARAM_SOURCE => 'body', |
88 | ParamValidator::PARAM_TYPE => 'string', |
89 | ParamValidator::PARAM_REQUIRED => false, |
90 | ], |
91 | 'scope' => [ |
92 | self::PARAM_SOURCE => 'body', |
93 | ParamValidator::PARAM_TYPE => 'string', |
94 | ParamValidator::PARAM_REQUIRED => false, |
95 | ], |
96 | 'code' => [ |
97 | self::PARAM_SOURCE => 'body', |
98 | ParamValidator::PARAM_TYPE => 'string', |
99 | ParamValidator::PARAM_REQUIRED => false, |
100 | ], |
101 | 'refresh_token' => [ |
102 | self::PARAM_SOURCE => 'body', |
103 | ParamValidator::PARAM_TYPE => 'string', |
104 | ParamValidator::PARAM_REQUIRED => false, |
105 | ], |
106 | 'code_verifier' => [ |
107 | self::PARAM_SOURCE => 'body', |
108 | ParamValidator::PARAM_TYPE => 'string', |
109 | ParamValidator::PARAM_REQUIRED => false, |
110 | ] |
111 | ]; |
112 | } |
113 | |
114 | /** |
115 | * @return string |
116 | */ |
117 | protected function getGrantType() { |
118 | $body = $this->getValidatedBody(); |
119 | '@phan-var array $body'; |
120 | return $body['grant_type']; |
121 | } |
122 | |
123 | /** |
124 | * @param string $grantType |
125 | * @return string|false |
126 | */ |
127 | protected function getGrantClass( $grantType ) { |
128 | switch ( $grantType ) { |
129 | case static::GRANT_TYPE_AUTHORIZATION_CODE: |
130 | return AuthorizationCodeAccessTokens::class; |
131 | case static::GRANT_TYPE_CLIENT_CREDENTIALS: |
132 | return ClientCredentials::class; |
133 | case static::GRANT_TYPE_REFRESH_TOKEN: |
134 | return RefreshToken::class; |
135 | default: |
136 | return false; |
137 | } |
138 | } |
139 | } |