OauthStorage   F
last analyzed

Complexity

Total Complexity 82

Size/Duplication

Total Lines 624
Duplicated Lines 0 %

Coupling/Cohesion

Components 8
Dependencies 6

Test Coverage

Coverage 98.32%

Importance

Changes 0
Metric Value
wmc 82
lcom 8
cbo 6
dl 0
loc 624
ccs 292
cts 297
cp 0.9832
rs 1.976
c 0
b 0
f 0

33 Methods

Rating   Name   Duplication   Size   Complexity  
A getAccessTokenClass() 0 8 2
A getAuthCodeClass() 0 8 2
A getClientClass() 0 8 2
A getCypherKeyClass() 0 8 2
A getJtiClass() 0 8 2
A getJwtClass() 0 8 2
A getRefreshTokenClass() 0 8 2
A getScopeClass() 0 8 2
A getUserClass() 0 8 2
A getAccessToken() 0 33 5
A setAccessToken() 0 25 4
A unsetAccessToken() 0 10 2
A getAuthorizationCode() 0 17 2
A setAuthorizationCode() 0 21 3
A expireAuthorizationCode() 0 9 2
A getClientDetails() 0 16 4
A getClientScope() 0 10 2
A checkRestrictedGrantType() 0 12 3
A checkClientCredentials() 0 6 2
A isPublicClient() 0 6 2
A getJti() 0 22 2
A setJti() 0 15 2
A getClientKey() 0 13 2
A getPublicKey() 0 15 4
A getPrivateKey() 0 15 4
A getEncryptionAlgorithm() 0 15 4
A getRefreshToken() 0 16 2
A setRefreshToken() 0 19 3
A unsetRefreshToken() 0 9 2
A scopeExists() 0 8 1
A getDefaultScope() 0 10 2
A checkUserCredentials() 0 6 1
A getUserDetails() 0 17 4

How to fix   Complexity   

Complex Class

Complex classes like OauthStorage often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use OauthStorage, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * OauthStorage.php
4
 *
5
 * PHP version 5.6+
6
 *
7
 * @author pgaultier
8
 * @copyright 2010-2017 Philippe Gaultier
9
 * @license http://www.sweelix.net/license license
10
 * @version 1.2.0
11
 * @link http://www.sweelix.net
12
 * @packages sweelix\oauth2\server\storage
13
 */
14
15
namespace sweelix\oauth2\server\storage;
16
17
use OAuth2\Encryption\Jwt;
18
use OAuth2\OpenID\Storage\AuthorizationCodeInterface;
19
use OAuth2\Storage\AccessTokenInterface;
20
use OAuth2\Storage\ClientCredentialsInterface;
21
use OAuth2\Storage\JwtAccessTokenInterface;
22
use OAuth2\Storage\JwtBearerInterface;
23
use OAuth2\Storage\PublicKeyInterface;
24
use OAuth2\Storage\RefreshTokenInterface;
25
use OAuth2\Storage\ScopeInterface;
26
use OAuth2\Storage\UserCredentialsInterface;
27
use Yii;
28
use yii\helpers\ArrayHelper;
29
30
/**
31
 * OauthStorage class
32
 *
33
 * PHP version 5.6+
34
 *
35
 * @author pgaultier
36
 * @copyright 2010-2017 Philippe Gaultier
37
 * @license http://www.sweelix.net/license license
38
 * @version 1.2.0
39
 * @link http://www.sweelix.net
40
 * @packages sweelix\oauth2\server\storage
41
 * @since 1.0.0
42
 */
43
class OauthStorage implements
44
    AccessTokenInterface,
45
    AuthorizationCodeInterface,
46
    ClientCredentialsInterface,
47
    JwtAccessTokenInterface, // identical to AccessTokenInterface
48
    JwtBearerInterface,
49
    PublicKeyInterface,
50
    RefreshTokenInterface,
51
    ScopeInterface,
52
    UserCredentialsInterface
