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.
Passed
Branch php72 (880eb0)
by Joni
05:58
created

ValidationContext::withConstraint()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 9
ccs 6
cts 6
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 3
crap 2
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Sop\JWX\JWT;
6
7
use Sop\JWX\JWK\JWK;
8
use Sop\JWX\JWK\JWKSet;
9
use Sop\JWX\JWT\Claim\RegisteredClaim;
10
use Sop\JWX\JWT\Claim\Validator\Validator;
11
use Sop\JWX\JWT\Exception\ValidationException;
12
13
/**
14
 * Class to provide context for claims validation.
15
 *
16
 * Validation constraints are variables that are compared against the claims.
17
 * Validation of the expiration, not-before and not-after claims is provided by
18
 * default.
19
 *
20
 * Context also provides a set of JSON Web Keys, that shall be used for the
21
 * JWS signature validation or JWE payload decryption.
22
 *
23
 * Registered claims provide their own validation logic. Claims that are not
24
 * supported by this library must be provided with an explicit validator along
25
 * with the constraint.
26
 */
27
class ValidationContext
28
{
29
    /**
30
     * Reference time.
31
     *
32
     * @var int
33
     */
34
    protected $_refTime;
35
36
    /**
37
     * Leeway in seconds for the reference time constraints.
38
     *
39
     * @var int
40
     */
41
    protected $_leeway;
42
43
    /**
44
     * Validation constraints.
45
     *
46
     * @var array
47
     */
48
    protected $_constraints;
49
50
    /**
51
     * Explicitly defined validators for named claims.
52
     *
53
     * @var Validator[]
54
     */
55
    protected $_validators;
56
57
    /**
58
     * Set of JSON Web Keys usable for the validation.
59
     *
60
     * @var JWKSet
61
     */
62
    protected $_keys;
63
64
    /**
65
     * Whether to allow unsecured JWT's, that is, claims without integrity
66
     * protection nor encryption.
67
     *
68
     * @var bool
69
     */
70
    protected $_allowUnsecured;
71
72
    /**
73
     * Constructor.
74
     *
75
     * @param null|array  $constraints Optional array of constraints for the
76
     *                                 registered claims
77
     * @param null|JWKSet $keys        Optional set of JSON Web Keys used for
78
     *                                 signature validation and/or decryption
79
     */
80 41
    public function __construct(?array $constraints = null, ?JWKSet $keys = null)
81
    {
82 41
        $this->_refTime = time();
83 41
        $this->_leeway = 60;
84 41
        $this->_constraints = $constraints ? $constraints : [];
85 41
        $this->_validators = [];
86 41
        $this->_keys = $keys ? $keys : new JWKSet();
87 41
        $this->_allowUnsecured = false;
88 41
    }
89
90
    /**
91
     * Initialize with a single JSON Web Key.
92
     *
93
     * @param JWK        $key         JSON Web Key
94
     * @param null|array $constraints Optional constraints
95
     *
96
     * @return self
97
     */
98 3
    public static function fromJWK(JWK $key, ?array $constraints = null): self
99
    {
100 3
        return new self($constraints, new JWKSet($key));
101
    }
102
103
    /**
104
     * Get self with the reference time.
105
     *
106
     * @param null|int $ts Unix timestamp
107
     *
108
     * @return self
109
     */
110 23
    public function withReferenceTime(?int $ts): self
111
    {
112 23
        $obj = clone $this;
113 23
        $obj->_refTime = $ts;
114 23
        return $obj;
115
    }
116
117
    /**
118
     * Check whether the reference time is set.
119
     *
120
     * @return bool
121
     */
122 20
    public function hasReferenceTime(): bool
123
    {
124 20
        return isset($this->_refTime);
125
    }
126
127
    /**
128
     * Get the reference time.
129
     *
130
     * @throws \LogicException
131
     *
132
     * @return int
133
     */
134 13
    public function referenceTime(): int
135
    {
136 13
        if (!$this->hasReferenceTime()) {
137 1
            throw new \LogicException('Reference time not set.');
138
        }
139 12
        return $this->_refTime;
140
    }
141
142
    /**
143
     * Get self with the reference time leeway.
144
     *
145
     * @param int $seconds
146
     *
147
     * @return self
148
     */
149 11
    public function withLeeway(int $seconds): self
150
    {
151 11
        $obj = clone $this;
152 11
        $obj->_leeway = $seconds;
153 11
        return $obj;
154
    }
155
156
    /**
157
     * Get the reference time leeway.
158
     *
159
     * @return int
160
     */
161 12
    public function leeway(): int
162
    {
163 12
        return $this->_leeway;
164
    }
165
166
    /**
167
     * Get self with a validation constraint.
168
     *
169
     * If the claim does not provide its own validator, an explicit validator
170
     * must be given.
171
     *
172
     * @param string         $name       Claim name
173
     * @param mixed          $constraint Value to check claim against
174
     * @param null|Validator $validator  Optional explicit validator
175
     *
176
     * @return self
177
     */
178 16
    public function withConstraint(string $name, $constraint,
179
        ?Validator $validator = null): self
180
    {
181 16
        $obj = clone $this;
182 16
        $obj->_constraints[$name] = $constraint;
183 16
        if ($validator) {
184 2
            $obj->_validators[$name] = $validator;
185
        }
186 16
        return $obj;
187
    }
188
189
    /**
190
     * Get self with the issuer constraint.
191
     *
192
     * @param string $issuer Issuer name
193
     *
194
     * @return self
195
     */
196 4
    public function withIssuer(string $issuer): self
197
    {
198 4
        return $this->withConstraint(RegisteredClaim::NAME_ISSUER, $issuer);
199
    }
200
201
    /**
202
     * Get self with the subject constraint.
203
     *
204
     * @param string $subject Subject name
205
     *
206
     * @return self
207
     */
208 3
    public function withSubject(string $subject): self
209
    {
210 3
        return $this->withConstraint(RegisteredClaim::NAME_SUBJECT, $subject);
211
    }
212
213
    /**
214
     * Get self with the audience constraint.
215
     *
216
     * @param string $audience Audience name
217
     *
218
     * @return self
219
     */
220 3
    public function withAudience(string $audience): self
221
    {
222 3
        return $this->withConstraint(RegisteredClaim::NAME_AUDIENCE, $audience);
223
    }
224
225
    /**
226
     * Get self with the JWT ID constraint.
227
     *
228
     * @param string $id JWT ID
229
     *
230
     * @return self
231
     */
232 3
    public function withID(string $id): self
233
    {
234 3
        return $this->withConstraint(RegisteredClaim::NAME_JWT_ID, $id);
235
    }
236
237
    /**
238
     * Check whether a named constraint is present.
239
     *
240
     * @param string $name Claim name
241
     *
242
     * @return bool
243
     */
244 35
    public function hasConstraint(string $name): bool
245
    {
246 35
        return isset($this->_constraints[$name]);
247
    }
248
249
    /**
250
     * Get a constraint value by the claim name.
251
     *
252
     * @param string $name Claim name
253
     *
254
     * @throws \LogicException If constraint is not set
255
     *
256
     * @return mixed Constraint value
257
     */
258 22
    public function constraint(string $name)
259
    {
260 22
        if (!$this->hasConstraint($name)) {
261 1
            throw new \LogicException("Constraint {$name} not set.");
262
        }
263 21
        return $this->_constraints[$name];
264
    }
265
266
    /**
267
     * Check whether a validator is defined for the given claim name.
268
     *
269
     * @param string $name Claim name
270
     *
271
     * @return bool
272
     */
273 17
    public function hasValidator(string $name): bool
274
    {
275 17
        return isset($this->_validators[$name]);
276
    }
277
278
    /**
279
     * Get explicitly defined validator by the claim name.
280
     *
281
     * @param string $name Claim name
282
     *
283
     * @throws \LogicException If validator is not set
284
     *
285
     * @return Validator
286
     */
287 3
    public function validator(string $name): Validator
288
    {
289 3
        if (!$this->hasValidator($name)) {
290 1
            throw new \LogicException("Validator {$name} not set.");
291
        }
292 2
        return $this->_validators[$name];
293
    }
294
295
    /**
296
     * Get a set of JSON Web Keys defined in this context.
297
     *
298
     * @return JWKSet
299
     */
300 8
    public function keys(): JWKSet
301
    {
302 8
        return $this->_keys;
303
    }
304
305
    /**
306
     * Get self with 'allow unsecured' flag set.
307
     *
308
     * If the unsecured JWT's are allowed, claims shall be considered valid even
309
     * though they are not signed nor encrypted.
310
     *
311
     * @param bool $allow Whether to allow unsecured JWT's
312
     *
313
     * @return self
314
     */
315 3
    public function withUnsecuredAllowed(bool $allow): self
316
    {
317 3
        $obj = clone $this;
318 3
        $obj->_allowUnsecured = $allow;
319 3
        return $obj;
320
    }
321
322
    /**
323
     * Check whether the unsecured JWT's are allowed.
324
     *
325
     * @return bool
326
     */
327 3
    public function isUnsecuredAllowed(): bool
328
    {
329 3
        return $this->_allowUnsecured;
330
    }
331
332
    /**
333
     * Validate claims.
334
     *
335
     * @param Claims $claims
336
     *
337
     * @throws ValidationException If any of the claims is not valid
338
     *
339
     * @return self
340
     */
341 25
    public function validate(Claims $claims): self
342
    {
343 25
        foreach ($claims as $claim) {
344 25
            if (!$claim->validateWithContext($this)) {
345 10
                throw new ValidationException(
346 25
                    "Validation of claim '" . $claim->name() . "' failed.");
347
            }
348
        }
349 15
        return $this;
350
    }
351
}
352