Test Failed
Push — master ( 535fd6...a48418 )
by Julien
13:35
created

Jwt::parseToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 6
ccs 0
cts 4
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Zemit\Provider\Jwt;
4
5
use Phalcon\Security\JWT\Builder;
6
use Phalcon\Security\JWT\Exceptions\ValidatorException;
7
use Phalcon\Security\JWT\Signer\Hmac;
8
use Phalcon\Security\JWT\Token\Parser;
9
use Phalcon\Security\JWT\Signer\AbstractSigner;
10
use Phalcon\Security\JWT\Token\Token;
11
use Phalcon\Security\JWT\Validator;
12
13
/**
14
 * allow you to issue, parse and validate JSON Web Tokens as described in RFC 7519.
15
 *
16
 * Builder (Phalcon\Security\JWT\Builder)
17
 * Parser (Phalcon\Security\JWT\Token\Parser)
18
 * Validator (Phalcon\Security\JWT\Validator)
19
 */
20
class Jwt
21
{
22
    public array $options;
23
    public Builder $builder;
24
    public Parser $parser;
25
    public Validator $validator;
26
    public AbstractSigner $signer;
27
    public Token $token;
28
    
29
    /**
30
     * @throws \Exception
31
     */
32
    public function __construct(array $defaultOptions = [])
33
    {
34
        $this->options = $defaultOptions;
35
        $this->signer();
36
    }
37
    
38
    /**
39
     * Initialize JWT Signer
40
     * @param string|null $signer
41
     * @param string|null $algo
42
     * @return AbstractSigner
43
     * @throws \Exception
44
     */
45
    public function signer(string $signer = null, string $algo = null): AbstractSigner {
46
        $signer ??= $this->options['signer'] ?? Hmac::class;
47
        $algo ??= $this->options['algo'] ?? 'sha512';
48
    
49
        $this->signer = new $signer($algo);
50
        
51
        if (!($this->signer instanceof AbstractSigner)) {
0 ignored issues
show
introduced by
$this->signer is always a sub-type of Phalcon\Security\JWT\Signer\AbstractSigner.
Loading history...
52
            throw new \Exception('Signer must be an instance of `' . AbstractSigner::class . '`.');
53
        }
54
        
55
        return $this->signer;
56
    }
57
    
58
    /**
59
     * Initialize JWT Builder
60
     * @param array $options
61
     * @return Builder
62
     * @throws ValidatorException
63
     */
64
    public function builder(array $options = []): Builder {
65
        $options = $this->getDefaultOptions($options);
66
        
67
        $this->builder = new Builder($this->signer);
68
        $this->builder->setPassphrase($options['passphrase']);
0 ignored issues
show
Bug introduced by
It seems like $options['passphrase'] can also be of type null; however, parameter $passphrase of Phalcon\Security\JWT\Builder::setPassphrase() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

68
        $this->builder->setPassphrase(/** @scrutinizer ignore-type */ $options['passphrase']);
Loading history...
69
        $this->builder->setExpirationTime($options['expiration']);
0 ignored issues
show
Bug introduced by
It seems like $options['expiration'] can also be of type null; however, parameter $timestamp of Phalcon\Security\JWT\Builder::setExpirationTime() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

69
        $this->builder->setExpirationTime(/** @scrutinizer ignore-type */ $options['expiration']);
Loading history...
70
        $this->builder->setNotBefore($options['notBefore']);
0 ignored issues
show
Bug introduced by
It seems like $options['notBefore'] can also be of type null; however, parameter $timestamp of Phalcon\Security\JWT\Builder::setNotBefore() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
        $this->builder->setNotBefore(/** @scrutinizer ignore-type */ $options['notBefore']);
Loading history...
71
        $this->builder->setIssuedAt($options['issuedAt']);
0 ignored issues
show
Bug introduced by
It seems like $options['issuedAt'] can also be of type null; however, parameter $timestamp of Phalcon\Security\JWT\Builder::setIssuedAt() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

71
        $this->builder->setIssuedAt(/** @scrutinizer ignore-type */ $options['issuedAt']);
Loading history...
72
        $this->builder->setIssuer($options['issuer']);
0 ignored issues
show
Bug introduced by
It seems like $options['issuer'] can also be of type null; however, parameter $issuer of Phalcon\Security\JWT\Builder::setIssuer() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

72
        $this->builder->setIssuer(/** @scrutinizer ignore-type */ $options['issuer']);
Loading history...
73
        $this->builder->setAudience($options['audience']);
74
        $this->builder->setContentType($options['contentType']);
0 ignored issues
show
Bug introduced by
It seems like $options['contentType'] can also be of type null; however, parameter $contentType of Phalcon\Security\JWT\Builder::setContentType() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

74
        $this->builder->setContentType(/** @scrutinizer ignore-type */ $options['contentType']);
Loading history...
75
        $this->builder->setId($options['id']);
0 ignored issues
show
Bug introduced by
It seems like $options['id'] can also be of type null; however, parameter $id of Phalcon\Security\JWT\Builder::setId() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

75
        $this->builder->setId(/** @scrutinizer ignore-type */ $options['id']);
Loading history...
76
        $this->builder->setSubject($options['subject']);
0 ignored issues
show
Bug introduced by
It seems like $options['subject'] can also be of type null; however, parameter $subject of Phalcon\Security\JWT\Builder::setSubject() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

76
        $this->builder->setSubject(/** @scrutinizer ignore-type */ $options['subject']);
Loading history...
77
        
78
        return $this->builder;
79
    }
80
    
81
    /**
82
     * Initialize JWT Parser
83
     * @return Parser
84
     */
85
    public function parser(): Parser {
86
        $this->parser = new Parser();
87
        return $this->parser;
88
    }
89
    
90
    /**
91
     * Initialize JWT Validator
92
     * @param Token|null $token
93
     * @param int $timeShift
94
     * @return Validator'
0 ignored issues
show
Documentation Bug introduced by
The doc comment Validator' at position 0 could not be parsed: Unknown type name 'Validator'' at position 0 in Validator'.
Loading history...
95
     */
96
    public function validator(Token $token = null, int $timeShift = 0): Validator {
97
        $token ??= $this->token;
98
        
99
        $this->validator = new Validator($token, $timeShift);
100
        
101
        return $this->validator;
102
    }
103
    
104
    /**
105
     * @param Builder|null $builder
106
     * @return Token
107
     * @throws ValidatorException
108
     */
109
    public function buildToken(Builder $builder = null): Token {
110
        $builder ??= $this->builder;
111
        
112
        $this->token = $builder->getToken();
113
        
114
        return $this->token;
115
    }
116
    
117
    /**
118
     * @param string $token
119
     * @return Token
120
     */
121
    public function parseToken(string $token): Token {
122
        $parser = $this->parser();
123
        
124
        $this->token = $parser->parse($token);
125
        
126
        return $this->token;
127
    }
128
    
129
    /**
130
     * @param Token|null $token
131
     * @param int $timeShift
132
     * @param array $options
133
     * @param AbstractSigner|null $signer
134
     * @return void
135
     * @throws ValidatorException
136
     */
137
    public function validateToken(Token $token = null, int $timeShift = 0, array $options = [], AbstractSigner $signer = null): void {
138
        $token ??= $this->token;
139
        $signer ??= $this->signer;
140
        $now = new \DateTimeImmutable();
141
        $options['expiration'] ??= $now->getTimestamp();
142
        $options['notBefore'] ??= $now->modify('-10 second')->getTimestamp();
143
        $options['issuedAt'] ??= $now->modify('+10 second')->getTimestamp();
144
        $options = $this->getDefaultOptions($options);
145
        
146
        $this->validator = $this->validator($token, $timeShift);
147
    
148
        $this->validator->validateId($options['id']);
0 ignored issues
show
Bug introduced by
It seems like $options['id'] can also be of type null; however, parameter $id of Phalcon\Security\JWT\Validator::validateId() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

148
        $this->validator->validateId(/** @scrutinizer ignore-type */ $options['id']);
Loading history...
149
        $this->validator->validateIssuer($options['issuer']);
0 ignored issues
show
Bug introduced by
It seems like $options['issuer'] can also be of type null; however, parameter $issuer of Phalcon\Security\JWT\Validator::validateIssuer() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

149
        $this->validator->validateIssuer(/** @scrutinizer ignore-type */ $options['issuer']);
Loading history...
150
        $this->validator->validateAudience($options['audience']);
0 ignored issues
show
Bug introduced by
It seems like $options['audience'] can also be of type null; however, parameter $audience of Phalcon\Security\JWT\Validator::validateAudience() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

150
        $this->validator->validateAudience(/** @scrutinizer ignore-type */ $options['audience']);
Loading history...
151
        $this->validator->validateNotBefore($options['notBefore']);
0 ignored issues
show
Bug introduced by
It seems like $options['notBefore'] can also be of type null; however, parameter $timestamp of Phalcon\Security\JWT\Val...or::validateNotBefore() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

151
        $this->validator->validateNotBefore(/** @scrutinizer ignore-type */ $options['notBefore']);
Loading history...
152
        $this->validator->validateExpiration($options['expiration']);
0 ignored issues
show
Bug introduced by
It seems like $options['expiration'] can also be of type null; however, parameter $timestamp of Phalcon\Security\JWT\Val...r::validateExpiration() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

152
        $this->validator->validateExpiration(/** @scrutinizer ignore-type */ $options['expiration']);
Loading history...
153
        $this->validator->validateIssuedAt($options['issuedAt']);
0 ignored issues
show
Bug introduced by
It seems like $options['issuedAt'] can also be of type null; however, parameter $timestamp of Phalcon\Security\JWT\Validator::validateIssuedAt() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

153
        $this->validator->validateIssuedAt(/** @scrutinizer ignore-type */ $options['issuedAt']);
Loading history...
154
        $this->validator->validateSignature($signer, $options['passphrase']);
0 ignored issues
show
Bug introduced by
It seems like $options['passphrase'] can also be of type null; however, parameter $passphrase of Phalcon\Security\JWT\Val...or::validateSignature() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

154
        $this->validator->validateSignature($signer, /** @scrutinizer ignore-type */ $options['passphrase']);
Loading history...
155
    }
156
    
157
    /**
158
     * Get default JWT Builder Options
159
     * @param array $options
160
     * @return array
161
     */
162
    public function getDefaultOptions(array $options = []): array {
163
        
164
        $options['expiration'] ??= $this->options['expiration'] ?? null;
165
        $options['notBefore'] ??= $this->options['notBefore'] ?? null;
166
        $options['issuedAt'] ??= $this->options['issuedAt'] ?? null;
167
        $options['issuer'] ??= $this->options['issuer'] ?? null;
168
        $options['audience'] ??= $this->options['audience'] ?? null;
169
        $options['contentType'] ??= $this->options['contentType'] ?? null;
170
        $options['passphrase'] ??= $this->options['passphrase'] ?? null;
171
        $options['id'] ??= $this->options['id'] ?? null;
172
        $options['subject'] ??= $this->options['subject'] ?? null;
173
        
174
        return $options;
175
    }
176
}
177