AbstractLoader::sub()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2019 Spomky-Labs
9
 *
10
 * This software may be modified and distributed under the terms
11
 * of the MIT license.  See the LICENSE file for details.
12
 */
13
14
namespace Jose\Easy;
15
16
use InvalidArgumentException;
17
use Jose\Component\Checker;
18
use Jose\Component\Core\Algorithm;
19
use Jose\Component\Core\JWK;
20
use Jose\Component\Core\JWKSet;
21
22
abstract class AbstractLoader
23
{
24
    /**
25
     * @var string
26
     */
27
    protected $token;
28
29
    /**
30
     * @var JWKSet
31
     */
32
    protected $jwkset;
33
34
    /**
35
     * @var Checker\HeaderChecker[]
36
     */
37
    protected $headerCheckers = [];
38
39
    /**
40
     * @var Checker\ClaimChecker[]
41
     */
42
    protected $claimCheckers = [];
43
44
    /**
45
     * @var string[]
46
     */
47
    protected $allowedAlgorithms = [];
48
49
    /**
50
     * @var Algorithm[]
51
     */
52
    protected $algorithms = [];
53
54
    /**
55
     * @var string[]
56
     */
57
    protected $mandatoryClaims = [];
58
59
    protected function __construct(string $token)
60
    {
61
        $this->token = $token;
62
        $this->jwkset = new JWKSet([]);
63
        $this->claimCheckers = [];
64
    }
65
66
    /**
67
     * @param string[] $mandatoryClaims
68
     */
69
    public function mandatory(array $mandatoryClaims): self
70
    {
71
        $clone = clone $this;
72
        $clone->mandatoryClaims = $mandatoryClaims;
73
74
        return $clone;
75
    }
76
77
    public function aud(string $aud, bool $inHeader = false): self
78
    {
79
        return $this->claim('aud', new Checker\AudienceChecker($aud, true), $inHeader);
80
    }
81
82
    public function iss(string $iss, bool $inHeader = false): self
83
    {
84
        return $this->claim('iss', new Checker\IssuerChecker([$iss], true), $inHeader);
85
    }
86
87
    public function jti(string $jti, bool $inHeader = false): self
88
    {
89
        return $this->claim('jti', $jti, $inHeader);
90
    }
91
92
    public function sub(string $sub, bool $inHeader = false): self
93
    {
94
        return $this->claim('sub', $sub, $inHeader);
95
    }
96
97
    /**
98
     * @param null|array|callable|Checker\ClaimChecker $checker
99
     */
100
    public function claim(string $key, $checker, bool $inHeader = false): self
101
    {
102
        $clone = clone $this;
103
        if (false === $checker) {
104
            unset($clone->claimCheckers[$key]);
105
106
            return $clone;
107
        }
108
109
        switch (true) {
110
            case $checker instanceof Checker\ClaimChecker:
111
                break;
112
            case \is_callable($checker):
113
                $checker = new CallableChecker($key, $checker);
114
115
                break;
116
            case \is_array($checker):
117
                $checker = new CallableChecker($key, static function ($value) use ($checker) {return \in_array($value, $checker, true); });
118
119
                break;
120
            default:
121
                $checker = new CallableChecker($key, static function ($value) use ($checker) {return $value === $checker; });
122
        }
123
124
        $clone->claimCheckers[$key] = $checker;
125
        if ($inHeader) {
126
            return $clone->header($key, $checker);
127
        }
128
129
        return $clone;
130
    }
131
132
    /**
133
     * @param false|int $leeway
134
     *
135
     * @throws InvalidArgumentException if the leeway is negative, not an integer or not false
136
     */
137
    public function exp($leeway = 0, bool $inHeader = false): self
138
    {
139
        if (false === $leeway) {
140
            $clone = clone $this;
141
            unset($clone->claimCheckers['exp']);
142
143
            return $clone;
144
        }
145
        if (!\is_int($leeway) or $leeway < 0) {
146
            throw new InvalidArgumentException('First parameter for "exp" claim is invalid. Set false to disable or a positive integer.');
147
        }
148
149
        return $this->claim('exp', new Checker\ExpirationTimeChecker($leeway), $inHeader);
150
    }
151
152
    /**
153
     * @param false|int $leeway
154
     *
155
     * @throws InvalidArgumentException if the leeway is negative, not an integer or not false
156
     */
157
    public function nbf($leeway = 0, bool $inHeader = false): self
158
    {
159
        if (false === $leeway) {
160
            $clone = clone $this;
161
            unset($clone->claimCheckers['nbf']);
162
163
            return $clone;
164
        }
165
        if (!\is_int($leeway) or $leeway < 0) {
166
            throw new InvalidArgumentException('First parameter for "nbf" claim is invalid. Set false to disable or a positive integer.');
167
        }
168
169
        return $this->claim('nbf', new Checker\NotBeforeChecker($leeway, true), $inHeader);
170
    }
171
172
    /**
173
     * @param false|int $leeway
174
     *
175
     * @throws InvalidArgumentException if the leeway is negative, not an integer or not false
176
     */
177
    public function iat($leeway = 0, bool $inHeader = false): self
178
    {
179
        if (false === $leeway) {
180
            $clone = clone $this;
181
            unset($clone->claimCheckers['iat']);
182
183
            return $clone;
184
        }
185
        if (!\is_int($leeway) or $leeway < 0) {
186
            throw new InvalidArgumentException('First parameter for "iat" claim is invalid. Set false to disable or a positive integer.');
187
        }
188
189
        return $this->claim('iat', new Checker\IssuedAtChecker($leeway, true), $inHeader);
190
    }
191
192
    /**
193
     * @param Algorithm|string $alg
194
     *
195
     * @throws InvalidArgumentException if the algorithm is not a string or an instance of Jose\Component\Core\Algorithm
196
     */
197
    public function alg($alg): self
198
    {
199
        $clone = clone $this;
200
        switch (true) {
201
            case \is_string($alg):
202
                $clone->allowedAlgorithms[] = $alg;
203
204
                return $clone;
205
            case $alg instanceof Algorithm:
206
                $clone->algorithms[$alg->name()] = $alg;
207
                $clone->allowedAlgorithms[] = $alg->name();
208
209
                return $clone;
210
            default:
211
                throw new InvalidArgumentException('Invalid parameter "alg". Shall be a string or an algorithm instance.');
212
        }
213
    }
214
215
    /**
216
     * @param Algorithm[]|string[] $algs
217
     */
218
    public function algs($algs): self
219
    {
220
        $clone = clone $this;
221
        foreach ($algs as $alg) {
222
            $clone = $clone->alg($alg);
223
        }
224
225
        return $clone;
226
    }
227
228
    /**
229
     * @param array|callable|Checker\HeaderChecker|false|mixed $checker
230
     */
231
    public function header(string $key, $checker): self
232
    {
233
        $clone = clone $this;
234
        if (false === $checker) {
235
            unset($clone->headerCheckers[$key]);
236
237
            return $clone;
238
        }
239
240
        switch (true) {
241
            case $checker instanceof Checker\HeaderChecker:
242
                break;
243
            case \is_callable($checker):
244
                $checker = new CallableChecker($key, $checker);
245
246
                break;
247
            case \is_array($checker):
248
                $checker = new CallableChecker($key, static function ($value) use ($checker) {return \in_array($value, $checker, true); });
249
250
                break;
251
            default:
252
                $checker = new CallableChecker($key, static function ($value) use ($checker) {return $value === $checker; });
253
        }
254
255
        $clone->headerCheckers[$key] = $checker;
256
257
        return $clone;
258
    }
259
260
    public function key(JWK $jwk): self
261
    {
262
        $clone = clone $this;
263
        $jwkset = $this->jwkset->with($jwk);
264
        $clone->jwkset = $jwkset;
265
266
        return $clone;
267
    }
268
269
    public function keyset(JWKSet $jwkset): self
270
    {
271
        $clone = clone $this;
272
        $clone->jwkset = $jwkset;
273
274
        return $clone;
275
    }
276
}
277