Test Failed
Push — feature-laravel-5.4 ( bce2b2...556e60 )
by Kirill
03:14
created

ApiAuthenticate::authByToken()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 16
nc 5
nop 1
dl 0
loc 27
rs 8.439
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of laravel.su package.
4
 * For the full copyright and license information, please view the LICENSE
5
 * file that was distributed with this source code.
6
 */
7
declare(strict_types=1);
8
9
namespace App\Http\Middleware;
10
11
use App\Models\User;
12
use Illuminate\Contracts\Auth\Authenticatable;
13
use Illuminate\Contracts\Auth\Guard;
14
use Illuminate\Contracts\Container\Container;
15
use Illuminate\Http\Request;
16
use Illuminate\Http\Response;
17
use Illuminate\Support\Arr;
18
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
19
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
20
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
21
use Tymon\JWTAuth\Exceptions\JWTException;
22
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
23
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
24
use Tymon\JWTAuth\Providers\JWT\JWTInterface;
25
26
/**
27
 * Class ApiAuthenticate.
28
 */
29
class ApiAuthenticate
30
{
31
    /**
32
     * @var Guard
33
     */
34
    private $auth;
35
36
    /**
37
     * @var JWTInterface
38
     */
39
    private $jwt;
40
41
    /**
42
     * @var Container
43
     */
44
    private $app;
45
46
    /**
47
     * ApiAuthenticate constructor.
48
     * @param Guard        $auth
49
     * @param JWTInterface $jwt
50
     * @param Container    $app
51
     */
52
    public function __construct(Guard $auth, JWTInterface $jwt, Container $app)
53
    {
54
        $this->auth = $auth;
55
        $this->jwt = $jwt;
56
        $this->app = $app;
57
    }
58
59
    /**
60
     * @param Request  $request
61
     * @param \Closure $next
62
     * @return mixed
63
     * @throws BadRequestHttpException
64
     * @throws UnprocessableEntityHttpException
65
     */
66
    public function handle(Request $request, \Closure $next)
67
    {
68
        $user = $this->getUser($request);
69
70
        $this->app->instance(Authenticatable::class, $user);
71
72
        /** @var Response $response */
73
        return $next($request);
74
    }
75
76
    /**
77
     * @param Request $request
78
     * @return Authenticatable|User
79
     * @throws BadRequestHttpException
80
     * @throws UnprocessableEntityHttpException
81
     */
82
    private function getUser(Request $request): Authenticatable
83
    {
84
        switch (true) {
85
            case $request->has('_token'):
86
                return $this->authByToken($request->get('_token', ''));
87
88
            case $request->headers->has('X-Api-Token'):
89
                return $this->authByToken($request->headers->get('X-Api-Token', ''));
90
91
            case $this->auth->check():
92
                return $this->auth->user();
93
        }
94
95
        return User::guest();
96
    }
97
98
    /**
99
     * @param string $token
100
     * @return Authenticatable
101
     * @throws BadRequestHttpException
102
     * @throws UnprocessableEntityHttpException
103
     */
104
    private function authByToken(string $token): Authenticatable
105
    {
106
        try {
107
            $userInfo = $this->jwt->decode($token);
108
        } catch (TokenExpiredException $e) {
109
            throw new BadRequestHttpException('Token lifetime is timed out.');
110
        } catch (JWTException $invalidException) {
111
            throw new BadRequestHttpException('Broken api token.');
112
        }
113
114
        [$id, $password] = [
0 ignored issues
show
Bug introduced by
The variable $id does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $password does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
115
            Arr::get($userInfo, 'user.id'),
116
            Arr::get($userInfo, 'user.password')
117
        ];
118
119
        if (User::guest()->id === $id) {
120
            return User::guest();
121
        }
122
123
        $user = User::where('id', $id)->where('password', $password)->first();
124
125
        if (! $user) {
126
            throw new UnprocessableEntityHttpException('Invalid user credentials.');
127
        }
128
129
        return $user;
130
    }
131
}