53
{
54
    /**
55
     * @var string
56
     */
57
    private $accessTokenClass;
58
59
    /**
60
     * @var string
61
     */
62
    private $authCodeClass;
63
64
    /**
65
     * @var string
66
     */
67
    private $clientClass;
68
69
    /**
70
     * @var string
71
     */
72
    private $cypherKeyClass;
73
74
    /**
75
     * @var string
76
     */
77
    private $jtiClass;
78
79
    /**
80
     * @var string
81
     */
82
    private $jwtClass;
83
84
    /**
85
     * @var string
86
     */
87
    private $refreshTokenClass;
88
89
    /**
90
     * @var string
91
     */
92
    private $scopeClass;
93
94
    /**
95
     * @var string
96
     */
97
    private $userClass;
98
99
    /**
100
     * @return string classname for selected interface
101 1
     * @throws \yii\base\InvalidConfigException
102
     * @since 1.0.0
103 1
     */
104 1
    protected function getAccessTokenClass()
105 1
    {
106 1
        if ($this->accessTokenClass === null) {
107 1
            $accessToken = Yii::createObject('sweelix\oauth2\server\interfaces\AccessTokenModelInterface');
108
            $this->accessTokenClass = get_class($accessToken);
109
        }
110
        return $this->accessTokenClass;
111
    }
112
113
    /**
114 2
     * @return string classname for selected interface
115
     * @throws \yii\base\InvalidConfigException
116 2
     * @since 1.0.0
117 2
     */
118 2
    protected function getAuthCodeClass()
119 2
    {
120 2
        if ($this->authCodeClass === null) {
121
            $authCode = Yii::createObject('sweelix\oauth2\server\interfaces\AuthCodeModelInterface');
122
            $this->authCodeClass = get_class($authCode);
123
        }
124
        return $this->authCodeClass;
125
    }
126
127 15
    /**
128
     * @return string classname for selected interface
129 15
     * @throws \yii\base\InvalidConfigException
130 15
     * @since 1.0.0
131 15
     */
132 15
    protected function getClientClass()
133 15
    {
134
        if ($this->clientClass === null) {
135
            $client = Yii::createObject('sweelix\oauth2\server\interfaces\ClientModelInterface');
136
            $this->clientClass = get_class($client);
137
        }
138
        return $this->clientClass;
139
    }
140 1
141
    /**
142 1
     * @return string classname for selected interface
143 1
     * @throws \yii\base\InvalidConfigException
144 1
     * @since 1.0.0
145 1
     */
146 1
    protected function getCypherKeyClass()
147
    {
148
        if ($this->cypherKeyClass === null) {
149
            $cypherKey = Yii::createObject('sweelix\oauth2\server\interfaces\CypherKeyModelInterface');
150
            $this->cypherKeyClass = get_class($cypherKey);
151
        }
152
        return $this->cypherKeyClass;
153 1
    }
154
155 1
    /**
156 1
     * @return string classname for selected interface
157 1
     * @throws \yii\base\InvalidConfigException
158 1
     * @since 1.0.0
159 1
     */
160
    protected function getJtiClass()
161
    {
162
        if ($this->jtiClass === null) {
163
            $jti = Yii::createObject('sweelix\oauth2\server\interfaces\JtiModelInterface');
164
            $this->jtiClass = get_class($jti);
165
        }
166 1
        return $this->jtiClass;
167
    }
168 1
169 1
    /**
170 1
     * @return string classname for selected interface
171 1
     * @throws \yii\base\InvalidConfigException
172 1
     * @since 1.0.0
173
     */
174
    protected function getJwtClass()
175
    {
176
        if ($this->jwtClass === null) {
177
            $jwt = Yii::createObject('sweelix\oauth2\server\interfaces\JwtModelInterface');
178
            $this->jwtClass = get_class($jwt);
179 2
        }
180
        return $this->jwtClass;
181 2
    }
182 2
183 2
    /**
184 2
     * @return string classname for selected interface
185 2
     * @throws \yii\base\InvalidConfigException
186
     * @since 1.0.0
187
     */
188
    protected function getRefreshTokenClass()
189
    {
190
        if ($this->refreshTokenClass === null) {
191
            $refreshToken = Yii::createObject('sweelix\oauth2\server\interfaces\RefreshTokenModelInterface');
192 8
            $this->refreshTokenClass = get_class($refreshToken);
193
        }
194 8
        return $this->refreshTokenClass;
195 8
    }
196 8
197 8
    /**
198 8
     * @return string classname for selected interface
199
     * @throws \yii\base\InvalidConfigException
200
     * @since 1.0.0
201
     */
202
    public function getScopeClass()
203
    {
204
        if ($this->scopeClass === null) {
205 4
            $scope = Yii::createObject('sweelix\oauth2\server\interfaces\ScopeModelInterface');
206
            $this->scopeClass = get_class($scope);
207 4
        }
208 4
        return $this->scopeClass;
209 4
    }
210 4
211 4
    /**
212
     * @return string classname for selected interface
213
     * @throws \yii\base\InvalidConfigException
214
     * @since 1.0.0
215
     */
216
    public function getUserClass()
217 1
    {
218
        if ($this->userClass === null) {
219 1
            $scope = Yii::createObject('sweelix\oauth2\server\interfaces\UserModelInterface');
220 1
            $this->userClass = get_class($scope);
221
        }
222 1
        return $this->userClass;
223
    }
224 1
225 1
    /**
226 1
     * @inheritdoc
227 1
     */
228 1
    public function getAccessToken($oauth_token)
229 1
    {
230 1
        $accessToken = null;
231 1
        $accessTokenClass = $this->getAccessTokenClass();
232 1
        if (preg_match($accessTokenClass::JWT_REGEX, $oauth_token)) {
233
            $jwt = new Jwt();
234
            $decodedJwt = $jwt->decode($oauth_token, null, false);
235
            $key = $this->getPublicKey($decodedJwt['aud']);
236
            if (($key !== null) && ($decodedJwt = $jwt->decode($oauth_token, $key, true))) {
237
                $accessToken = ArrayHelper::merge([
238 6
                    'expires' => $decodedJwt['exp'],
239
                    'client_id' => $decodedJwt['aud'],
240 6
                    'user_id' => $decodedJwt['sub'],
241
                    'scope' => $decodedJwt['scope'],
242 6
                    'id_token' => $decodedJwt['jti'],
243 6
                ], $decodedJwt);
244 6
            }
245 6
        } else {
246 6
            $accessToken = $accessTokenClass::findOne($oauth_token);
247 6
            /* @var \sweelix\oauth2\server\interfaces\AccessTokenModelInterface $accessToken */
248 6
            if ($accessToken !== null) {
249 1
                $finalToken = [
250
                    'expires' => $accessToken->expiry,
0 ignored issues
show
Bug introduced by
Accessing expiry on the interface sweelix\oauth2\server\in...cessTokenModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
251 6
                    'client_id' => $accessToken->clientId,
0 ignored issues
show
Bug introduced by
Accessing clientId on the interface sweelix\oauth2\server\in...cessTokenModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
252 6
                    'user_id' => $accessToken->userId,
0 ignored issues
show
Bug introduced by
Accessing userId on the interface sweelix\oauth2\server\in...cessTokenModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
253
                    'scope' => implode(' ', $accessToken->scopes),
0 ignored issues
show
Bug introduced by
Accessing scopes on the interface sweelix\oauth2\server\in...cessTokenModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
254
                    'id_token' => $accessToken->id,
0 ignored issues
show
Bug introduced by
Accessing id on the interface sweelix\oauth2\server\in...cessTokenModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
255
                ];
256
                $accessToken = $finalToken;
257
            }
258 1
        }
259
        return $accessToken;
260 1
    }
261 1
262
    /**
263 1
     * @inheritdoc
264 1
     */
265
    public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null)
