Completed
Push — master ( 241ec6...70b488 )
by Antonio Carlos
04:26
created

Google2FA::verifyAndStoreOneTimePassword()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 0
cts 4
cp 0
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace PragmaRX\Google2FALaravel;
4
5
use Carbon\Carbon;
6
use PragmaRX\Google2FALaravel\Support\Auth;
7
use PragmaRX\Google2FALaravel\Support\Config;
8
use PragmaRX\Google2FALaravel\Support\Request;
9
use PragmaRX\Google2FALaravel\Support\Session;
10
use PragmaRX\Google2FALaravel\Events\LoggedOut;
11
use PragmaRX\Google2FALaravel\Support\Constants;
12
use Illuminate\Http\Request as IlluminateRequest;
13
use PragmaRX\Google2FALaravel\Exceptions\InvalidSecretKey;
14
use PragmaRX\Google2FAQRCode\Google2FA as Google2FAService;
15
use PragmaRX\Google2FALaravel\Events\OneTimePasswordExpired;
16
use PragmaRX\Google2FA\Support\Constants as Google2FAConstants;
17
18
class Google2FA extends Google2FAService
19
{
20
    use Auth, Config, Request, Session;
21
22
    /**
23
     * Authenticator constructor.
24
     *
25
     * @param IlluminateRequest $request
26
     */
27
    public function __construct(IlluminateRequest $request)
28
    {
29
        $this->boot($request);
30
31
        parent::__construct();
32
    }
33
34
    /**
35
     * Authenticator boot.
36
     *
37
     * @param $request
38
     *
39
     * @return Google2FA
40
     */
41
    public function boot($request)
42
    {
43
        $this->setRequest($request);
44
45
        return $this;
46
    }
47
48
    /**
49
     * Get the user Google2FA secret.
50
     *
51
     * @throws InvalidSecretKey
52
     *
53
     * @return mixed
54
     */
55
    protected function getGoogle2FASecretKey()
56
    {
57
        return $this->getUser()->{$this->config('otp_secret_column')};
58
    }
59
60
    /**
61
     * Check if the 2FA is activated for the user.
62
     *
63
     * @return bool
64
     */
65
    public function isActivated()
66
    {
67
        $secret = $this->getGoogle2FASecretKey();
68
69
        return !is_null($secret) && !empty($secret);
70
    }
71
72
    /**
73
     * Store the old OTP timestamp.
74
     *
75
     * @param $key
76
     *
77
     * @return mixed
78
     */
79
    protected function storeOldTimestamp($key)
80
    {
81
        return $this->config('forbid_old_passwords') === true
82
            ? $this->sessionPut(Constants::SESSION_OTP_TIMESTAMP, $key)
83
            : $key;
84
    }
85
86
    /**
87
     * Get the previous OTP timestamp.
88
     *
89
     * @return null|mixed
90
     */
91
    protected function getOldTimestamp()
92
    {
93
        return $this->config('forbid_old_passwords') === true
94
            ? $this->sessionGet(Constants::SESSION_OTP_TIMESTAMP)
95
            : null;
96
    }
97
98
    /**
99
     * Keep this OTP session alive.
100
     */
101
    protected function keepAlive()
102
    {
103
        if ($this->config('keep_alive')) {
104
            $this->updateCurrentAuthTime();
105
        }
106
    }
107
108
    /**
109
     * Get minutes since last activity.
110
     *
111
     * @return int
112
     */
113
    protected function minutesSinceLastActivity()
114
    {
115
        return Carbon::now()->diffInMinutes(
116
            $this->sessionGet(Constants::SESSION_AUTH_TIME)
117
        );
118
    }
119
120
    /**
121
     * Check if no user is authenticated using OTP.
122
     *
123
     * @return bool
124
     */
125
    protected function noUserIsAuthenticated()
126
    {
127
        return is_null($this->getUser());
128
    }
129
130
    /**
131
     * Check if OTP has expired.
132
     *
133
     * @return bool
134
     */
135
    protected function passwordExpired()
136
    {
137
        if (($minutes = $this->config('lifetime')) !== 0 && $this->minutesSinceLastActivity() > $minutes) {
138
            event(new OneTimePasswordExpired($this->getUser()));
139
140
            $this->logout();
141
142
            return true;
143
        }
144
145
        $this->keepAlive();
146
147
        return false;
148
    }
149
150
    /**
151
     * Verifies, in the current session, if a 2fa check has already passed.
152
     *
153
     * @return bool
154
     */
155
    protected function twoFactorAuthStillValid()
156
    {
157
        return
158
            (bool) $this->sessionGet(Constants::SESSION_AUTH_PASSED, false) &&
159
            !$this->passwordExpired();
160
    }
161
162
    /**
163
     * Check if the module is enabled.
164
     *
165
     * @return mixed
166
     */
167
    protected function isEnabled()
168
    {
169
        return $this->config('enabled');
170
    }
171
172
    /**
173
     * Set current auth as valid.
174
     */
175
    public function login()
176
    {
177
        $this->sessionPut(Constants::SESSION_AUTH_PASSED, true);
178
179
        $this->updateCurrentAuthTime();
180
    }
181
182
    /**
183
     * OTP logout.
184
     */
185
    public function logout()
186
    {
187
        $user = $this->getUser();
188
189
        $this->sessionForget();
190
191
        event(new LoggedOut($user));
192
    }
193
194
    /**
195
     * Update the current auth time.
196
     */
197
    protected function updateCurrentAuthTime()
198
    {
199
        $this->sessionPut(Constants::SESSION_AUTH_TIME, Carbon::now());
200
    }
201
202
    /**
203
     * Verify the OTP.
204
     *
205
     * @param $secret
206
     * @param $one_time_password
207
     *
208
     * @return mixed
209
     */
210
    public function verifyGoogle2FA($secret, $one_time_password)
211
    {
212
        return $this->verifyKey(
213
                $secret,
214
                $one_time_password,
215
                $this->config('window'),
216
                null, // $timestamp
217
                $this->getOldTimestamp() ?: Google2FAConstants::ARGUMENT_NOT_SET
218
        );
219
    }
220
221
    /**
222
     * Verify the OTP and store the timestamp.
223
     *
224
     * @param $one_time_password
225
     *
226
     * @return mixed
227
     */
228
    protected function verifyAndStoreOneTimePassword($one_time_password)
229
    {
230
        return $this->storeOldTimeStamp(
231
            $this->verifyGoogle2FA(
232
                $this->getGoogle2FASecretKey(),
233
                $one_time_password
234
            )
235
        );
236
    }
237
}
238