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

Oauth2ScopeRepository::finalizeScopes()   C

Complexity

Conditions 13
Paths 44

Size

Total Lines 83
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 48
CRAP Score 13.0108

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 49
c 1
b 0
f 0
dl 0
loc 83
ccs 48
cts 50
cp 0.96
rs 6.6166
cc 13
nc 44
nop 4
crap 13.0108

How to fix   Long Method    Complexity   

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\repositories;
4
5
use League\OAuth2\Server\Entities\ClientEntityInterface;
6
use rhertogh\Yii2Oauth2Server\components\repositories\base\Oauth2BaseRepository;
7
use rhertogh\Yii2Oauth2Server\components\repositories\traits\Oauth2RepositoryIdentifierTrait;
8
use rhertogh\Yii2Oauth2Server\exceptions\Oauth2ServerException;
9
use rhertogh\Yii2Oauth2Server\helpers\DiHelper;
10
use rhertogh\Yii2Oauth2Server\interfaces\components\repositories\Oauth2ScopeRepositoryInterface;
11
use rhertogh\Yii2Oauth2Server\interfaces\models\Oauth2ClientInterface;
12
use rhertogh\Yii2Oauth2Server\interfaces\models\Oauth2ScopeInterface;
13
use rhertogh\Yii2Oauth2Server\models\Oauth2Scope;
14
use rhertogh\Yii2Oauth2Server\Oauth2Module;
15
use yii\base\InvalidArgumentException;
16
use yii\base\InvalidConfigException;
17
18
class Oauth2ScopeRepository extends Oauth2BaseRepository implements Oauth2ScopeRepositoryInterface
19
{
20
    use Oauth2RepositoryIdentifierTrait;
21
22
    /**
23
     * @inheritDoc
24
     * @return class-string<Oauth2ScopeInterface>
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Oauth2ScopeInterface> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Oauth2ScopeInterface>.
Loading history...
25
     */
26 4
    public function getModelClass()
27
    {
28 4
        return Oauth2ScopeInterface::class;
29
    }
30
31
    /**
32
     * @inheritDoc
33
     * @throws InvalidConfigException
34
     */
35 4
    public function getScopeEntityByIdentifier($identifier)
36
    {
37 4
        return $this->findModelByIdentifier($identifier);
38
    }
39
40
    /**
41
     * @inheritDoc
42
     */
43 14
    public function finalizeScopes(
44
        array $scopes,
45
        $grantType,
46
        ClientEntityInterface $clientEntity,
47
        $userIdentifier = null
48
    ) {
49 14
        if (!($clientEntity instanceof Oauth2ClientInterface)) {
50 1
            throw new InvalidArgumentException(
51 1
                get_class($clientEntity) . ' must implement ' . Oauth2ClientInterface::class
52 1
            );
53
        } else {
54
            /** @var Oauth2ClientInterface $client */
55 13
            $client = $clientEntity;
56
        }
57
58
        // Only allow scopes without user if grant type is 'client_credentials'.
59 13
        if (empty($userIdentifier)) {
60 1
            if ($grantType === Oauth2Module::GRANT_TYPE_IDENTIFIER_CLIENT_CREDENTIALS) {
61
                $userIdentifier = $client->getClientCredentialsGrantUserId();
62
            } else {
63 1
                throw new InvalidArgumentException(
64 1
                    '$userIdentifier is required when $grantType is not "client_credentials".'
65 1
                );
66
            }
67
        }
68
69 12
        $requestedScopeIdentifiers = array_map(fn(Oauth2ScopeInterface $scope) => $scope->getIdentifier(), $scopes);
70
71
        // Validate requested scopes if they haven't been checked before (based on the grant type)
0 ignored issues
show
Coding Style introduced by
Inline comments must end in full-stops, exclamation marks, or question marks
Loading history...
72 12
        if (!in_array($grantType, [
0 ignored issues
show
Coding Style introduced by
The first expression of a multi-line control structure must be on the line after the opening parenthesis
Loading history...
73 12
            Oauth2Module::GRANT_TYPE_IDENTIFIER_AUTH_CODE,
74 12
            Oauth2Module::GRANT_TYPE_IDENTIFIER_IMPLICIT,
75 12
            Oauth2Module::GRANT_TYPE_IDENTIFIER_REFRESH_TOKEN,
76 12
        ])) {
0 ignored issues
show
Coding Style introduced by
Each line in a multi-line control structure must be indented at least once; expected at least 12 spaces, but found 8
Loading history...
Coding Style introduced by
The closing parenthesis of a multi-line control structure must be on the line after the last expression
Loading history...
77 6
            if (!$client->validateAuthRequestScopes($requestedScopeIdentifiers, $unauthorizedScopes)) {
78 6
                throw Oauth2ServerException::scopeNotAllowedForClient(array_shift($unauthorizedScopes));
79
            }
80
        }
81
82 6
        $clientAllowedScopes = $client->getAllowedScopes($requestedScopeIdentifiers);
83
84
        /** @var class-string<Oauth2ScopeInterface> $scopeClass */
85 6
        $scopeClass = DiHelper::getValidatedClassName(Oauth2ScopeInterface::class);
86
87 6
        if ($userIdentifier) {
88 6
            $clientAllowedScopeIds = array_map(fn($scope) => $scope->getPrimaryKey(), $clientAllowedScopes);
89
90 6
            $approvedScopes = $scopeClass::find()
91 6
                ->alias('scope')
92 6
                ->innerJoinWith('userClientScopes user_client_scope', false)
93 6
                ->andWhere([
94 6
                    'scope.id' => $clientAllowedScopeIds,
95 6
                    'user_client_scope.user_id' => $userIdentifier,
96 6
                    'user_client_scope.client_id' => $client->getPrimaryKey(),
97 6
                    'user_client_scope.enabled' => 1,
98 6
                ])
99 6
                ->orderBy('id')
100 6
                ->indexBy('id')
101 6
                ->all();
102
        } else {
103
            $approvedScopes = [];
104
        }
105
106 6
        foreach ($clientAllowedScopes as $clientAllowedScope) {
107 6
            $clientScope = $clientAllowedScope->getClientScope($client->getPrimaryKey());
108 6
            $appliedByDefault = ($clientScope ? $clientScope->getAppliedByDefault() : null)
109 6
                ?? $clientAllowedScope->getAppliedByDefault();
110 6
            $scopeId = $clientAllowedScope->getPrimaryKey();
111
            if (
112 6
                !array_key_exists($scopeId, $approvedScopes)
113
                && (
114 6
                    $appliedByDefault === Oauth2ScopeInterface::APPLIED_BY_DEFAULT_AUTOMATICALLY
115 6
                    || (
116 6
                        $appliedByDefault === Oauth2ScopeInterface::APPLIED_BY_DEFAULT_IF_REQUESTED
117 6
                        && in_array($clientAllowedScope->getIdentifier(), $requestedScopeIdentifiers)
118 6
                    )
119
                )
120
            ) {
121 6
                $approvedScopes[$scopeId] = $clientAllowedScope;
122
            }
123
        }
124
125 6
        return array_values($approvedScopes);
126
    }
127
}
128