Completed
Push — master ( b0b47a...abbd86 )
by Arman
15s queued 11s
created

ApiAuth::checkRefreshToken()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 5
c 2
b 0
f 0
dl 0
loc 10
rs 10
cc 2
nc 2
nop 0
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.0.0
13
 */
14
15
namespace Quantum\Libraries\Auth;
16
17
use Quantum\Exceptions\ExceptionMessages;
18
use Quantum\Exceptions\AuthException;
19
use Quantum\Libraries\JWToken\JWToken;
20
use Quantum\Libraries\Hasher\Hasher;
21
use Quantum\Http\Response;
22
use Quantum\Http\Request;
23
24
/**
25
 * Class ApiAuth
26
 * @package Quantum\Libraries\Auth
27
 */
28
class ApiAuth extends BaseAuth implements AuthenticableInterface
29
{
30
31
    /**
32
     * @var JWToken
33
     */
34
    protected $jwt;
35
36
    /**
37
     * @var Hasher
38
     */
39
    protected $hasher;
40
41
    /**
42
     * @var AuthServiceInterface
43
     */
44
    protected $authService;
45
46
    /**
47
     * @var array
48
     */
49
    protected $keys = [];
50
51
    /**
52
     * @var string
53
     */
54
    protected $authUserKey = 'auth_user';
55
56
    /**
57
     * ApiAuth constructor.
58
     * @param AuthServiceInterface $authService
59
     * @param Hasher $hasher
60
     * @param JWToken|null $jwt
61
     */
62
    public function __construct(AuthServiceInterface $authService, Hasher $hasher, JWToken $jwt = null)
63
    {
64
        $this->jwt = $jwt;
65
        $this->hasher = $hasher;
66
        $this->authService = $authService;
67
        $this->keys = $this->authService->getDefinedKeys();
68
    }
69
70
    /**
71
     * Sign In
72
     * @param string $username
73
     * @param string $password
74
     * @return array
75
     * @throws AuthException
76
     */
77
    public function signin($mailer, $username, $password)
78
    {
79
        $user = $this->authService->get($this->keys['usernameKey'], $username);
80
81
        if (empty($user)) {
82
            throw new AuthException(ExceptionMessages::INCORRECT_AUTH_CREDENTIALS);
83
        }
84
85
        if (!$this->hasher->check($password, $user[$this->keys['passwordKey']])) {
86
            throw new AuthException(ExceptionMessages::INCORRECT_AUTH_CREDENTIALS);
87
        }
88
        if (!$this->isActivated($user)) {
89
            throw new AuthException(ExceptionMessages::INACTIVE_ACCOUNT);
90
        }
91
92
        if (config()->get('two_step_verification')) {
93
94
           $user = $this->towStepVerification($mailer, $user);
95
        }
96
97
        $tokens = $this->setUpdatedTokens($user);
98
99
        return $tokens;
100
    }
101
102
    /**
103
     * Sign Out
104
     * @return bool|mixed
105
     */
106
    public function signout()
107
    {
108
        $refreshToken = Request::getHeader($this->keys['refreshTokenKey']);
109
110
        $user = $this->authService->get($this->keys['refreshTokenKey'], $refreshToken);
111
112
        if (!empty($user)) {
113
            $this->authService->update(
114
                    $this->keys['refreshTokenKey'],
115
                    $refreshToken,
116
                    [
117
                        $this->authUserKey => $user,
118
                        $this->keys['refreshTokenKey'] => ''
119
                    ]
120
            );
121
122
            Request::deleteHeader($this->keys['refreshTokenKey']);
123
            Request::deleteHeader('Authorization');
124
            Response::delete('tokens');
125
126
            return true;
127
        }
128
129
        return false;
130
    }
131
132
    /**
133
     * User
134
     * @return mixed|null
135
     */
136
    public function user()
137
    {
138
        try {
139
            $accessToken = base64_decode(Request::getAuthorizationBearer());
140
            return (object) $this->jwt->retrieve($accessToken)->fetchData();
141
        } catch (\Exception $e) {
142
            if (Request::hasHeader($this->keys['refreshTokenKey'])) {
143
                $user = $this->checkRefreshToken();
144
                if ($user) {
145
                    return $this->user();
146
                }
147
            }
148
            return null;
149
        }
150
    }
151
152
    /**
153
     * Get Updated Tokens
154
     * @param object $user
155
     * @return array
156
     */
157
    public function getUpdatedTokens(array $user)
158
    {
159
        return [
160
            $this->keys['refreshTokenKey'] => $this->generateToken(),
161
            $this->keys['accessTokenKey'] => base64_encode($this->jwt->setData($this->filterFields($user))->compose())
162
        ];
163
    }
164
165
    /**
166
     * Verify
167
     * @param int $code
168
     * @return array
169
     * @throws \Exception
170
     */
171
    public function verify($code)
172
    {
173
        $user = (array) $this->user();
174
175
        if ($code != $user[$this->keys['verificationCode']]) {
176
            throw new AuthException(ExceptionMessages::INCORRECT_VERIFICATION_CODE);
177
        }
178
179
        $this->authService->update($this->keys['usernameKey'], $user[$this->keys['usernameKey']], [
180
            $this->keys['verificationCode'] => null
181
        ]);
182
183
        $user['verification_code'] = null;
184
185
        $tokens = $this->setUpdatedTokens($user);
186
187
        return $tokens;
188
    }
189
190
    /**
191
     * Check Refresh Token
192
     * @return bool|mixed
193
     */
194
    protected function checkRefreshToken()
195
    {
196
        $user = $this->authService->get($this->keys['refreshTokenKey'], Request::getHeader($this->keys['refreshTokenKey']));
197
198
        if (!empty($user)) {
199
            $this->setUpdatedTokens($user);
200
            return $user;
201
        }
202
203
        return false;
204
    }
205
206
    /**
207
     * Set Updated Tokens
208
     * @param array $user
209
     * @return array
210
     */
211
    protected function setUpdatedTokens(array $user)
212
    {
213
        $tokens = $this->getUpdatedTokens($user);
214
215
        $this->authService->update(
216
                $this->keys['usernameKey'],
217
                $user[$this->keys['usernameKey']],
218
                [
219
                    $this->authUserKey => $user,
220
                    $this->keys['refreshTokenKey'] => $tokens[$this->keys['refreshTokenKey']]
221
                ]
222
        );
223
224
        Request::setHeader($this->keys['refreshTokenKey'], $tokens[$this->keys['refreshTokenKey']]);
225
        Request::setHeader('Authorization', 'Bearer ' . $tokens[$this->keys['accessTokenKey']]);
226
        Response::set('tokens', $tokens);
227
228
        return $tokens;
229
    }
230
231
}
232