266
    {
267
        $response = false;
268
        if ($expires > time()) {
269
            $accessTokenClass = $this->getAccessTokenClass();
270
            if (preg_match($accessTokenClass::JWT_REGEX, $oauth_token)) {
271
                $response = true;
272 2
            } else {
273
                $accessToken = Yii::createObject('sweelix\oauth2\server\interfaces\AccessTokenModelInterface');
274 2
                /* @var \sweelix\oauth2\server\interfaces\AccessTokenModelInterface $accessToken */
275 2
                $accessToken->id = $oauth_token;
0 ignored issues
show
Bug introduced by
Accessing id on the interface sweelix\oauth2\server\in...cessTokenModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
276 2
                $accessToken->clientId = $client_id;
0 ignored issues
show
Bug introduced by
Accessing clientId on the interface sweelix\oauth2\server\in...cessTokenModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
277
                $accessToken->userId = $user_id;
0 ignored issues
show
Bug introduced by
Accessing userId on the interface sweelix\oauth2\server\in...cessTokenModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
278 2
                $accessToken->expiry = $expires;
0 ignored issues
show
Bug introduced by
Accessing expiry on the interface sweelix\oauth2\server\in...cessTokenModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
279 2
                if ($scope === null) {
280 2
                    $scopes = [];
281 2
                } else {
282 2
                    $scopes = explode(' ', $scope);
283 2
                }
284 2
                $accessToken->scopes = $scopes;
0 ignored issues
show
Bug introduced by
Accessing scopes on the interface sweelix\oauth2\server\in...cessTokenModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
285 2
                $response = $accessToken->save();
286 2
            }
287 2
        }
288
        return $response;
289
    }
