This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace CodexShaper\OAuth2\Server; |
||
4 | |||
5 | use CodexShaper\OAuth2\Server\Repositories\AccessTokenRepository; |
||
6 | use CodexShaper\OAuth2\Server\Repositories\AuthCodeRepository; |
||
7 | use CodexShaper\OAuth2\Server\Repositories\ClientRepository; |
||
8 | use CodexShaper\OAuth2\Server\Repositories\RefreshTokenRepository; |
||
9 | use CodexShaper\OAuth2\Server\Repositories\ScopeRepository; |
||
10 | use CodexShaper\OAuth2\Server\Repositories\UserRepository; |
||
11 | use DateInterval; |
||
12 | use Defuse\Crypto\Key; |
||
13 | use League\OAuth2\Server\AuthorizationServer; |
||
14 | use League\OAuth2\Server\CryptKey; |
||
15 | use League\OAuth2\Server\Grant\AuthCodeGrant; |
||
16 | use League\OAuth2\Server\Grant\ClientCredentialsGrant; |
||
17 | use League\OAuth2\Server\Grant\ImplicitGrant; |
||
18 | use League\OAuth2\Server\Grant\PasswordGrant; |
||
19 | use League\OAuth2\Server\Grant\RefreshTokenGrant; |
||
20 | use League\OAuth2\Server\ResourceServer; |
||
21 | use phpseclib\Crypt\RSA; |
||
22 | |||
23 | class Manager |
||
24 | { |
||
25 | /** |
||
26 | * Authorization server. |
||
27 | * |
||
28 | * @var string |
||
29 | */ |
||
30 | protected $server; |
||
31 | |||
32 | /** |
||
33 | * All scopes. |
||
34 | * |
||
35 | * @var string |
||
36 | */ |
||
37 | protected static $scopes = [ |
||
38 | 'read' => 'Read', |
||
39 | 'read_write' => 'Read and Write', |
||
40 | ]; |
||
41 | |||
42 | /** |
||
43 | * Default scope. |
||
44 | * |
||
45 | * @var string |
||
46 | */ |
||
47 | protected static $defaultScope; |
||
48 | |||
49 | /** |
||
50 | * Enable or didable implicit grant. |
||
51 | * |
||
52 | * @var string |
||
53 | */ |
||
54 | protected $isEnableImplicitGrant = false; |
||
55 | |||
56 | /** |
||
57 | * Refresh token expire at. |
||
58 | * |
||
59 | * @var string |
||
60 | */ |
||
61 | protected static $refreshTokensExpireAt = 'P1Y'; |
||
62 | |||
63 | /** |
||
64 | * token exipre at. |
||
65 | * |
||
66 | * @var string |
||
67 | */ |
||
68 | protected static $tokensExpireAt = 'P1Y'; |
||
69 | |||
70 | /** |
||
71 | * Create RSA authorisation keys. |
||
72 | * |
||
73 | * @return void |
||
74 | */ |
||
75 | public static function keys($dir = null) |
||
76 | { |
||
77 | if (!$dir) { |
||
78 | $dir = __DIR__.'/../storage/rsa'; |
||
79 | } |
||
80 | |||
81 | if (!is_dir($dir)) { |
||
82 | mkdir($dir, 0777, true); |
||
83 | } |
||
84 | |||
85 | $publicKey = $dir.'/oauth-public.key'; |
||
86 | $privateKey = $dir.'/oauth-private.key'; |
||
87 | $rsa = new RSA(); |
||
88 | $keys = $rsa->createKey(4096); |
||
89 | |||
90 | file_put_contents($publicKey, $keys['publickey']); |
||
91 | file_put_contents($privateKey, $keys['privatekey']); |
||
92 | } |
||
93 | |||
94 | /** |
||
95 | * Add New scopes. |
||
96 | * |
||
97 | * @return void |
||
98 | */ |
||
99 | public static function setScopes(array $scopes = []) |
||
100 | { |
||
101 | if (!empty($scopes)) { |
||
102 | return; |
||
103 | } |
||
104 | |||
105 | static::$scopes = array_merge(static::$scopes, $scopes); |
||
106 | } |
||
107 | |||
108 | /** |
||
109 | * Get all available scopes. |
||
110 | * |
||
111 | * @return array |
||
112 | */ |
||
113 | public static function getScopes() |
||
114 | { |
||
115 | return static::$scopes; |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * Given a client, grant type and optional user identifier validate the set of scopes requested are valid and optionally |
||
120 | * append additional scopes or remove requested scopes. |
||
121 | * |
||
122 | * @param \League\OAuth2\Server\Entities\ScopeEntityInterface[] $scopes |
||
123 | * @param string $grantType |
||
124 | * @param \League\OAuth2\Server\Entities\ClientEntityInterface $clientEntity |
||
125 | * @param null|string $userIdentifier |
||
126 | * |
||
127 | * @return \League\OAuth2\Server\Entities\ScopeEntityInterface[] |
||
128 | */ |
||
129 | public static function filterScopes($scopes, $grantType) |
||
130 | { |
||
131 | if (!in_array($grantType, ['password', 'personal_access', 'client_credentials'])) { |
||
132 | $scopes = array_filter($scopes, function ($scope) { |
||
133 | return trim($scope->getIdentifier()) !== '*'; |
||
134 | }); |
||
135 | } |
||
136 | |||
137 | return array_filter($scopes, function ($scope) { |
||
138 | return static::hasScope($scope->getIdentifier()); |
||
139 | }); |
||
140 | } |
||
141 | |||
142 | /** |
||
143 | * Create a CryptKey instance without permissions check. |
||
144 | * |
||
145 | * @param string $identifier |
||
146 | * |
||
147 | * @return bool |
||
148 | */ |
||
149 | public static function hasScope($identifier) |
||
150 | { |
||
151 | return trim($identifier) === '*' || array_key_exists($identifier, static::$scopes); |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * Check is isset a scope or not. |
||
156 | * |
||
157 | * @param string $identifier |
||
158 | * |
||
159 | * @return bool |
||
160 | */ |
||
161 | public static function isValidateScope($identifier) |
||
162 | { |
||
163 | return array_key_exists($identifier, static::$scopes); |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * Make the authorization service instance. |
||
168 | * |
||
169 | * @return \League\OAuth2\Server\AuthorizationServer |
||
170 | */ |
||
171 | public function makeAuthorizationServer() |
||
172 | { |
||
173 | $encryptionKey = 'def00000069ceedc03a1f91fd51a49ce08ebb8580d688f4fbc3774c86aaa4df516eea0f72c1f62e3e577ec9f0c83c773b890222966bf93ac22e84a9eca55638be310665b'; |
||
174 | |||
175 | $this->server = new AuthorizationServer( |
||
176 | new ClientRepository(), |
||
177 | new AccessTokenRepository(), |
||
178 | new ScopeRepository(), |
||
179 | $this->makeCryptKey('private'), |
||
180 | Key::loadFromAsciiSafeString($encryptionKey) |
||
181 | ); |
||
182 | |||
183 | $this->server->setDefaultScope(static::$defaultScope); |
||
184 | $this->enableGrantTypes(); |
||
185 | |||
186 | return $this->server; |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * Enable All grant types. |
||
191 | * |
||
192 | * @return void |
||
193 | */ |
||
194 | protected function enableGrantTypes() |
||
195 | { |
||
196 | $this->server->enableGrantType( |
||
197 | new ClientCredentialsGrant(), |
||
198 | new DateInterval(static::$tokensExpireAt) // access tokens will expire after 1 hour |
||
199 | ); |
||
200 | |||
201 | $this->enableAuthCodeGrant(); |
||
202 | $this->enablePasswordGrant(); |
||
203 | $this->enableRefreshTokenGrant(); |
||
204 | |||
205 | if ($this->isEnableImplicitGrant) { |
||
206 | $this->server->enableGrantType( |
||
207 | new ImplicitGrant(new DateInterval(static::$tokensExpireAt)), |
||
208 | new DateInterval(static::$tokensExpireAt) // access tokens will expire after 1 hour |
||
209 | ); |
||
210 | } |
||
211 | } |
||
212 | |||
213 | /** |
||
214 | * Enable Authorization code Grant. |
||
215 | * |
||
216 | * @return void |
||
217 | */ |
||
218 | View Code Duplication | protected function enableAuthCodeGrant() |
|
0 ignored issues
–
show
|
|||
219 | { |
||
220 | $authCodeGrant = new AuthCodeGrant( |
||
221 | new AuthCodeRepository(), |
||
222 | new RefreshTokenRepository(), |
||
223 | new DateInterval('PT10M') |
||
224 | ); |
||
225 | |||
226 | $authCodeGrant->setRefreshTokenTTL(new DateInterval(static::$refreshTokensExpireAt)); |
||
227 | |||
228 | $this->server->enableGrantType( |
||
229 | $authCodeGrant, |
||
230 | new DateInterval(static::$tokensExpireAt) |
||
231 | ); |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * Enable Password Grant. |
||
236 | * |
||
237 | * @return void |
||
238 | */ |
||
239 | View Code Duplication | protected function enablePasswordGrant() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
240 | { |
||
241 | $passwordGrant = new PasswordGrant( |
||
242 | new UserRepository(), |
||
243 | new RefreshTokenRepository() |
||
244 | ); |
||
245 | |||
246 | $passwordGrant->setRefreshTokenTTL(new DateInterval(static::$refreshTokensExpireAt)); // refresh tokens will expire after 1 month |
||
247 | |||
248 | // Enable the password grant on the server |
||
249 | $this->server->enableGrantType( |
||
250 | $passwordGrant, |
||
251 | new DateInterval(static::$tokensExpireAt) // access tokens will expire after 1 hour |
||
252 | ); |
||
253 | } |
||
254 | |||
255 | /** |
||
256 | * Enable Refresh token Grant. |
||
257 | * |
||
258 | * @return void |
||
259 | */ |
||
260 | View Code Duplication | protected function enableRefreshTokenGrant() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
261 | { |
||
262 | $refreshTokenGrant = new RefreshTokenGrant(new RefreshTokenRepository()); |
||
263 | $refreshTokenGrant->setRefreshTokenTTL(new \DateInterval(static::$refreshTokensExpireAt)); // new refresh tokens will expire after 1 month |
||
264 | |||
265 | // Enable the refresh token grant on the server |
||
266 | $this->server->enableGrantType( |
||
267 | $refreshTokenGrant, |
||
268 | new \DateInterval(static::$tokensExpireAt) // new access tokens will expire after an hour |
||
269 | ); |
||
270 | } |
||
271 | |||
272 | /** |
||
273 | * Create a resource server for validation. |
||
274 | * |
||
275 | * @return \League\OAuth2\Server\ResourServer |
||
276 | */ |
||
277 | public function getResourceServer() |
||
278 | { |
||
279 | return new ResourceServer( |
||
280 | new AccessTokenRepository(), |
||
281 | $this->makeCryptKey('public') |
||
282 | ); |
||
283 | } |
||
284 | |||
285 | /** |
||
286 | * Create a CryptKey instance without permissions check. |
||
287 | * |
||
288 | * @param string $key |
||
289 | * |
||
290 | * @return \League\OAuth2\Server\CryptKey |
||
291 | */ |
||
292 | protected function makeCryptKey($type) |
||
293 | { |
||
294 | $key = __DIR__.'/../storage/rsa/oauth-'.$type.'.key'; |
||
295 | |||
296 | return new CryptKey($key, null, false); |
||
297 | } |
||
298 | |||
299 | /** |
||
300 | * Validate user for current request. |
||
301 | * |
||
302 | * @param \Psr\Http\Message\ServerRequestInterface $request |
||
303 | * |
||
304 | * @return null|int |
||
305 | */ |
||
306 | public function validateUserForRequest($request) |
||
307 | { |
||
308 | $token = Model::instance('tokenModel')->find($request->getAttribute('oauth_access_token_id')); |
||
309 | $client = Model::instance('clientModel')->find($request->getAttribute('oauth_client_id')); |
||
310 | |||
311 | if (!$token || !$client) { |
||
312 | return null; |
||
313 | } |
||
314 | |||
315 | if (!$token->user_id && !$client->user_id) { |
||
316 | return null; |
||
317 | } |
||
318 | |||
319 | if ($token->user_id != null) { |
||
320 | return $token->user_id; |
||
321 | } |
||
322 | |||
323 | return $client->user_id; |
||
324 | } |
||
325 | |||
326 | /** |
||
327 | * Migrate tables. |
||
328 | * |
||
329 | * @param string $dir |
||
330 | * |
||
331 | * @return void |
||
332 | */ |
||
333 | View Code Duplication | public static function migrate($dir = null) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
334 | { |
||
335 | if (is_null($dir)) { |
||
336 | $dir = __DIR__.'/../database/migrations'; |
||
337 | } |
||
338 | |||
339 | foreach (glob($dir.'/*.php') as $file) { |
||
340 | require_once $file; |
||
341 | $table = pathinfo($file)['filename']; |
||
342 | (new $table())->up(); |
||
343 | } |
||
344 | } |
||
345 | |||
346 | /** |
||
347 | * Drop tables. |
||
348 | * |
||
349 | * @param string $dir |
||
350 | * |
||
351 | * @return void |
||
352 | */ |
||
353 | View Code Duplication | public static function rollback($dir = null) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
354 | { |
||
355 | if (is_null($dir)) { |
||
356 | $dir = __DIR__.'/../database/migrations'; |
||
357 | } |
||
358 | |||
359 | foreach (glob($dir.'/*.php') as $file) { |
||
360 | require_once $file; |
||
361 | $table = pathinfo($file)['filename']; |
||
362 | (new $table())->down(); |
||
363 | } |
||
364 | } |
||
365 | |||
366 | /** |
||
367 | * Drop and migrate fresh tables. |
||
368 | * |
||
369 | * @param string $dir |
||
370 | * |
||
371 | * @return void |
||
372 | */ |
||
373 | public static function refresh($dir = null) |
||
374 | { |
||
375 | if (is_null($dir)) { |
||
376 | $dir = __DIR__.'/../database/migrations'; |
||
377 | } |
||
378 | |||
379 | static::rollback($dir); |
||
380 | static::migrate($dir); |
||
381 | } |
||
382 | } |
||
383 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.