Passed
Push — 2.0 ( c9bf56...63bb57 )
by Kirill
03:11
created

TokenAuth::resolveExistingUser()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 3
nop 1
dl 0
loc 20
rs 9.4285
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\Services;
10
11
use App\Models\User;
12
use Carbon\Carbon;
13
use Illuminate\Contracts\Auth\Authenticatable;
14
use Illuminate\Contracts\Auth\Guard;
15
use Illuminate\Contracts\Encryption\DecryptException;
16
use Illuminate\Encryption\Encrypter;
17
use Illuminate\Support\Arr;
18
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
19
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
20
use Tymon\JWTAuth\Exceptions\JWTException;
21
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
22
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
23
use Tymon\JWTAuth\Providers\JWT\JWTInterface;
24
25
/**
26
 * Class TokenAuth
27
 * @package App\Services
28
 */
29
class TokenAuth
30
{
31
    /**
32
     * @var JWTInterface
33
     */
34
    private $jwt;
35
36
    /**
37
     * @var Guard
38
     */
39
    private $guard;
40
41
    /**
42
     * TokenAuth constructor.
43
     * @param JWTInterface $jwt
44
     * @param Guard $guard
45
     */
46
    public function __construct(JWTInterface $jwt, Guard $guard)
47
    {
48
        $this->jwt = $jwt;
49
        $this->guard = $guard;
50
    }
51
52
    /**
53
     * @param string $email
54
     * @param string $password
55
     * @return Authenticatable
56
     */
57
    public function attemptFromEmailAndPassword(string $email, string $password): ?Authenticatable
58
    {
59
        if (! $this->guard->validate(['email' => $email, 'password' => $password])) {
60
            return null;
61
        }
62
63
        return User::whereEmail($email)->first();
64
    }
65
66
    /**
67
     * @param int $id
68
     * @param string $password
69
     * @return Authenticatable
70
     */
71
    public function resolveFromIdAndPassword(int $id, string $password): ?Authenticatable
72
    {
73
        if (! $this->guard->validate(['id' => $id, 'password' => $password])) {
74
            return null;
75
        }
76
77
        return User::find($id);
78
    }
79
80
    /**
81
     * @param Guard $guard
82
     * @return string
83
     */
84
    public function fromGuard(Guard $guard): string
85
    {
86
        return $this->fromUser($guard->check() ? $guard->user() : $this->guest());
87
    }
88
89
    /**
90
     * @param Authenticatable $user
91
     * @return string
92
     */
93
    public function fromUser(Authenticatable $user): string
94
    {
95
        return $this->encode([
96
            'user'  => [
97
                'id'       => $user->getAuthIdentifier(),
98
                'password' => $user->getAuthPassword(),
99
            ],
100
            'guest' => 0 === (int)$user->getAuthIdentifier(),
101
            'token' => $user->getRememberToken(),
102
        ]);
103
    }
104
105
    /**
106
     * @param array $payload
107
     * @return string
108
     */
109
    public function encode(array $payload): string
110
    {
111
        return $this->jwt->encode($payload);
112
    }
113
114
    /**
115
     * @return Authenticatable
116
     */
117
    public function guest(): Authenticatable
118
    {
119
        return new User(['id' => 0, 'name' => 'Guest']);
120
    }
121
122
    /**
123
     * @param string $token
124
     * @return Authenticatable
125
     * @throws BadRequestHttpException
126
     * @throws UnprocessableEntityHttpException
127
     */
128
    public function fromToken(string $token): Authenticatable
129
    {
130
        try {
131
            $userInfo = $this->decode($token);
132
        } catch (TokenExpiredException $e) {
133
            throw new BadRequestHttpException('Token lifetime is timed out.');
134
        } catch (JWTException $invalidException) {
135
            throw new BadRequestHttpException('Broken api token.');
136
        }
137
138
        if (false !== Arr::get($userInfo, 'guest', true)) {
139
            return $this->resolveExistingUser($userInfo);
140
        }
141
142
        return $this->guest();
143
    }
144
145
    /**
146
     * @param string $token
147
     * @return array
148
     */
149
    public function decode(string $token): array
150
    {
151
        return $this->jwt->decode($token);
152
    }
153
154
    /**
155
     * @param array $userInfo
156
     * @return mixed
157
     * @throws UnprocessableEntityHttpException
158
     */
159
    private function resolveExistingUser(array $userInfo)
160
    {
161
        [$id, $password, $token] = [
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...
Bug introduced by
The variable $token 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...
162
            (int)Arr::get($userInfo, 'user.id'),
163
            (string)Arr::get($userInfo, 'user.password'),
164
            (string)Arr::get($userInfo, 'token'),
165
        ];
166
167
        $user = User::where('id', $id)->where('password', $password)->first();
168
169
        if ($user->remember_token !== $token) {
170
            throw new UnprocessableEntityHttpException('Invalid remember token');
171
        }
172
173
        if (! $user) {
174
            throw new UnprocessableEntityHttpException('Invalid user credentials.');
175
        }
176
177
        return $user;
178
    }
179
}