290
291
    /**
292
     * @inheritdoc
293 2
     */
294
    public function unsetAccessToken($access_token)
295 2
    {
296 2
        $accessTokenClass = $this->getAccessTokenClass();
297 2
        $accessToken = $accessTokenClass::findOne($access_token);
298 2
        /* @var \sweelix\oauth2\server\interfaces\AccessTokenModelInterface $accessToken */
299 2
        if ($accessToken !== null) {
300 2
            return $accessToken->delete();
301 2
        }
302 2
        return true;
303 2
    }
304 2
305 1
    /**
306
     * @inheritdoc
307 2
     */
308 2
    public function getAuthorizationCode($code)
309
    {
310
        $authCodeClass = $this->getAuthCodeClass();
311
        $authCode = $authCodeClass::findOne($code);
312
        if ($authCode !== null) {
313
            $finalCode = [
314 2
                'client_id' => $authCode->clientId,
315
                'user_id' => $authCode->userId,
316 2
                'expires' => $authCode->expiry,
317 2
                'redirect_uri' => $authCode->redirectUri,
318 2
                'scope' => implode(' ', $authCode->scopes),
319 2
                'id_token' => $authCode->tokenId,
320
            ];
321
            $authCode = $finalCode;
322
        }
323
        return $authCode;
324
    }
325
326 10
    /**
327
     * @inheritdoc
328 10
     */
329 10
    public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
330 10
    {
331
        $response = false;
332 8
        if ($expires > time()) {
333 8
            $authCode = Yii::createObject('sweelix\oauth2\server\interfaces\AuthCodeModelInterface');
334 8
            $authCode->id = $code;
335 8
            $authCode->clientId = $client_id;
336 8
            $authCode->userId = $user_id;
337 8
            $authCode->redirectUri = $redirect_uri;
338 8
            $authCode->expiry = $expires;
339 8
            $authCode->tokenId = $id_token;
340 10
            if ($scope === null) {
341
                $scopes = [];
342
            } else {
343
                $scopes = explode(' ', $scope);
344
            }
345
            $authCode->scopes = $scopes;
346 1
            $response = $authCode->save();
347
        }
348 1
        return $response;
349 1
    }
350 1
351 1
    /**
352 1
     * @inheritdoc
353 1
     */
354 1
    public function expireAuthorizationCode($code)
