Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
84.29% covered (warning)
84.29%
59 / 70
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
AccessToken
84.29% covered (warning)
84.29%
59 / 70
50.00% covered (danger)
50.00%
2 / 4
11.47
0.00% covered (danger)
0.00%
0 / 1
 execute
62.50% covered (warning)
62.50%
10 / 16
0.00% covered (danger)
0.00%
0 / 1
4.84
 getParamSettings
100.00% covered (success)
100.00%
46 / 46
100.00% covered (success)
100.00%
1 / 1
1
 getGrantKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGrantClass
28.57% covered (danger)
28.57%
2 / 7
0.00% covered (danger)
0.00%
0 / 1
14.11
1<?php
2
3namespace MediaWiki\Extension\OAuth\Rest\Handler;
4
5use GuzzleHttp\Psr7\ServerRequest;
6use League\OAuth2\Server\Exception\OAuthServerException;
7use MediaWiki\Extension\OAuth\AuthorizationProvider\Grant\AuthorizationCodeAccessTokens;
8use MediaWiki\Extension\OAuth\AuthorizationProvider\Grant\ClientCredentials;
9use MediaWiki\Extension\OAuth\AuthorizationProvider\Grant\RefreshToken;
10use MediaWiki\Extension\OAuth\Response;
11use MWExceptionHandler;
12use Throwable;
13use 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 */
19class 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     * @inheritDoc
27     */
28    public function execute() {
29        $response = new Response();
30
31        try {
32            if ( $this->queuedError ) {
33                throw $this->queuedError;
34            }
35            $request = ServerRequest::fromGlobals()->withParsedBody(
36                $this->getValidatedParams()
37            );
38
39            $authProvider = $this->getAuthorizationProvider();
40            return $authProvider->getAccessTokens( $request, $response );
41        } catch ( OAuthServerException $exception ) {
42            return $this->errorResponse( $exception, $response );
43        } catch ( Throwable $exception ) {
44            MWExceptionHandler::logException( $exception );
45            return $this->errorResponse(
46                OAuthServerException::serverError( $exception->getMessage(), $exception ),
47                $response
48            );
49        }
50    }
51
52    /**
53     * @inheritDoc
54     */
55    public function getParamSettings() {
56        return [
57            'grant_type' => [
58                self::PARAM_SOURCE => 'post',
59                ParamValidator::PARAM_TYPE => [
60                    self::GRANT_TYPE_CLIENT_CREDENTIALS,
61                    self::GRANT_TYPE_AUTHORIZATION_CODE,
62                    self::GRANT_TYPE_REFRESH_TOKEN,
63                ],
64                ParamValidator::PARAM_REQUIRED => true,
65            ],
66            'client_id' => [
67                self::PARAM_SOURCE => 'post',
68                ParamValidator::PARAM_TYPE => 'string',
69                ParamValidator::PARAM_REQUIRED => false,
70            ],
71            'client_secret' => [
72                self::PARAM_SOURCE => 'post',
73                ParamValidator::PARAM_TYPE => 'string',
74                ParamValidator::PARAM_REQUIRED => false,
75            ],
76            'redirect_uri' => [
77                self::PARAM_SOURCE => 'post',
78                ParamValidator::PARAM_TYPE => 'string',
79                ParamValidator::PARAM_REQUIRED => false,
80            ],
81            'scope' => [
82                self::PARAM_SOURCE => 'post',
83                ParamValidator::PARAM_TYPE => 'string',
84                ParamValidator::PARAM_REQUIRED => false,
85            ],
86            'code' => [
87                self::PARAM_SOURCE => 'post',
88                ParamValidator::PARAM_TYPE => 'string',
89                ParamValidator::PARAM_REQUIRED => false,
90            ],
91            'refresh_token' => [
92                self::PARAM_SOURCE => 'post',
93                ParamValidator::PARAM_TYPE => 'string',
94                ParamValidator::PARAM_REQUIRED => false,
95            ],
96            'code_verifier' => [
97                self::PARAM_SOURCE => 'post',
98                ParamValidator::PARAM_TYPE => 'string',
99                ParamValidator::PARAM_REQUIRED => false,
100            ]
101        ];
102    }
103
104    /**
105     * @return string
106     */
107    protected function getGrantKey() {
108        return 'grant_type';
109    }
110
111    /**
112     * @param string $grantKey
113     * @return string|false
114     */
115    protected function getGrantClass( $grantKey ) {
116        switch ( $grantKey ) {
117            case static::GRANT_TYPE_AUTHORIZATION_CODE:
118                return AuthorizationCodeAccessTokens::class;
119            case static::GRANT_TYPE_CLIENT_CREDENTIALS:
120                return ClientCredentials::class;
121            case static::GRANT_TYPE_REFRESH_TOKEN:
122                return RefreshToken::class;
123            default:
124                return false;
125        }
126    }
127}