Passed
Pull Request — master (#35)
by
unknown
01:55
created

WebAuth::user()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 7
c 3
b 0
f 0
dl 0
loc 11
rs 10
cc 4
nc 4
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\Hasher\Hasher;
20
use Quantum\Libraries\JWToken\JWToken;
21
use Quantum\Libraries\Mailer\Mailer;
22
23
/**
24
 * Class WebAuth
25
 * @package Quantum\Libraries\Auth
26
 */
27
class WebAuth extends BaseAuth implements AuthenticableInterface
28
{
29
30
    /**
31
     * @var Hasher
32
     */
33
    protected $hasher;
34
35
    /**
36
     * @var AuthServiceInterface
37
     */
38
    protected $authService;
39
40
    /**
41
     * @var array
42
     */
43
    protected $keys = [];
44
45
    /**
46
     * @var string
47
     */
48
    protected $authUserKey = 'auth_user';
49
50
    /**
51
     * WebAuth constructor.
52
     * @param AuthServiceInterface $authService
53
     * @param Hasher $hasher
54
     * @param JWToken|null $jwt
55
     */
56
    public function __construct(AuthServiceInterface $authService, Hasher $hasher, JWToken $jwt = null)
57
    {
58
        $this->hasher = $hasher;
59
        $this->authService = $authService;
60
        $this->keys = $this->authService->getDefinedKeys();
61
    }
62
63
    /**
64
     * Sign In
65
     * @param Mailer $mailer
66
     * @param string $username
67
     * @param string $password
68
     * @param boolean $remember
69
     * @return mixed|boolean
70
     * @throws AuthException
71
     */
72
    public function signin($mailer, $username, $password, $remember = false)
73
    {
74
        $user = $this->authService->get($this->keys['usernameKey'], $username);
75
76
        if (empty($user)) {
77
            throw new AuthException(ExceptionMessages::INCORRECT_AUTH_CREDENTIALS);
78
        }
79
80
        if (!$this->hasher->check($password, $user[$this->keys['passwordKey']])) {
81
            throw new AuthException(ExceptionMessages::INCORRECT_AUTH_CREDENTIALS);
82
        }
83
84
        if (!$this->isActivated($user)) {
85
            throw new AuthException(ExceptionMessages::INACTIVE_ACCOUNT);
86
        }
87
88
        if ($remember) {
89
            $this->setRememberToken($user);
90
        }
91
92
        if (filter_var(config()->get('2SV'), FILTER_VALIDATE_BOOLEAN)) {
93
94
            $otp_token = $this->generateOtpToken($user[$this->keys['usernameKey']]);
95
96
            $time = new \DateTime();
97
98
            $time->add(new \DateInterval('PT' . config()->get('otp_expiry_time') . 'M'));
99
100
            $otp_expiry_time = $time->format('Y-m-d H:i');
101
102
            $this->towStepVerification($mailer, $user, $otp_expiry_time, $otp_token);
103
104
            return $otp_token;
105
106
        } else {
107
108
            session()->set($this->authUserKey, $this->filterFields($user));
109
        }
110
111
        return true;
112
    }
113
114
    /**
115
     * Sign Out
116
     * @throws \Exception
117
     */
118
    public function signout()
119
    {
120
        if (session()->has($this->authUserKey)) {
121
            session()->delete($this->authUserKey);
122
            $this->removeRememberToken();
123
        }
124
    }
125
126
    /**
127
     * User
128
     * @return mixed|null
129
     * @throws \Exception
130
     */
131
    public function user()
132
    {
133
        if (session()->has($this->authUserKey)) {
134
            return (object) session()->get($this->authUserKey);
135
        } else if (cookie()->has($this->keys['rememberTokenKey'])) {
136
            $user = $this->checkRememberToken();
137
            if ($user) {
138
                return $this->user();
139
            }
140
        }
141
        return null;
142
    }
143
144
    /**
145
     * Verify
146
     * @param int $code
147
     * @return bool
148
     * @throws \Exception
149
     */
150
151
    public function verify($code, $otp_token)
152
    {
153
        $user = $this->authService->get($this->keys['otpToken'], $otp_token);
154
155
        if (new \DateTime() >= new \DateTime($user[$this->keys['otpExpiryIn']])){
156
            throw new AuthException(ExceptionMessages::VERIFICATION_CODE_EXPIRY_IN);
157
        }
158
159
        if ($code != $user[$this->keys['otpKey']]) {
160
            throw new AuthException(ExceptionMessages::INCORRECT_VERIFICATION_CODE);
161
        }
162
163
        $this->authService->update($this->keys['usernameKey'], $user[$this->keys['usernameKey']], [
164
            $this->keys['otpKey'] => null,
165
            $this->keys['otpExpiryIn'] => null,
166
            $this->keys['otpToken'] => null,
167
        ]);
168
169
        $user = $this->authService->get($this->keys['usernameKey'], $user[$this->keys['usernameKey']]);
170
171
        session()->set($this->authUserKey, $this->filterFields($user));
172
173
        return true;
174
    }
175
176
    /**
177
     * Resend Otp
178
     * @param Mailer $mailer
179
     * @param string $otp_token
180
     * @return bool|mixed
181
     * @throws \Exception
182
     */
183
184
    public function resendOtp($mailer, $otp_token)
185
    {
186
        $user = $this->authService->get($this->keys['otpToken'], $otp_token);
187
188
        if (empty($user)) {
189
190
            return false;
191
        }
192
193
        $otp_token = $this->generateOtpToken($user[$this->keys['usernameKey']]);
194
195
        $time = new \DateTime();
196
197
        $time->add(new \DateInterval('PT' . config()->get('otp_expiry_time') . 'M'));
198
199
        $stamp = $time->format('Y-m-d H:i');
200
201
        $this->towStepVerification($mailer, $user, $stamp, $otp_token);
202
203
        return $otp_token;
204
    }
205
206
    /**
207
     * Check Remember Token
208
     * @return bool|mixed
209
     * @throws \Exception
210
     */
211
    private function checkRememberToken()
212
    {
213
        $user = $this->authService->get($this->keys['rememberTokenKey'], cookie()->get($this->keys['rememberTokenKey']));
214
        if (!empty($user)) {
215
            $this->setRememberToken($user);
216
            return $user;
217
        }
218
        return false;
219
    }
220
221
    /**
222
     * Set Remember Token
223
     * @param array $user
224
     * @throws \Exception
225
     */
226
    private function setRememberToken(array $user)
227
    {
228
        $rememberToken = $this->generateToken();
229
230
        $this->authService->update($this->keys['usernameKey'], $user[$this->keys['usernameKey']], [
231
            $this->keys['rememberTokenKey'] => $rememberToken
232
        ]);
233
234
        session()->set($this->authUserKey, $this->filterFields($user));
235
        cookie()->set($this->keys['rememberTokenKey'], $rememberToken);
236
    }
237
238
    /**
239
     * Remove Remember Token
240
     * @throws \Exception
241
     */
242
    private function removeRememberToken()
243
    {
244
        if (cookie()->has($this->keys['rememberTokenKey'])) {
245
            $user = $this->authService->get($this->keys['rememberTokenKey'], cookie()->get($this->keys['rememberTokenKey']));
246
247
            if (!empty($user)) {
248
                $this->authService->update($this->keys['rememberTokenKey'], $user[$this->keys['rememberTokenKey']], [
249
                    $this->keys['rememberTokenKey'] => ''
250
                ]);
251
            }
252
253
            cookie()->delete($this->keys['rememberTokenKey']);
254
        }
255
    }
256
}
257