Passed
Push — master ( b8bdbf...0c1875 )
by Rutger
15:13
created

Oauth2ScopeRepository   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Test Coverage

Coverage 96.23%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 14
eloc 53
c 1
b 0
f 0
dl 0
loc 110
ccs 51
cts 53
cp 0.9623
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getModelClass() 0 3 1
A getScopeEntityByIdentifier() 0 3 1
C finalizeScopes() 0 83 12
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\Oauth2ModelRepositoryTrait;
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\Oauth2Module;
14
use yii\base\InvalidArgumentException;
15
use yii\base\InvalidConfigException;
16
17
class Oauth2ScopeRepository extends Oauth2BaseRepository implements Oauth2ScopeRepositoryInterface
18
{
19
    use Oauth2ModelRepositoryTrait;
20
21
    /**
22
     * @inheritDoc
23
     * @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...
24
     */
25 4
    public function getModelClass()
26
    {
27 4
        return Oauth2ScopeInterface::class;
28
    }
29
30
    /**
31
     * @inheritDoc
32
     * @throws InvalidConfigException
33
     */
34 4
    public function getScopeEntityByIdentifier($identifier)
35
    {
36 4
        return $this->findModelByIdentifier($identifier);
37
    }
38
39
    /**
40
     * @inheritDoc
41
     * @throws Oauth2ServerException
42
     * @throws InvalidConfigException
43
     */
44 14
    public function finalizeScopes(
45
        array $scopes,
46
        $grantType,
47
        ClientEntityInterface $clientEntity,
48
        $userIdentifier = null
49
    ) {
50 14
        if (!($clientEntity instanceof Oauth2ClientInterface)) {
51 1
            throw new InvalidArgumentException(
52 1
                get_class($clientEntity) . ' must implement ' . Oauth2ClientInterface::class
53 1
            );
54
        } else {
55
            /** @var Oauth2ClientInterface $client */
56 13
            $client = $clientEntity;
57
        }
58
59
        // Only allow scopes without user if grant type is 'client_credentials'.
60 13
        if (empty($userIdentifier)) {
61 1
            if ($grantType === Oauth2Module::GRANT_TYPE_IDENTIFIER_CLIENT_CREDENTIALS) {
62
                $userIdentifier = $client->getClientCredentialsGrantUserId();
63
            } else {
64 1
                throw new InvalidArgumentException(
65 1
                    '$userIdentifier is required when $grantType is not "client_credentials".'
66 1
                );
67
            }
68
        }
69
70 12
        $requestedScopeIdentifiers = array_map(fn(Oauth2ScopeInterface $scope) => $scope->getIdentifier(), $scopes);
71
72
        // Validate requested scopes if they haven't been checked before (based on the grant type).
73
        if (
74 12
            !in_array($grantType, [
75 12
                Oauth2Module::GRANT_TYPE_IDENTIFIER_AUTH_CODE,
76 12
                Oauth2Module::GRANT_TYPE_IDENTIFIER_IMPLICIT,
77 12
                Oauth2Module::GRANT_TYPE_IDENTIFIER_REFRESH_TOKEN,
78 12
            ])
79
        ) {
80 6
            $this->_module->validateAuthRequestScopes($client, $requestedScopeIdentifiers);
0 ignored issues
show
Bug introduced by
The method validateAuthRequestScopes() does not exist on null. ( Ignorable by Annotation )

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

80
            $this->_module->/** @scrutinizer ignore-call */ 
81
                            validateAuthRequestScopes($client, $requestedScopeIdentifiers);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
81
        }
82
83 6
        $clientAllowedScopes = $client->getAllowedScopes($requestedScopeIdentifiers);
84
85
        /** @var class-string<Oauth2ScopeInterface> $scopeClass */
86 6
        $scopeClass = DiHelper::getValidatedClassName(Oauth2ScopeInterface::class);
87
88 6
        if ($userIdentifier) {
89 6
            $clientAllowedScopeIds = array_map(fn($scope) => $scope->getPrimaryKey(), $clientAllowedScopes);
90
91 6
            $approvedScopes = $scopeClass::find()
92 6
                ->alias('scope')
93 6
                ->innerJoinWith('userClientScopes user_client_scope', false)
94 6
                ->andWhere([
95 6
                    'scope.id' => $clientAllowedScopeIds,
96 6
                    'user_client_scope.user_id' => $userIdentifier,
97 6
                    'user_client_scope.client_id' => $client->getPrimaryKey(),
98 6
                    'user_client_scope.enabled' => 1,
99 6
                ])
100 6
                ->orderBy('id')
101 6
                ->indexBy('id')
102 6
                ->all();
103
        } else {
104
            $approvedScopes = [];
105
        }
106
107 6
        foreach ($clientAllowedScopes as $clientAllowedScope) {
108 6
            $clientScope = $clientAllowedScope->getClientScope($client->getPrimaryKey());
109 6
            $appliedByDefault = ($clientScope ? $clientScope->getAppliedByDefault() : null)
110 6
                ?? $clientAllowedScope->getAppliedByDefault();
111 6
            $scopeId = $clientAllowedScope->getPrimaryKey();
112
            if (
113 6
                !array_key_exists($scopeId, $approvedScopes)
114
                && (
115 6
                    $appliedByDefault === Oauth2ScopeInterface::APPLIED_BY_DEFAULT_AUTOMATICALLY
116 6
                    || (
117 6
                        $appliedByDefault === Oauth2ScopeInterface::APPLIED_BY_DEFAULT_IF_REQUESTED
118 6
                        && in_array($clientAllowedScope->getIdentifier(), $requestedScopeIdentifiers)
119 6
                    )
120
                )
121
            ) {
122 6
                $approvedScopes[$scopeId] = $clientAllowedScope;
123
            }
124
        }
125
126 6
        return array_values($approvedScopes);
127
    }
128
}
129