Passed
Push — master ( bf67e8...626507 )
by Milad
02:27
created

VerifierFactory::__construct()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 5
eloc 8
c 1
b 0
f 1
nc 3
nop 3
dl 0
loc 14
rs 9.6111
1
<?php
2
3
namespace MiladRahimi\Jwt;
4
5
use InvalidArgumentException;
6
use MiladRahimi\Jwt\Base64\Base64Parser;
7
use MiladRahimi\Jwt\Base64\SafeBase64Parser;
8
use MiladRahimi\Jwt\Cryptography\Verifier;
9
use MiladRahimi\Jwt\Exceptions\InvalidTokenException;
10
use MiladRahimi\Jwt\Exceptions\JsonDecodingException;
11
use MiladRahimi\Jwt\Exceptions\NoKidException;
12
use MiladRahimi\Jwt\Exceptions\VerifierNotFoundException;
13
use MiladRahimi\Jwt\Json\JsonParser;
14
use MiladRahimi\Jwt\Json\StrictJsonParser;
15
16
class VerifierFactory
17
{
18
    private array $verifiers;
19
20
    private JsonParser $jsonParser;
21
22
    private Base64Parser $base64Parser;
23
24
    /**
25
     * @param Verifier[] $verifiers
26
     * @param JsonParser|null $jsonParser
27
     * @param Base64Parser|null $base64Parser
28
     */
29
    public function __construct(array $verifiers, JsonParser $jsonParser = null, Base64Parser $base64Parser = null)
30
    {
31
        foreach ($verifiers as $verifier) {
32
            if ($verifier instanceof Verifier) {
33
                $this->verifiers[$verifier->kid()] = $verifier;
34
            } else {
35
                throw new InvalidArgumentException(
36
                    'Values of $verifiers array must be instance of MiladRahimi\Jwt\Cryptography\Verifier.'
37
                );
38
            }
39
        }
40
41
        $this->jsonParser = $jsonParser ?: new StrictJsonParser();
42
        $this->base64Parser = $base64Parser ?: new SafeBase64Parser();
43
    }
44
45
    /**
46
     * @throws InvalidTokenException
47
     * @throws JsonDecodingException
48
     * @throws NoKidException
49
     * @throws VerifierNotFoundException
50
     */
51
    public function getVerifier(string $jwt)
52
    {
53
        $header = $this->jsonParser->decode($this->base64Parser->decode($this->extractHeader($jwt)));
54
55
        if (isset($header['kid'])) {
56
            if (isset($this->verifiers[$header['kid']])) {
57
                return $this->verifiers[$header['kid']];
58
            }
59
60
            throw new VerifierNotFoundException("No verifier found for {$header['kid']}");
61
        }
62
63
        throw new NoKidException();
64
    }
65
66
    /**
67
     * Extract header component of given JWT
68
     *
69
     * @throws Exceptions\InvalidTokenException
70
     */
71
    private function extractHeader(string $jwt): string
72
    {
73
        $sections = explode('.', $jwt);
74
75
        if (count($sections) !== 3) {
76
            throw new Exceptions\InvalidTokenException('JWT format is not valid');
77
        }
78
79
        return $sections[0];
80
    }
81
}