Passed
Branch master (c0ae7d)
by Rutger
02:34
created

Oauth2OidcScopeCollection::setOidcScopes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
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 4
        if (empty($identifier)) {
111
            throw new InvalidArgumentException('Scope identifier must be set.');
112
        }
113
114 4
        if ($merge && array_key_exists($identifier, $this->_oidcScopes)) {
115 1
            $this->_oidcScopes[$identifier]->addClaims($oidcScope->getClaims());
116
        } else {
117 4
            $this->_oidcScopes[$identifier] = $oidcScope;
118
        }
119
120 4
        return $this;
121
    }
122
123
    /**
124
     * @inheritDoc
125
     */
126 1
    public function removeOidcScope($scopeIdentifier)
127
    {
128 1
        unset($this->_oidcScopes[$scopeIdentifier]);
129 1
        return $this;
130
    }
131
132
    /**
133
     * @inheritDoc
134
     */
135 2
    public function hasOidcScope($scopeIdentifier)
136
    {
137 2
        return array_key_exists($scopeIdentifier, $this->getOidcScopes());
138
    }
139
140
    /**
141
     * @inheritDoc
142
     */
143 6
    public function getDefaultOidcScope($scopeIdentifier)
144
    {
145 6
        if (!in_array($scopeIdentifier, static::OPENID_CONNECT_DEFAULT_SCOPES)) {
146 1
            throw new InvalidArgumentException(
147 1
                'Invalid $scopeName "' . $scopeIdentifier . '", it must be an OpenID Connect default claims scope ('
148 1
                . implode(', ', static::OPENID_CONNECT_DEFAULT_SCOPES) . ').'
149
            );
150
        }
151
152 5
        return Yii::createObject([
153
            'class' => Oauth2OidcScopeInterface::class,
154
            'identifier' => $scopeIdentifier,
155 5
            'claims' => Oauth2OidcScopeInterface::OPENID_CONNECT_DEFAULT_SCOPE_CLAIMS[$scopeIdentifier],
156
        ]);
157
    }
158
159
    /**
160
     * @inheritDoc
161
     */
162 1
    public function getSupportedScopeAndClaimIdentifiers()
163
    {
164
        $result = [
165 1
            'scopeIdentifiers' => [],
166
            'claimIdentifiers' => [],
167
        ];
168
169 1
        foreach ($this->getOidcScopes() as $oidcScope) {
170 1
            $result['scopeIdentifiers'][] = $oidcScope->getIdentifier();
171 1
            $result['claimIdentifiers'] = array_merge($result['claimIdentifiers'], $oidcScope->getClaims());
172
        }
173 1
        $result['claimIdentifiers'] = array_keys($result['claimIdentifiers']);
174 1
        sort($result['claimIdentifiers']);
175
176 1
        return $result;
177
    }
178
179
    /**
180
     * @inheritDoc
181
     */
182 1
    public function getFilteredClaims($scopeIdentifiers)
183
    {
184 1
        $claims = [];
185 1
        foreach ($scopeIdentifiers as $scopeIdentifier) {
186 1
            $oidcScope = $this->getOidcScope($scopeIdentifier);
187 1
            if ($oidcScope) {
188 1
                $claims = array_merge($claims, $oidcScope->getClaims());
189
            }
190
        }
191
192 1
        ksort($claims);
193
194 1
        return $claims;
195
    }
196
}
197