Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 59 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
AbstractClientHandler | |
0.00% |
0 / 59 |
|
0.00% |
0 / 4 |
182 | |
0.00% |
0 / 1 |
execute | |
0.00% |
0 / 29 |
|
0.00% |
0 / 1 |
42 | |||
getFixedParams | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
getParamMapping | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
getUnifiedParams | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
30 | |||
getSupportedRequestTypes | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\OAuth\Rest\Handler; |
4 | |
5 | use League\OAuth2\Server\Entities\AccessTokenEntityInterface; |
6 | use MediaWiki\Context\RequestContext; |
7 | use MediaWiki\Extension\OAuth\Backend\Utils; |
8 | use MediaWiki\Extension\OAuth\Control\ConsumerSubmitControl; |
9 | use MediaWiki\Extension\OAuth\Entity\ClientEntity; |
10 | use MediaWiki\Rest\Handler; |
11 | use MediaWiki\Rest\HttpException; |
12 | use MediaWiki\Rest\LocalizedHttpException; |
13 | use MediaWiki\Rest\ResponseInterface; |
14 | use Wikimedia\Message\MessageValue; |
15 | |
16 | /** |
17 | * This class serves as the base class for all operations |
18 | * on OAuth 2.0 clients over the REST API. |
19 | * It provides client initialization and basic checks on it, |
20 | * as well as parameter name mapping between OAuth 2.0 and 1.0 terminology |
21 | */ |
22 | abstract class AbstractClientHandler extends Handler { |
23 | |
24 | /** |
25 | * @return ResponseInterface |
26 | * @throws HttpException |
27 | */ |
28 | public function execute(): ResponseInterface { |
29 | // At this point we assume user is authenticated and has valid session |
30 | // Authentication can be achieved over CentralAuth or Access token in authorization header |
31 | $responseFactory = $this->getResponseFactory(); |
32 | $params = $this->getUnifiedParams(); |
33 | |
34 | $control = new ConsumerSubmitControl( |
35 | RequestContext::getMain(), |
36 | $params, |
37 | Utils::getCentralDB( DB_PRIMARY ) |
38 | ); |
39 | |
40 | $status = $control->submit(); |
41 | if ( $status->isGood() ) { |
42 | $value = $status->getValue(); |
43 | if ( isset( $value['result']['consumer'] ) ) { |
44 | /** @var ClientEntity $client */ |
45 | $client = $value['result']['consumer']; |
46 | $data = [ |
47 | 'name' => $client->getName(), |
48 | 'client_key' => $client->getConsumerKey(), |
49 | 'secret' => Utils::hmacDBSecret( $client->getSecretKey() ) |
50 | ]; |
51 | if ( $client->getOwnerOnly() ) { |
52 | $accessToken = $value['result']['accessToken']; |
53 | if ( $accessToken instanceof AccessTokenEntityInterface ) { |
54 | $data['access_token'] = (string)$accessToken; |
55 | } |
56 | } |
57 | |
58 | return $responseFactory->createJson( $data ); |
59 | } |
60 | |
61 | throw new LocalizedHttpException( |
62 | MessageValue::new( 'mwoauth-consumer-submit-error' ), 400 |
63 | ); |
64 | } |
65 | $value = $status->getValue(); |
66 | if ( isset( $value['error'] ) ) { |
67 | throw new HttpException( $value['error'], 400 ); |
68 | } |
69 | |
70 | throw new HttpException( $status->getMessage() ); |
71 | } |
72 | |
73 | /** |
74 | * Get params that have fixed values and cannot be |
75 | * changed by the request params |
76 | * |
77 | * @return array |
78 | */ |
79 | abstract protected function getFixedParams(): array; |
80 | |
81 | /** |
82 | * Maps modern OAuth2 param names to the ones |
83 | * expected by the SubmitControl |
84 | * |
85 | * @return string[] |
86 | */ |
87 | protected function getParamMapping(): array { |
88 | return [ |
89 | 'oauth2IsConfidential' => 'is_confidential', |
90 | 'ownerOnly' => 'owner_only', |
91 | 'callbackUrl' => 'callback_url', |
92 | 'callbackIsPrefix' => 'callback_is_prefix', |
93 | 'oauth2GrantTypes' => 'grant_types', |
94 | 'grants' => 'scopes', |
95 | 'consumerKey' => 'client_key', |
96 | ]; |
97 | } |
98 | |
99 | /** |
100 | * Merge and adjust all params |
101 | * |
102 | * @return array |
103 | */ |
104 | protected function getUnifiedParams(): array { |
105 | $finalParams = []; |
106 | |
107 | $requestParams = $this->getValidatedParams(); |
108 | $mapping = array_flip( $this->getParamMapping() ); |
109 | foreach ( $requestParams as $name => $value ) { |
110 | if ( isset( $mapping[$name] ) ) { |
111 | $finalParams[$mapping[$name]] = $value; |
112 | } else { |
113 | $finalParams[$name] = $value; |
114 | } |
115 | } |
116 | |
117 | $bodyParams = $this->getValidatedBody(); |
118 | foreach ( $bodyParams as $name => $value ) { |
119 | if ( isset( $mapping[$name] ) ) { |
120 | $finalParams[$mapping[$name]] = $value; |
121 | } else { |
122 | $finalParams[$name] = $value; |
123 | } |
124 | } |
125 | |
126 | $finalParams = array_merge( |
127 | $finalParams, |
128 | $this->getFixedParams() |
129 | ); |
130 | |
131 | return $finalParams; |
132 | } |
133 | |
134 | /** |
135 | * @return string[] |
136 | */ |
137 | public function getSupportedRequestTypes(): array { |
138 | return [ |
139 | 'application/json', |
140 | 'application/x-www-form-urlencoded' |
141 | ]; |
142 | } |
143 | } |