ClaimExtractor   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 0 Features 2
Metric Value
wmc 13
eloc 58
c 4
b 0
f 2
dl 0
loc 134
ccs 69
cts 69
cp 1
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A hasClaimSet() 0 3 1
A getClaimSet() 0 7 2
A addClaimSet() 0 13 3
A __construct() 0 42 2
A extract() 0 30 5
1
<?php
2
/**
3
 * @author Steve Rhoades <[email protected]>
4
 * @license http://opensource.org/licenses/MIT MIT
5
 */
6
namespace OpenIDConnectServer;
7
8
use OpenIDConnectServer\Entities\ClaimSetEntity;
9
use OpenIDConnectServer\Entities\ClaimSetEntityInterface;
10
use OpenIDConnectServer\Exception\InvalidArgumentException;
11
use League\OAuth2\Server\Entities\ScopeEntityInterface;
12
13
class ClaimExtractor
14
{
15
    protected $claimSets;
16
17
    protected $protectedClaims = ['profile', 'email', 'address', 'phone'];
18
19
    /**
20
     * ClaimExtractor constructor.
21
     * @param ClaimSetEntity[] $claimSets
22
     */
23 10
    public function __construct($claimSets = [])
24
    {
25
        // Add Default OpenID Connect Claims
26
        // @see http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
27 10
        $this->addClaimSet(
28 10
            new ClaimSetEntity('profile', [
29 10
                'name',
30 10
                'family_name',
31 10
                'given_name',
32 10
                'middle_name',
33 10
                'nickname',
34 10
                'preferred_username',
35 10
                'profile',
36 10
                'picture',
37 10
                'website',
38 10
                'gender',
39 10
                'birthdate',
40 10
                'zoneinfo',
41 10
                'locale',
42
                'updated_at'
43 10
            ])
44 10
        );
45 10
        $this->addClaimSet(
46 10
            new ClaimSetEntity('email', [
47 10
                'email',
48
                'email_verified'
49 10
            ])
50 10
        );
51 10
        $this->addClaimSet(
52 10
            new ClaimSetEntity('address', [
53
                'address'
54 10
            ])
55 10
        );
56 10
        $this->addClaimSet(
57 10
            new ClaimSetEntity('phone', [
58 10
                'phone_number',
59
                'phone_number_verified'
60 10
            ])
61 10
        );
62
63 10
        foreach ($claimSets as $claimSet) {
64 2
            $this->addClaimSet($claimSet);
65 9
        }
66 9
    }
67
68
    /**
69
     * @param ClaimSetEntityInterface $claimSet
70
     * @return $this
71
     * @throws InvalidArgumentException
72
     */
73 10
    public function addClaimSet(ClaimSetEntityInterface $claimSet)
74
    {
75 10
        $scope = $claimSet->getScope();
76
77 10
        if (in_array($scope, $this->protectedClaims) && !empty($this->claimSets[$scope])) {
78 1
            throw new InvalidArgumentException(
79 1
                sprintf("%s is a protected scope and is pre-defined by the OpenID Connect specification.", $scope)
80 1
            );
81
        }
82
83 10
        $this->claimSets[$scope] = $claimSet;
84
85 10
        return $this;
86
    }
87
88
    /**
89
     * @param string $scope
90
     * @return ClaimSetEntity|null
91
     */
92 5
    public function getClaimSet($scope)
93
    {
94 5
        if (!$this->hasClaimSet($scope)) {
95 4
            return null;
96
        }
97
98 4
        return $this->claimSets[$scope];
99
    }
100
101
    /**
102
     * @param string $scope
103
     * @return bool
104
     */
105 6
    public function hasClaimSet($scope)
106
    {
107 6
        return array_key_exists($scope, $this->claimSets);
108
    }
109
110
    /**
111
     * For given scopes and aggregated claims get all claims that have been configured on the extractor.
112
     *
113
     * @param array $scopes
114
     * @param array $claims
115
     * @return array
116
     */
117 4
    public function extract(array $scopes, array $claims)
118
    {
119 4
        $claimData  = [];
120 4
        $keys       = array_keys($claims);
121
122 4
        foreach ($scopes as $scope) {
123 4
            $scopeName = ($scope instanceof ScopeEntityInterface) ? $scope->getIdentifier() : $scope;
124
125 4
            $claimSet = $this->getClaimSet($scopeName);
126 4
            if (null === $claimSet) {
127 3
                continue;
128
            }
129
130 3
            $intersected = array_intersect($claimSet->getClaims(), $keys);
131
132 3
            if (empty($intersected)) {
133 1
                continue;
134
            }
135
136 3
            $data = array_filter($claims,
137 3
                function($key) use ($intersected) {
138 3
                    return in_array($key, $intersected);
139 3
                },
140
                ARRAY_FILTER_USE_KEY
141 3
            );
142
143 3
            $claimData = array_merge($claimData, $data);
144 4
        }
145
146 4
        return $claimData;
147
    }
148
}
149