Completed
Push — develop ( 8d6c8a...ce3493 )
by Sean
37:58 queued 35:12
created

JWTAuth   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 338
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 92.59%

Importance

Changes 21
Bugs 3 Features 1
Metric Value
wmc 33
c 21
b 3
f 1
lcom 1
cbo 9
dl 0
loc 338
ccs 75
cts 81
cp 0.9259
rs 9.4

24 Methods

Rating   Name   Duplication   Size   Complexity  
A fromUser() 0 6 1
A attempt() 0 8 2
A authenticate() 0 10 2
A toUser() 0 4 1
A refresh() 0 6 1
A invalidate() 0 6 1
A checkOrFail() 0 4 1
A check() 0 10 2
A getToken() 0 12 3
A getPayload() 0 6 1
A getClaimsArray() 0 8 1
A user() 0 4 1
A __construct() 0 6 1
A parseToken() 0 8 2
A makePayload() 0 4 1
A setToken() 0 6 2
A requireToken() 0 6 2
A setRequest() 0 6 1
A manager() 0 4 1
A parser() 0 4 1
A factory() 0 4 1
A blacklist() 0 4 1
A __call() 0 8 2
A unsetToken() 0 4 1
1
<?php
2
3
/*
4
 * This file is part of jwt-auth
5
 *
6
 * (c) Sean Tymon <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Tymon\JWTAuth;
13
14
use Illuminate\Http\Request;
15
use Tymon\JWTAuth\Support\CustomClaims;
16
use Tymon\JWTAuth\Contracts\JWTSubject;
17
use Tymon\JWTAuth\Contracts\Providers\Auth;
18
use Tymon\JWTAuth\Exceptions\JWTException;
19
use Tymon\JWTAuth\Http\TokenParser;
20
21
class JWTAuth
22
{
23
    use CustomClaims;
24
25
    /**
26
     * @var \Tymon\JWTAuth\Manager
27
     */
28
    protected $manager;
29
30
    /**
31
     * @var \Tymon\JWTAuth\Contracts\Providers\Auth
32
     */
33
    protected $auth;
34
35
    /**
36
     * @var \Tymon\JWTAuth\Http\TokenParser
37
     */
38
    protected $parser;
39
40
    /**
41
     * @var \Tymon\JWTAuth\Token
42
     */
43
    protected $token;
44
45
    /**
46
     * @param \Tymon\JWTAuth\Manager                   $manager
47
     * @param \Tymon\JWTAuth\Contracts\Providers\Auth  $auth
48
     * @param \Tymon\JWTAuth\Http\TokenParser          $parser
49
     */
50 38
    public function __construct(Manager $manager, Auth $auth, TokenParser $parser)
51
    {
52 38
        $this->manager = $manager;
53 38
        $this->auth = $auth;
54 38
        $this->parser = $parser;
55 38
    }
56
57
    /**
58
     * Generate a token using the user identifier as the subject claim.
59
     *
60
     * @param \Tymon\JWTAuth\Contracts\JWTSubject $user
61
     *
62
     * @return string
63
     */
64 4
    public function fromUser(JWTSubject $user)
65
    {
66 4
        $payload = $this->makePayload($user);
67
68 4
        return $this->manager->encode($payload)->get();
69
    }
70
71
    /**
72
     * Attempt to authenticate the user and return the token.
73
     *
74
     * @param array $credentials
75
     *
76
     * @return false|string
77
     */
78 4
    public function attempt(array $credentials)
79
    {
80 4
        if (! $this->auth->byCredentials($credentials)) {
81 2
            return false;
82
        }
83
84 2
        return $this->fromUser($this->user());
85
    }
86
87
    /**
88
     * Authenticate a user via a token.
89
     *
90
     * @return \Tymon\JWTAuth\Contracts\JWTSubject|false
91
     */
92 6
    public function authenticate()
93
    {
94 6
        $id = $this->getPayload()->get('sub');
95
96 4
        if (! $this->auth->byId($id)) {
97 2
            return false;
98
        }
99
100 2
        return $this->user();
101
    }
102
103
    /**
104
     * Alias for authenticate().
105
     *
106
     * @return \Tymon\JWTAuth\Contracts\JWTSubject|false
107
     */
108 2
    public function toUser()
109
    {
110 2
        return $this->authenticate();
111
    }
112
113
    /**
114
     * Refresh an expired token.
115
     *
116
     * @return string
117
     */
118 2
    public function refresh()
119
    {
120 2
        $this->requireToken();
121
122 2
        return $this->manager->customClaims($this->getCustomClaims())->refresh($this->token)->get();
123
    }
124
125
    /**
126
     * Invalidate a token (add it to the blacklist).
127
     *
128
     * @param  boolean  $forceForever
129
     *
130
     * @return boolean
131
     */
132 4
    public function invalidate($forceForever = false)
133
    {
134 4
        $this->requireToken();
135
136 4
        return $this->manager->invalidate($this->token, $forceForever);
137
    }
138
139
    /**
140
     * Alias to get the payload, and as a result checks that
141
     * the token is valid i.e. not expired or blacklisted
142
     *
143
     * @throws JWTException
144
     *
145
     * @return \Tymon\JWTAuth\Payload
146
     */
147 4
    public function checkOrFail()
148
    {
149 4
        return $this->getPayload();
150
    }
