Passed
Pull Request — master (#1316)
by
unknown
30:49
created

ClaimExtractor::getClaimSets()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace League\OAuth2\Server;
6
7
use InvalidArgumentException;
8
use League\OAuth2\Server\Entities\ClaimSetEntry;
9
use League\OAuth2\Server\Entities\ClaimSetEntryInterface;
10
use League\OAuth2\Server\Entities\ClaimSetInterface;
11
use League\OAuth2\Server\Entities\ScopeEntityInterface;
12
13
use function array_filter;
14
use function array_intersect;
15
use function array_keys;
16
use function array_merge;
17
use function in_array;
18
use function sprintf;
19
20
/**
21
 * ClaimExtractor
22
 *
23
 * @link https://github.com/steverhoades/oauth2-openid-connect-server
24
 *
25
 * @author Steve Rhoades <[email protected]>
26
 * @author Marc Riemer <[email protected]>
27
 */
28
class ClaimExtractor implements ClaimExtractorInterface
29
{
30
    /**
31
     * claimSets
32
     *
33
     * @var ClaimSetEntryInterface[]
34
     */
35
    protected array $claimSets = [];
36
37
    /**
38
     * Protected claims
39
     *
40
     * @var string[]
41
     */
42
    protected array $protectedClaims = ['profile', 'email', 'address', 'phone'];
43
44
    /**
45
     * ClaimExtractor constructor
46
     *
47
     * @param ClaimSetEntryInterface[] $claimSets
48
     */
49
    public function __construct(array $claimSets = [])
50
    {
51
        $this->claimSets = self::getDefaultClaimSetEnties();
52
        foreach ($claimSets as $claimSet) {
53
            $this->addClaimSet($claimSet);
54
        }
55
    }
56
57
    /**
58
     *
59
     * @return $this
60
     *
61
     * @throws \InvalidArgumentException
62
     */
63
    public function addClaimSet(ClaimSetEntryInterface $claimSetEntry): ClaimExtractor
64
    {
65
        if (in_array($claimSetEntry->getScope(), $this->protectedClaims) && !$this->getClaimSet($claimSetEntry->getScope())) {
66
            throw new InvalidArgumentException(
67
                sprintf('%s is a protected scope and is pre-defined by the OpenID Connect specification.', $claimSetEntry->getScope())
68
            );
69
        }
70
71
        $this->claimSets[] = $claimSetEntry;
72
73
        return $this;
74
    }
75
76
    public function getClaimSet(string $scope): ?ClaimSetEntryInterface
77
    {
78
        foreach ($this->claimSets as $set) {
79
            if ($set->getScope() === $scope) {
80
                return $set;
81
            }
82
        }
83
84
        return null;
85
    }
86
87
    /**
88
     * Get claimSets
89
     *
90
     * @return ClaimSetInterface[]
91
     */
92
    public function getClaimSets(): array
93
    {
94
        return $this->claimSets;
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100
    public function extract(array $scopes, array $claims): array
101
    {
102
        $claimData  = [];
103
        $keys = array_keys($claims);
104
105
        foreach ($scopes as $scope) {
106
            $scopeName = ($scope instanceof ScopeEntityInterface) ? $scope->getIdentifier() : $scope;
107
108
            $claimSet = $this->getClaimSet($scopeName);
109
            if (null === $claimSet) {
110
                continue;
111
            }
112
113
            $intersected = array_intersect($claimSet->getClaims(), $keys);
114
115
            if (empty($intersected)) {
116
                continue;
117
            }
118
119
            $data = array_filter(
120
                $claims,
121
                function ($key) use ($intersected) {
122
                    return in_array($key, $intersected);
123
                },
124
                ARRAY_FILTER_USE_KEY
125
            );
126
127
            $claimData = array_merge($claimData, $data);
128
        }
129
130
        return $claimData;
131
    }
132
133
    /**
134
     * Create a array default openID connect claims
135
     *
136
     * @see http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
137
     *
138
     * @return ClaimSetEntry[]
139
     */
140
    public static function getDefaultClaimSetEnties(): array
141
    {
142
        return [
143
            new ClaimSetEntry('profile', [
144
                'name',
145
                'family_name',
146
                'given_name',
147
                'middle_name',
148
                'nickname',
149
                'preferred_username',
150
                'profile',
151
                'picture',
152
                'website',
153
                'gender',
154
                'birthdate',
155
                'zoneinfo',
156
                'locale',
157
                'updated_at',
158
            ]),
159
            new ClaimSetEntry('email', [
160
                'email',
161
                'email_verified',
162
            ]),
163
            new ClaimSetEntry('address', [
164
                'address',
165
            ]),
166
            new ClaimSetEntry('phone', [
167
                'phone_number',
168
                'phone_number_verified',
169
            ]),
170
            new ClaimSetEntry('openid', [
171
                'nonce',
172
                'auth_time',
173
                'acr',
174
                'amr',
175
                'azp',
176
            ]),
177
        ];
178
    }
179
}
180