355
    {
356
        $authCodeClass = $this->getAuthCodeClass();
357
        $authCode = $authCodeClass::findOne($code);
358
        if ($authCode !== null) {
359
            return $authCode->delete();
360 8
        }
361
        return true;
362 8
    }
363 8
364 8
    /**
365 8
     * @inheritdoc
366 8
     */
367 1
    public function getClientDetails($client_id)
368 1
    {
369 8
        $clientClass = $this->getClientClass();
370 8
        $client = $clientClass::findOne($client_id);
371
        if ($client !== null) {
372
            $finalClient = [
373
                'redirect_uri' => is_array($client->redirectUri) ? implode(' ', $client->redirectUri) : $client->redirectUri,
374
                'client_id' => $client->id,
375
                'grant_types' => $client->grantTypes,
376 8
                'user_id' => $client->userId,
377
                'scope' => implode(' ', $client->scopes),
378 8
            ];
379 8
            $client = $finalClient;
380 8
        }
381
        return ($client !== null) ? $client : false;
382
    }
383
384
    /**
385
     * @inheritdoc
386 1
     */
387
    public function getClientScope($client_id)
388 1
    {
389 1
        $clientClass = $this->getClientClass();
390 1
        $client = $clientClass::findOne($client_id);
391
        $scopes = '';
392
        if ($client !== null) {
393
            $scopes = implode(' ', $client->scopes);
394
        }
395
        return $scopes;
396 1
    }
397
398 1
    /**
399 1
     * @inheritdoc
400 1
     */
401 1
    public function checkRestrictedGrantType($client_id, $grant_type)
402 1
    {
403 1
        $clientClass = $this->getClientClass();
404 1
        $client = $clientClass::findOne($client_id);
405 1
        $notRestricted = true;
406 1
        if ($client !== null) {
407
            if (empty($client->grantTypes) === false) {
408 1
                $notRestricted = in_array($grant_type, $client->grantTypes);
409 1
            }
410 1
        }
411 1
        return $notRestricted;
412 1
    }
413 1
414 1
    /**
415 1
     * @inheritdoc
416 1
     */
417
    public function checkClientCredentials($client_id, $client_secret = null)
418
    {
419
        $clientClass = $this->getClientClass();
420
        $client = $clientClass::findOne($client_id);
421
        return ($client !== null) ? ($client->secret === $client_secret) : false;
422 1
    }
423
424 1
    /**
425
     * @inheritdoc
426 1
     */
427 1
    public function isPublicClient($client_id)
428 1
    {
429 1
        $clientClass = $this->getClientClass();
430 1
        $client = $clientClass::findOne($client_id);
431 1
        return ($client !== null) ? $client->isPublic : false;
432
    }
433
434
    /**
435
     * @inheritdoc
436
     */
437 1
    public function getJti($client_id, $subject, $audience, $expiration, $jti)
438
    {
439 1
        $jtiClass = $this->getJtiClass();
440 1
        $jtiModel = $jtiClass::findOne([
441 1
            'clientId' => $client_id,
442 1
            'subject' => $subject,
443 1
            'audience' => $audience,
444 1
            'expires' => $expiration,
445 1
            'jti' => $jti,
446 1
        ]);
447 1
        if ($jtiModel !== null) {
448 1
            $finalJti = [
449
                'issuer' => $jtiModel->clientId,
450
                'subject' => $jtiModel->subject,
451
                'audience' => $jtiModel->audience,
452
                'expires' => $jtiModel->expires,
453
                'jti' => $jtiModel->jti,
454 1
            ];
455
            $jtiModel = $finalJti;
456 1
        }
457 1
        return $jtiModel;
458 1
    }
459 1
460 1
    /**
461 1
     * @inheritdoc
462 1
     */
463 1
    public function setJti($client_id, $subject, $audience, $expiration, $jti)
