Passed
Pull Request — master (#1316)
by
unknown
32:56
created

ClaimExtractor::getDefaultClaimSetEnties()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 36
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 30
nc 1
nop 0
dl 0
loc 36
rs 9.44
c 1
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
     * claimSetEntries
32
     *
33
     * @var ClaimSetEntryInterface[]
34
     */
35
    protected array $claimSetEntries = [];
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 array<int, ClaimSetEntryInterface> $claimSetEntries
48
     */
49
    public function __construct(array $claimSetEntries = [])
50
    {
51
        $this->claimSetEntries = self::getDefaultClaimSetEnties();
52
        foreach ($claimSetEntries as $claimSetEntry) {
53
            $this->addClaimSetEntry($claimSetEntry);
54
        }
55
    }
56
57
    /**
58
     * @return $this
59
     *
60
     * @throws \InvalidArgumentException
61
     */
62
    public function addClaimSetEntry(ClaimSetEntryInterface $claimSetEntry): ClaimExtractor
63
    {
64
        if (in_array($claimSetEntry->getScope(), $this->protectedClaims) && !$this->getClaimSetEntry($claimSetEntry->getScope())) {
65
            throw new InvalidArgumentException(
66
                sprintf('%s is a protected scope and is pre-defined by the OpenID Connect specification.', $claimSetEntry->getScope())
67
            );
68
        }
69
70
        $this->claimSetEntries[] = $claimSetEntry;
71
72
        return $this;
73
    }
74
75
    public function getClaimSetEntry(string $scope): ?ClaimSetEntryInterface
76
    {
77
        foreach ($this->claimSetEntries as $entry) {
78
            if ($entry->getScope() === $scope) {
79
                return $entry;
80
            }
81
        }
82
83
        return null;
84
    }
85
86
    /**
87
     * Get claimSetEntries
88
     *
89
     * @return array<ClaimSetInterface>
90
     */
91
    public function getClaimSetEntries(): array
92
    {
93
        return $this->claimSetEntries;
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99
    public function extract(array $scopes, array $claims): array
100
    {
101
        $claimData  = [];
102
        $keys = array_keys($claims);
103
104
        foreach ($scopes as $scope) {
105
            $scopeName = ($scope instanceof ScopeEntityInterface) ? $scope->getIdentifier() : $scope;
106
107
            $claimSet = $this->getClaimSetEntry($scopeName);
108
            if (null === $claimSet) {
109
                continue;
110
            }
111
112
            $intersected = array_intersect($claimSet->getClaims(), $keys);
113
114
            if (empty($intersected)) {
115
                continue;
116
            }
117
118
            $data = array_filter(
119
                $claims,
120
                function ($key) use ($intersected) {
121
                    return in_array($key, $intersected);
122
                },
123
                ARRAY_FILTER_USE_KEY
124
            );
125
126
            $claimData = array_merge($claimData, $data);
127
        }
128
129
        return $claimData;
130
    }
131
132
    /**
133
     * Create a array default openID connect claims
134
     *
135
     * @see http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
136
     *
137
     * @return ClaimSetEntry[]
138
     */
139
    public static function getDefaultClaimSetEnties(): array
140
    {
141
        return [
142
            new ClaimSetEntry('profile', [
143
                'name',
144
                'family_name',
145
                'given_name',
146
                'middle_name',
147
                'nickname',
148
                'preferred_username',
149
                'profile',
150
                'picture',
151
                'website',
152
                'gender',
153
                'birthdate',
154
                'zoneinfo',
155
                'locale',
156
                'updated_at',
157
            ]),
158
            new ClaimSetEntry('email', [
159
                'email',
160
                'email_verified',
161
            ]),
162
            new ClaimSetEntry('address', [
163
                'address',
164
            ]),
165
            new ClaimSetEntry('phone', [
166
                'phone_number',
167
                'phone_number_verified',
168
            ]),
169
            new ClaimSetEntry('openid', [
170
                'nonce',
171
                'auth_time',
172
                'acr',
173
                'amr',
174
                'azp',
175
            ]),
176
        ];
177
    }
178
}
179