GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

JWKSet::__clone()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Sop\JWX\JWK;
6
7
use Sop\JWX\JWK\Parameter\JWKParameter;
8
9
/**
10
 * Represents a JWK set structure.
11
 *
12
 * @see https://tools.ietf.org/html/rfc7517#section-5
13
 */
14
class JWKSet implements \Countable, \IteratorAggregate
15
{
16
    /**
17
     * JWK objects.
18
     *
19
     * @var JWK[]
20
     */
21
    protected $_jwks;
22
23
    /**
24
     * Additional members.
25
     *
26
     * @var array
27
     */
28
    protected $_additional;
29
30
    /**
31
     * JWK mappings.
32
     *
33
     * @var array
34
     */
35
    private $_mappings = [];
36
37
    /**
38
     * Constructor.
39
     *
40
     * @param JWK ...$jwks
41
     */
42 56
    public function __construct(JWK ...$jwks)
43
    {
44 56
        $this->_jwks = $jwks;
45 56
        $this->_additional = [];
46 56
    }
47
48
    /**
49
     * Reset internal cache variables on clone.
50
     */
51 2
    public function __clone()
52
    {
53 2
        $this->_mappings = [];
54 2
    }
55
56
    /**
57
     * Initialize from an array representing a JSON object.
58
     *
59
     * @throws \UnexpectedValueException
60
     */
61 3
    public static function fromArray(array $members): self
62
    {
63 3
        if (!isset($members['keys']) || !is_array($members['keys'])) {
64 1
            throw new \UnexpectedValueException(
65 1
                "JWK Set must have a 'keys' member.");
66
        }
67 2
        $jwks = array_map(
68
            function ($jwkdata) {
69 2
                return JWK::fromArray($jwkdata);
70 2
            }, $members['keys']);
71 2
        unset($members['keys']);
72 2
        $obj = new self(...$jwks);
73 2
        $obj->_additional = $members;
74 2
        return $obj;
75
    }
76
77
    /**
78
     * Initialize from a JSON string.
79
     *
80
     * @throws \UnexpectedValueException
81
     */
82 3
    public static function fromJSON(string $json): self
83
    {
84 3
        $members = json_decode($json, true, 32, JSON_BIGINT_AS_STRING);
85 3
        if (!is_array($members)) {
86 1
            throw new \UnexpectedValueException('Invalid JSON.');
87
        }
88 2
        return self::fromArray($members);
89
    }
90
91
    /**
92
     * Get self with keys added.
93
     *
94
     * @param JWK ...$keys JWK objects
95
     */
96 1
    public function withKeys(JWK ...$keys): self
97
    {
98 1
        $obj = clone $this;
99 1
        $obj->_jwks = array_merge($obj->_jwks, $keys);
100 1
        return $obj;
101
    }
102
103
    /**
104
     * Get all JWK's in a set.
105
     *
106
     * @return JWK[]
107
     */
108 1
    public function keys(): array
109
    {
110 1
        return $this->_jwks;
111
    }
112
113
    /**
114
     * Get the first JWK in the set.
115
     *
116
     * @throws \LogicException
117
     */
118 5
    public function first(): JWK
119
    {
120 5
        if (!count($this->_jwks)) {
121 1
            throw new \LogicException('No keys.');
122
        }
123 4
        return $this->_jwks[0];
124
    }
125
126
    /**
127
     * Check whether set has a JWK with a given key ID.
128
     */
129 13
    public function hasKeyID(string $id): bool
130
    {
131 13
        return null !== $this->_getKeyByID($id);
132
    }
133
134
    /**
135
     * Get a JWK by a key ID.
136
     *
137
     * @throws \LogicException
138
     */
139 12
    public function keyByID(string $id): JWK
140
    {
141 12
        $jwk = $this->_getKeyByID($id);
142 12
        if (!$jwk) {
143 1
            throw new \LogicException("No key ID {$id}.");
144
        }
145 11
        return $jwk;
146
    }
147
148
    /**
149
     * Convert to array.
150
     */
151 1
    public function toArray(): array
152
    {
153 1
        $data = $this->_additional;
154 1
        $data['keys'] = array_map(
155
            function (JWK $jwk) {
156 1
                return $jwk->toArray();
157 1
            }, $this->_jwks);
158 1
        return $data;
159
    }
160
161
    /**
162
     * Convert to JSON.
163
     */
164 1
    public function toJSON(): string
165
    {
166 1
        return json_encode((object) $this->toArray(), JSON_UNESCAPED_SLASHES);
167
    }
168
169
    /**
170
     * Get the number of keys.
171
     *
172
     * @see \Countable::count()
173
     */
174 14
    public function count(): int
175
    {
176 14
        return count($this->_jwks);
177
    }
178
179
    /**
180
     * Get iterator for JWK objects.
181
     *
182
     * @see \IteratorAggregate::getIterator()
183
     */
184 1
    public function getIterator(): \ArrayIterator
185
    {
186 1
        return new \ArrayIterator($this->_jwks);
187
    }
188
189
    /**
190
     * Get JWK by key ID.
191
     *
192
     * @return null|JWK Null if not found
193
     */
194 18
    protected function _getKeyByID(string $id): ?JWK
195
    {
196 18
        $map = $this->_getMapping(JWKParameter::PARAM_KEY_ID);
197 18
        return isset($map[$id]) ? $map[$id] : null;
198
    }
199
200
    /**
201
     * Get mapping from parameter values of given parameter name to JWK.
202
     *
203
     * Later duplicate value shall override earlier JWK.
204
     *
205
     * @param string $name Parameter name
206
     */
207 18
    protected function _getMapping(string $name): array
208
    {
209 18
        if (!isset($this->_mappings[$name])) {
210 14
            $mapping = [];
211 14
            foreach ($this->_jwks as $jwk) {
212 14
                if ($jwk->has($name)) {
213 11
                    $key = (string) $jwk->get($name)->value();
214 14
                    $mapping[$key] = $jwk;
215
                }
216
            }
217 14
            $this->_mappings[$name] = $mapping;
218
        }
219 18
        return $this->_mappings[$name];
220
    }
221
}
222