Passed
Push — master ( e9591a...c0a685 )
by Rutger
13:20
created

respondToAccessTokenRequest()   B

Complexity

Conditions 9
Paths 8

Size

Total Lines 58
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 9.4078

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 29
c 1
b 0
f 0
dl 0
loc 58
ccs 29
cts 35
cp 0.8286
rs 8.0555
cc 9
nc 8
nop 3
crap 9.4078

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace rhertogh\Yii2Oauth2Server\components\server\grants;
4
5
use DateInterval;
6
use League\OAuth2\Server\Exception\OAuthServerException;
7
use League\OAuth2\Server\Grant\RefreshTokenGrant;
8
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
9
use Psr\Http\Message\ServerRequestInterface;
10
use rhertogh\Yii2Oauth2Server\components\server\grants\traits\Oauth2GrantTrait;
11
use rhertogh\Yii2Oauth2Server\exceptions\Oauth2ServerException;
12
use rhertogh\Yii2Oauth2Server\interfaces\components\openidconnect\scope\Oauth2OidcScopeInterface;
13
use rhertogh\Yii2Oauth2Server\interfaces\components\server\grants\Oauth2RefreshTokenGrantInterface;
14
use rhertogh\Yii2Oauth2Server\interfaces\models\external\user\Oauth2OidcUserSessionStatusInterface;
15
use rhertogh\Yii2Oauth2Server\interfaces\models\Oauth2ClientInterface;
16
use rhertogh\Yii2Oauth2Server\Oauth2Module;
17
use Yii;
18
use yii\base\InvalidConfigException;
19
use yii\web\NotFoundHttpException;
20
21
class Oauth2RefreshTokenGrant extends RefreshTokenGrant implements Oauth2RefreshTokenGrantInterface
22
{
23
    use Oauth2GrantTrait;
24
25
    /** @var Oauth2Module */
26
    public $module;
27
28
    /**
29
     * @throws InvalidConfigException
30
     * @throws Oauth2ServerException
31
     * @throws NotFoundHttpException
32
     * @throws OAuthServerException
33
     */
34 8
    public function respondToAccessTokenRequest(
35
        ServerRequestInterface $request,
36
        ResponseTypeInterface $responseType,
37
        DateInterval $accessTokenTTL
38
    ) {
39
        /** @var Oauth2ClientInterface $client */
40 8
        $client = $this->validateClient($request);
41 8
        $oldRefreshToken = $this->validateOldRefreshToken($request, $client->getIdentifier());
42
43 8
        $user = $this->module->getUserRepository()->getUserEntityByIdentifier($oldRefreshToken['user_id']);
44 8
        if (empty($user)) {
45 1
            throw new NotFoundHttpException(
46 1
                Yii::t('oauth2', 'Unable to find user with id "' . $oldRefreshToken['user_id'] . '".')
47 1
            );
48
        }
49
50 7
        if ($user->isOauth2ClientAllowed($client, $this->getIdentifier()) !== true) {
51
            throw Oauth2ServerException::accessDenied(
52
                Yii::t('oauth2', 'User {user_id} is not allowed to use client {client_identifier}.', [
53
                    'user_id' => $user->getId(),
0 ignored issues
show
Bug introduced by
The method getId() does not exist on rhertogh\Yii2Oauth2Serve...ser\Oauth2UserInterface. It seems like you code against a sub-type of said class. However, the method does not exist in rhertogh\Yii2Oauth2Serve...Oauth2OidcUserInterface or rhertogh\Yii2Oauth2Serve...swordGrantUserInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

53
                    'user_id' => $user->/** @scrutinizer ignore-call */ getId(),
Loading history...
54
                    'client_identifier' => $client->getIdentifier(),
55
                ])
56
            );
57
        }
58
59 7
        if ($this->module->enableOpenIdConnect) {
60 6
            $scopes = $oldRefreshToken['scopes'] ?? [];
61
62
            if (
63 6
                in_array(Oauth2OidcScopeInterface::OPENID_CONNECT_SCOPE_OPENID, $scopes)
64 6
                && !in_array(Oauth2OidcScopeInterface::OPENID_CONNECT_SCOPE_OFFLINE_ACCESS, $scopes)
65
            ) {
66
                // Refresh tokens are not issued when `openIdConnectIssueRefreshTokenWithoutOfflineAccessScope`
67
                // is disabled, but let's ensure setting hasn't changed.
68 4
                if (!$this->module->openIdConnectIssueRefreshTokenWithoutOfflineAccessScope) {
69 1
                    throw Oauth2ServerException::accessDenied(
70 1
                        'The refresh token grant type is unavailable in OpenID Connect context when'
71 1
                            . ' `openIdConnectIssueRefreshTokenWithoutOfflineAccessScope` is disabled.'
72 1
                    );
73
                }
74
75 3
                if (!($user instanceof Oauth2OidcUserSessionStatusInterface)) {
76 1
                    throw new InvalidConfigException(
77 1
                        'In order to support OpenId Connect Refresh Tokens without offline_access scope '
78 1
                            . get_class($user) . ' must implement ' . Oauth2OidcUserSessionStatusInterface::class
79 1
                    );
80
                }
81
82 2
                if (!$user->hasActiveSession()) {
83 1
                    throw Oauth2ServerException::accessDenied(
84 1
                        'The refresh token grant type is unavailable in OpenID Connect context when the user is'
85 1
                        . ' offline and the authorized scope does not include "offline_access".'
86 1
                    );
87
                }
88
            }
89
        }
90
91 4
        return parent::respondToAccessTokenRequest($request, $responseType, $accessTokenTTL);
92
    }
93
}
94