464 1
    {
465 1
        $response = false;
466 1
        if ($expiration > time()) {
467 1
            $jtiModel = Yii::createObject('sweelix\oauth2\server\interfaces\JtiModelInterface');
468
            /* @var \sweelix\oauth2\server\interfaces\JtiModelInterface $jtiModel */
469
            $jtiModel->clientId = $client_id;
0 ignored issues
show
Bug introduced by
Accessing clientId on the interface sweelix\oauth2\server\interfaces\JtiModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
470
            $jtiModel->subject = $subject;
0 ignored issues
show
Bug introduced by
Accessing subject on the interface sweelix\oauth2\server\interfaces\JtiModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
471
            $jtiModel->audience = $audience;
0 ignored issues
show
Bug introduced by
Accessing audience on the interface sweelix\oauth2\server\interfaces\JtiModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
472
            $jtiModel->expires = $expiration;
0 ignored issues
show
Bug introduced by
Accessing expires on the interface sweelix\oauth2\server\interfaces\JtiModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
473 1
            $jtiModel->jti = $jti;
0 ignored issues
show
Bug introduced by
Accessing jti on the interface sweelix\oauth2\server\interfaces\JtiModelInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
474
            $response = $jtiModel->save();
475 1
        }
476 1
        return $response;
477 1
    }
478 1
479 1
    /**
480 1
     * @inheritdoc
481 1
     */
482 1
    public function getClientKey($client_id, $subject)
483 1
    {
484 1
        $jwtClass = $this->getJwtClass();
485 1
        $jwt = $jwtClass::findOne([
486 1
            'clientId' => $client_id,
487
            'subject' => $subject,
488
        ]);
489
        if ($jwt !== null) {
490
            $finalJwt = $jwt->publicKey;
491
            $jwt = $finalJwt;
492 1
        }
493
        return $jwt;
494 1
    }
495 1
496 1
    /**
497 1
     * @inheritdoc
498 1
     */
499 1
    public function getPublicKey($client_id = null)
500 1
    {
501 1
        $cypherKeyClass = $this->getCypherKeyClass();
502 1
        if ($client_id === null) {
503 1
            $client_id = $cypherKeyClass::DEFAULT_KEY;
504 1
        }
505 1
        $cypherKey = $cypherKeyClass::findOne($client_id);
506
        if ($cypherKey === null) {
507
            $cypherKey = $cypherKeyClass::findOne($cypherKeyClass::DEFAULT_KEY);
508
        }
509
        if ($cypherKey !== null) {
510
            $cypherKey = $cypherKey->publicKey;
511 2
        }
512
        return $cypherKey;
513 2
    }
514 2
515 2
    /**
516
     * @inheritdoc
517 2
     */
518 2
    public function getPrivateKey($client_id = null)
519 2
    {
520 2
        $cypherKeyClass = $this->getCypherKeyClass();
521 2
        if ($client_id === null) {
522 2
            $client_id = $cypherKeyClass::DEFAULT_KEY;
523 2
        }
524 2
        $cypherKey = $cypherKeyClass::findOne($client_id);
525 2
        if ($cypherKey === null) {
526
            $cypherKey = $cypherKeyClass::findOne($cypherKeyClass::DEFAULT_KEY);
527
        }
528
        if ($cypherKey !== null) {
529
            $cypherKey = $cypherKey->privateKey;
530
        }
531 4
        return $cypherKey;
532
    }
533 4
534 4
    /**
535 4
     * @inheritdoc
536 4
     */
537 4
    public function getEncryptionAlgorithm($client_id = null)
538 4
    {
539 4
        $cypherKeyClass = $this->getCypherKeyClass();
540 4
        if ($client_id === null) {
541 1
            $client_id = $cypherKeyClass::DEFAULT_KEY;
542
        }
543 4
        $cypherKey = $cypherKeyClass::findOne($client_id);
544 4
        if ($cypherKey === null) {
545
            $cypherKey = $cypherKeyClass::findOne($cypherKeyClass::DEFAULT_KEY);
546
        }
547
        if ($cypherKey !== null) {
548
            $cypherKey = $cypherKey->encryptionAlgorithm;
549
        }
550 1
        return $cypherKey;
551
    }
