Passed
Pull Request — master (#34)
by
unknown
03:20
created

ApiAuth   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 194
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 17
eloc 67
c 4
b 0
f 0
dl 0
loc 194
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A signin() 0 23 5
A checkRefreshToken() 0 10 2
A getUpdatedTokens() 0 5 1
A verify() 0 13 1
A user() 0 13 4
A signout() 0 24 2
A setUpdatedTokens() 0 18 1
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('tow_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
     * @return array
168
     */
169
    public function verify()
170
    {
171
        $user = (array) $this->user();
172
173
        $this->authService->update($this->keys['usernameKey'], $user[$this->keys['usernameKey']], [
174
            $this->keys['verificationCode'] => null
175
        ]);
176
177
        $user['verification_code'] = null;
178
179
        $tokens = $this->setUpdatedTokens($user);
180
181
        return $tokens;
182
    }
183
184
    /**
185
     * Check Refresh Token
186
     * @return bool|mixed
187
     */
188
    protected function checkRefreshToken()
189
    {
190
        $user = $this->authService->get($this->keys['refreshTokenKey'], Request::getHeader($this->keys['refreshTokenKey']));
191
192
        if (!empty($user)) {
193
            $this->setUpdatedTokens($user);
194
            return $user;
195
        }
196
197
        return false;
198
    }
199
200
    /**
201
     * Set Updated Tokens
202
     * @param array $user
203
     */
204
    protected function setUpdatedTokens(array $user)
205
    {
206
        $tokens = $this->getUpdatedTokens($user);
207
208
        $this->authService->update(
209
                $this->keys['usernameKey'],
210
                $user[$this->keys['usernameKey']],
211
                [
212
                    $this->authUserKey => $user,
213
                    $this->keys['refreshTokenKey'] => $tokens[$this->keys['refreshTokenKey']]
214
                ]
215
        );
216
217
        Request::setHeader($this->keys['refreshTokenKey'], $tokens[$this->keys['refreshTokenKey']]);
218
        Request::setHeader('Authorization', 'Bearer ' . $tokens[$this->keys['accessTokenKey']]);
219
        Response::set('tokens', $tokens);
220
221
        return $tokens;
222
    }
223
224
}
225