151
152
    /**
153
     * Check that the token is valid
154
     *
155
     * @return boolean
156
     */
157 4
    public function check()
158
    {
159
        try {
160 4
            $this->checkOrFail();
161 3
        } catch (JWTException $e) {
162 2
            return false;
163
        }
164
165 2
        return true;
166
    }
167
168
    /**
169
     * Get the token.
170
     *
171
     * @return false|Token
172
     */
173 6
    public function getToken()
174
    {
175 6
        if (! $this->token) {
176
            try {
177 4
                $this->parseToken();
178 3
            } catch (JWTException $e) {
179 2
                return false;
180
            }
181 1
        }
182
183 4
        return $this->token;
184
    }
185
186
    /**
187
     * Parse the token from the request.
188
     *
189
     * @throws \Tymon\JWTAuth\Exceptions\JWTException
190
     *
191
     * @return JWTAuth
192
     */
193 12
    public function parseToken()
194
    {
195 12
        if (! $token = $this->parser->parseToken()) {
196 4
            throw new JWTException('The token could not be parsed from the request');
197
        }
198
199 8
        return $this->setToken($token);
0 ignored issues
show
Bug introduced by
It seems like $token defined by $this->parser->parseToken() on line 195 can also be of type array; however, Tymon\JWTAuth\JWTAuth::setToken() does only seem to accept object<Tymon\JWTAuth\Token>|string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
200
    }
201
202
    /**
203
     * Get the raw Payload instance.
204
     *
205
     * @return \Tymon\JWTAuth\Payload
206
     */
207 10
    public function getPayload()
208
    {
209 10
        $this->requireToken();
210
211 8
        return $this->manager->decode($this->token);
212
    }
213
214
    /**
215
     * Create a Payload instance.
216
     *
217
     * @param \Tymon\JWTAuth\Contracts\JWTSubject $user
218
     *
219
     * @return \Tymon\JWTAuth\Payload
220
     */
221 4
    public function makePayload(JWTSubject $user)
222
    {
223 4
        return $this->factory()->customClaims($this->getClaimsArray($user))->make();
224
    }
225
226
    /**
227
     * Build the claims array and return it
228
     *
229
     * @param \Tymon\JWTAuth\Contracts\JWTSubject $user
230
     *
231
     * @return array
232
     */
233 4
    protected function getClaimsArray(JWTSubject $user)
234
    {
235 4
        return array_merge(
236 4
            ['sub' => $user->getJWTIdentifier()],
237 4
            $this->customClaims,
238 4
            $user->getJWTCustomClaims()
239 2
        );
240
    }
241
242
    /**
243
     * Get the authenticated user
244
     *
245
     * @return \Tymon\JWTAuth\Contracts\JWTSubject
246
     */
247 4
    public function user()
248
    {
249 4
        return $this->auth->user();
250
    }
251
252
    /**
253
     * Set the token.
254
     *
255
     * @param  Token|string  $token
256
     *
257
     * @return JWTAuth
258
     */
259 18
    public function setToken($token)
260
    {
261 18
        $this->token = $token instanceof Token ? $token : new Token($token);
262
263 18
        return $this;
264
    }
265
266
    /**
267
     * Remove the current token.
268
     */
269
    public function unsetToken()
270
    {
271
        $this->token = null;
272
    }
273
274
    /**
275
     * Ensure that a token is available.
276
     *
277
     * @throws \Tymon\JWTAuth\Exceptions\JWTException
278
     */
279 16
    protected function requireToken()
280
    {
281 16
        if (! $this->token) {
282 2
            throw new JWTException('A token is required');
283
        }
284 14
    }
285
286
    /**
287
     * Set the request instance.
288
     *
289
     * @param \Illuminate\Http\Request $request
290
     *
291
     * @return JWTAuth
292
     */
293 2
    public function setRequest(Request $request)
294
    {
295 2
        $this->parser->setRequest($request);
296
297 2
        return $this;
298
    }
299
300
    /**
301
     * Get the Manager instance.
302
     *
303
     * @return \Tymon\JWTAuth\Manager
304
     */
305 4
    public function manager()
306
    {
307 4
        return $this->manager;
308
    }
309
310
    /**
311
     * Get the TokenParser instance
312
     *
313
     * @return \Tymon\JWTAuth\Http\TokenParser
314
     */
315 2
    public function parser()
316
    {
317 2
        return $this->parser;
318
    }
319
320
    /**
321
     * Get the Payload Factory
322
     *
323
     * @return \Tymon\JWTAuth\Factory
324
     */
325 4
    public function factory()
326
    {
327 4
        return $this->manager->getPayloadFactory();
328
    }
329
330
    /**
331
     * Get the Blacklist
332
     *
333
     * @return \Tymon\JWTAuth\Blacklist
334
     */
335
    public function blacklist()
336
    {
337
        return $this->manager->getBlacklist();
338
    }
339
340
    /**
341
     * Magically call the JWT Manager.
342
     *
343
     * @param string $method
344
     * @param array  $parameters
345
     *
346
     * @return mixed
347
     *
348
     * @throws \BadMethodCallException
349
     */
350 2
    public function __call($method, $parameters)
351
    {
352 2
        if (method_exists($this->manager, $method)) {
353 2
            return call_user_func_array([$this->manager, $method], $parameters);
354
        }
355
356
        throw new \BadMethodCallException("Method [$method] does not exist.");
357
    }
358
}
359