552 1
553 1
    /**
554 1
     * @inheritdoc
555 1
     */
556
    public function getRefreshToken($refresh_token)
557
    {
558
        $refreshTokenClass = $this->getRefreshTokenClass();
559
        $refreshToken = $refreshTokenClass::findOne($refresh_token);
560
        if ($refreshToken !== null) {
561
            $finalToken = [
562
                'refresh_token' => $refreshToken->id,
563 1
                'client_id' => $refreshToken->clientId,
564
                'user_id' => $refreshToken->userId,
565 1
                'expires' => $refreshToken->expiry,
566 1
                'scope' => implode(' ', $refreshToken->scopes),
567 1
            ];
568 1
            $refreshToken = $finalToken;
569 1
        }
570
        return $refreshToken;
571
    }
572
573
    /**
574
     * @inheritdoc
575 8
     */
576
    public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
577 8
    {
578 8
        $response = false;
579 8
        if ($expires > time()) {
580 8
            $refreshToken = Yii::createObject('sweelix\oauth2\server\interfaces\RefreshTokenModelInterface');
581 8
            $refreshToken->id = $refresh_token;
582 8
            $refreshToken->clientId = $client_id;
583 8
            $refreshToken->userId = $user_id;
584
            $refreshToken->expiry = $expires;
585
            if ($scope === null) {
586
                $scopes = [];
587
            } else {
588
                $scopes = explode(' ', $scope);
589 4
            }
590
            $refreshToken->scopes = $scopes;
591 4
            $response = $refreshToken->save();
592 4
        }
593 4
        return $response;
594
    }
595
596
    /**
597
     * @inheritdoc
598
     */
599 3
    public function unsetRefreshToken($refresh_token)
600
    {
601 3
        $refreshTokenClass = $this->getRefreshTokenClass();
602 3
        $refreshToken = $refreshTokenClass::findOne($refresh_token);
603
        if ($refreshToken !== null) {
604 3
            return $refreshToken->delete();
605 3
        }
606
        return true;
607 3
    }
608 3
609 3
    /**
610 3
     * @inheritdoc
611
     */
612
    public function scopeExists($scope)
613 3
    {
614 3
        $scopeClass = $this->getScopeClass();
615
        $availableScopes = $scopeClass::findAvailableScopeIds();
616
        $requestedScopes = explode(' ', $scope);
617
        $missingScopes = array_diff($requestedScopes, $availableScopes);
618
        return empty($missingScopes);
619
    }
620
621
    /**
622
     * @inheritdoc
623
     */
624
    public function getDefaultScope($client_id = null)
625
    {
626
        $scopeClass = $this->getScopeClass();
627
        $availableDefaultScopes = $scopeClass::findDefaultScopeIds($client_id);
628
        $scope = implode(' ', $availableDefaultScopes);
629
        if (empty($scope) === true) {
630
            $scope = null;
631
        }
632
        return $scope;
633
    }
634
635
    /**
636
     * @inheritdoc
637
     */
638
    public function checkUserCredentials($username, $password)
639
    {
640
        $userClass = $this->getUserClass();
641
        $user = $userClass::findByUsernameAndPassword($username, $password);
642
        return ($user !== null);
643
    }
644
645
    /**
646
     * @inheritdoc
647
     */
648
    public function getUserDetails($username)
649
    {
650
        $userClass = $this->getUserClass();
651
        $user = $userClass::findByUsername($username);
652
        /* @var \sweelix\oauth2\server\interfaces\UserModelInterface $user ) */
653
        $details = false;
654
        if ($user !== null) {
655
            $details = [
656
                'user_id' => $user->getId(),
657
            ];
658
            $restrictedScopes = $user->getRestrictedScopes();
659
            if (($restrictedScopes !== null) && (is_array($restrictedScopes) === true)) {
660
                $details['scope'] = implode(' ', $restrictedScopes);
661
            }
662
        }
663
        return $details;
664
    }
665
666
}
667