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.
Test Setup Failed
Push — master ( 500279...2f8c13 )
by
unknown
02:35
created

JsonWebToken::decode()   F

Complexity

Conditions 24
Paths 276

Size

Total Lines 113
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 24
eloc 53
nc 276
nop 2
dl 0
loc 113
rs 2.3833
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file is part of the O2System Framework package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author         Steeve Andrian Salim
9
 * @copyright      Copyright (c) Steeve Andrian Salim
10
 */
11
12
// ------------------------------------------------------------------------
13
14
namespace O2System\Security\Authentication;
15
16
// ------------------------------------------------------------------------
17
18
use O2System\Security\Encoders\Base64;
19
use O2System\Security\Encoders\Json;
20
use O2System\Security\Generators\Signature;
21
use O2System\Security\Generators\Token;
22
23
/**
24
 * Class JsonWebToken
25
 * @package O2System\Security\Authentication
26
 */
27
class JsonWebToken extends Token
28
{
29
    protected $keyId;
30
31
    /**
32
     * When checking nbf, iat or expiration times,
33
     * we want to provide some extra leeway time to
34
     * account for clock skew.
35
     */
36
    protected $leeway = 0;
37
38
    protected $headers = [
39
        'typ' => 'JWT',
40
    ];
41
42
    // ------------------------------------------------------------------------
43
44
    public function setKeyId($keyId)
45
    {
46
        $this->keyId = $keyId;
47
48
        return $this;
49
    }
50
51
    // ------------------------------------------------------------------------
52
53
    public function setLeeway($leeway)
54
    {
55
        $this->leeway = intval($leeway);
56
57
        return $this;
58
    }
59
60
    // ------------------------------------------------------------------------
61
62
    public function encode(array $payload, $key = null)
63
    {
64
        $key = empty($key) ? $this->key : $key;
65
        if (is_null($key)) {
66
            if (class_exists('O2System\Framework', false)) {
67
                $key = config()->getItem('security')->encryptionKey;
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

67
                $key = /** @scrutinizer ignore-call */ config()->getItem('security')->encryptionKey;
Loading history...
68
            }
69
        }
70
71
        $this->addHeader('alg', $this->algorithm);
72
73
        if ( ! empty($this->keyId)) {
74
            $this->addHeader('kid', $this->keyId);
75
        }
76
77
        // Create Header Segment
78
        $segments[] = Base64::encode(Json::encode($this->headers));
0 ignored issues
show
Comprehensibility Best Practice introduced by
$segments was never initialized. Although not strictly required by PHP, it is generally a good practice to add $segments = array(); before regardless.
Loading history...
79
80
        // Create Payload Segment
81
        $segments[] = Base64::encode(Json::encode($payload));
82
83
        // Create Signature Segment
84
        $segments[] = Base64::encode(Signature::generate($segments, $key, $this->algorithm));
85
86
        return implode('.', $segments);
87
    }
88
89
    // ------------------------------------------------------------------------
90
91
    public function decode($token, $key = null)
92
    {
93
        $key = empty($key) ? $this->key : $key;
94
        if (is_null($key)) {
95
            if (class_exists('O2System\Framework', false)) {
96
                $key = config()->getItem('security')->encryptionKey;
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

96
                $key = /** @scrutinizer ignore-call */ config()->getItem('security')->encryptionKey;
Loading history...
97
            }
98
        }
99
100
        $timestamp = empty($this->timestamp) ? time() : $this->timestamp;
101
102
        $segments = explode('.', $token);
103
        $segments = array_map('trim', $segments);
104
105
        if (count($segments) == 3) {
106
            list($headers, $payload, $signature) = $segments;
107
108
            // Base64 decode headers
109
            if (false === ($headers = Base64::decode($headers))) {
110
                $this->errors[] = 'Invalid header base64 decoding';
111
112
                return false;
113
            }
114
115
            // Json decode headers
116
            if (null === ($headers = Json::decode($headers))) {
117
                $this->errors[] = 'Invalid header json decoding';
118
119
                return false;
120
            }
121
122
            // Validate algorithm header
123
            if (empty($headers->alg)) {
124
                $this->errors[] = 'Invalid algorithm';
125
126
                return false;
127
            } elseif ( ! Signature::validAlgorithm($headers->alg)) {
0 ignored issues
show
Bug introduced by
The method validAlgorithm() does not exist on O2System\Security\Generators\Signature. ( Ignorable by Annotation )

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

127
            } elseif ( ! Signature::/** @scrutinizer ignore-call */ validAlgorithm($headers->alg)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
128
                $this->errors[] = 'Unsupported algorithm';
129
130
                return false;
131
            }
132
133
            // Validate algorithm key id
134
            if (is_array($key) or $key instanceof \ArrayAccess) {
135
                if (isset($headers->kid)) {
136
                    if ( ! isset($key[ $headers->kid ])) {
137
                        $this->errors[] = 'Invalid Key Id';
138
139
                        return false;
140
                    }
141
142
                    $key = $key[ $headers->kid ];
143
                } else {
144
                    $this->errors[] = 'Empty Key id';
145
146
                    return false;
147
                }
148
            }
149
150
            // Base64 decode payload
151
            if (false === ($payload = Base64::decode($payload))) {
152
                $this->errors[] = 'Invalid payload base64 decoding';
153
154
                return false;
155
            }
156
157
            // Json decode payload
158
            if (null === ($payload = Json::decode($payload))) {
159
                $this->errors[] = 'Invalid payload json decoding';
160
161
                return false;
162
            }
163
164
            // Base64 decode payload
165
            if (false === ($signature = Base64::decode($signature))) {
166
                $this->errors[] = 'Invalid signature base64 decoding';
167
168
                return false;
169
            }
170
171
            if (Signature::verify($token, $signature, $key, $headers->alg) === false) {
172
                $this->errors[] = 'Invalid signature';
173
174
                return false;
175
            }
176
177
            // Check if the nbf if it is defined. This is the time that the
178
            // token can actually be used. If it's not yet that time, abort.
179
            if (isset($payload->nbf) && $payload->nbf > ($timestamp + $this->leeway)) {
180
                $this->errors[] = 'Cannot handle token prior to ' . date(\DateTime::ISO8601, $payload->nbf);
181
182
                return false;
183
            }
184
185
            // Check that this token has been created before 'now'. This prevents
186
            // using tokens that have been created for later use (and haven't
187
            // correctly used the nbf claim).
188
            if (isset($payload->iat) && $payload->iat > ($timestamp + $this->leeway)) {
189
                $this->errors[] = 'Cannot handle token prior to ' . date(\DateTime::ISO8601, $payload->iat);
190
191
                return false;
192
            }
193
            // Check if this token has expired.
194
            if (isset($payload->exp) && ($timestamp - $this->leeway) >= $payload->exp) {
195
                $this->errors[] = 'Expired token';
196
197
                return false;
198
            }
199
200
            return $payload;
201
        }
202
203
        return false;
204
    }
205
}