Passed
Branch master (9b4352)
by Rutger
13:03
created

Oauth2OidcScopeCollection::addOidcScopes()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 17
c 1
b 0
f 0
dl 0
loc 27
ccs 14
cts 14
cp 1
rs 9.0777
cc 6
nc 6
nop 2
crap 6
1
<?php
2
3
namespace rhertogh\Yii2Oauth2Server\components\openidconnect\scopes;
4
5
use rhertogh\Yii2Oauth2Server\interfaces\components\openidconnect\scope\Oauth2OidcScopeCollectionInterface;
6
use rhertogh\Yii2Oauth2Server\interfaces\components\openidconnect\scope\Oauth2OidcScopeInterface;
7
use Yii;
8
use yii\base\BaseObject;
9
use yii\base\InvalidArgumentException;
10
use yii\helpers\ArrayHelper;
11
12
class Oauth2OidcScopeCollection extends BaseObject implements Oauth2OidcScopeCollectionInterface
13
{
14
    /**
15
     * @var Oauth2OidcScopeInterface[]
16
     */
17
    protected $_oidcScopes = [];
18
19
    /**
20
     * @inheritDoc
21
     */
22 4
    public function getOidcScopes()
23
    {
24 4
        if (!array_key_exists(Oauth2OidcScopeInterface::OPENID_CONNECT_SCOPE_OPENID, $this->_oidcScopes)) {
25 4
            $this->_oidcScopes = array_merge( // ensure openid scope is always the first element.
26
                [
27
                    Oauth2OidcScopeInterface::OPENID_CONNECT_SCOPE_OPENID =>
28 4
                        $this->getDefaultOidcScope(Oauth2OidcScopeInterface::OPENID_CONNECT_SCOPE_OPENID)
29
                ],
30 4
                $this->_oidcScopes
31
            );
32
        }
33 4
        return $this->_oidcScopes;
34
    }
35
36
    /**
37
     * @inheritDoc
38
     */
39 3
    public function setOidcScopes($oidcScopes)
40
    {
41 3
        $this->clearOidcScopes();
42 3
        return $this->addOidcScopes($oidcScopes);
43
    }
44
45
    /**
46
     * @inheritDoc
47
     */
48 4
    public function addOidcScopes($oidcScopes, $merge = true)
49
    {
50 4
        foreach ($oidcScopes as $scopeIdentifier => $scopeConfig) {
51 4
            if ($scopeConfig instanceof Oauth2OidcScopeInterface) {
52 1
                $this->addOidcScope($scopeConfig, $merge);
53 4
            } elseif (is_string($scopeConfig)) {
54 1
                $this->addOidcScope($scopeConfig, $merge);
55 4
            } elseif (is_array($scopeConfig)) {
56 3
                if (is_numeric($scopeIdentifier)) {
57 1
                    $this->addOidcScope($scopeConfig, $merge);
58
                } else {
59 3
                    $this->addOidcScope(
60
                        [
61 3
                            'identifier' => $scopeIdentifier,
62
                            'claims' => $scopeConfig,
63
                        ],
64
                        $merge
65
                    );
66
                }
67
            } else {
68 1
                throw new InvalidArgumentException(
69 1
                    'Elements should be of type array, string or ' . Oauth2OidcScopeInterface::class
70
                );
71
            }
72
        }
73
74 3
        return $this;
75
    }
76
77
    /**
78
     * @inheritDoc
79
     */
80 3
    public function clearOidcScopes()
81
    {
82 3
        $this->_oidcScopes = [];
83 3
        return $this;
84
    }
85
86
    /**
87
     * @inheritDoc
88
     */
89 3
    public function getOidcScope($scopeIdentifier)
90
    {
91 3
        return $this->getOidcScopes()[$scopeIdentifier] ?? null;
92
    }
93
94
    /**
95
     * @inheritDoc
96
     */
97 4
    public function addOidcScope($oidcScope, $merge = true)
98
    {
99 4
        if (is_string($oidcScope)) {
100 2
            $oidcScope = $this->getDefaultOidcScope($oidcScope);
101 4
        } elseif (is_array($oidcScope)) {
102 4
            $oidcScope = Yii::createObject(ArrayHelper::merge(
103
                [
104 4
                    'class' => Oauth2OidcScopeInterface::class,
105
                ],
106
                $oidcScope
107
            ));
108
        }
109 4
        $identifier = $oidcScope->getIdentifier();
110
111 4
        if ($merge && array_key_exists($identifier, $this->_oidcScopes)) {
112 1
            $this->_oidcScopes[$identifier]->addClaims($oidcScope->getClaims());
113
        } else {
114 4
            $this->_oidcScopes[$identifier] = $oidcScope;
115
        }
116
117 4
        return $this;
118
    }
119
120
    /**
121
     * @inheritDoc
122
     */
123 1
    public function removeOidcScope($scopeIdentifier)
124
    {
125 1
        unset($this->_oidcScopes[$scopeIdentifier]);
126 1
        return $this;
127
    }
128
129
    /**
130
     * @inheritDoc
131
     */
132 2
    public function hasOidcScope($scopeIdentifier)
133
    {
134 2
        return array_key_exists($scopeIdentifier, $this->getOidcScopes());
135
    }
136
137
    /**
138
     * @inheritDoc
139
     */
140 6
    public function getDefaultOidcScope($scopeIdentifier)
141
    {
142 6
        if (!in_array($scopeIdentifier, static::OPENID_CONNECT_DEFAULT_SCOPES)) {
143 1
            throw new InvalidArgumentException(
144 1
                'Invalid $scopeName "' . $scopeIdentifier . '", it must be an OpenID Connect default claims scope ('
145 1
                . implode(', ', static::OPENID_CONNECT_DEFAULT_SCOPES) . ').'
146
            );
147
        }
148
149 5
        return Yii::createObject([
150
            'class' => Oauth2OidcScopeInterface::class,
151
            'identifier' => $scopeIdentifier,
152 5
            'claims' => Oauth2OidcScopeInterface::OPENID_CONNECT_DEFAULT_SCOPE_CLAIMS[$scopeIdentifier],
153
        ]);
154
    }
155
156
    /**
157
     * @inheritDoc
158
     */
159 1
    public function getSupportedScopeAndClaimIdentifiers()
160
    {
161
        $result = [
162 1
            'scopeIdentifiers' => [],
163
            'claimIdentifiers' => [],
164
        ];
165
166 1
        foreach ($this->getOidcScopes() as $oidcScope) {
167 1
            $result['scopeIdentifiers'][] = $oidcScope->getIdentifier();
168 1
            $result['claimIdentifiers'] = array_merge($result['claimIdentifiers'], $oidcScope->getClaims());
169
        }
170 1
        $result['claimIdentifiers'] = array_keys($result['claimIdentifiers']);
171 1
        sort($result['claimIdentifiers']);
172
173 1
        return $result;
174
    }
175
176
    /**
177
     * @inheritDoc
178
     */
179 1
    public function getFilteredClaims($scopeIdentifiers)
180
    {
181 1
        $claims = [];
182 1
        foreach ($scopeIdentifiers as $scopeIdentifier) {
183 1
            $oidcScope = $this->getOidcScope($scopeIdentifier);
184 1
            if ($oidcScope) {
185 1
                $claims = array_merge($claims, $oidcScope->getClaims());
186
            }
187
        }
188
189 1
        ksort($claims);
190
191 1
        return $claims;
192
    }
193
}
194