Completed
Push — master ( 21c015...b85bcf )
by Antonio Carlos
07:14 queued 05:46
created

Google2FA::getOldTimestamp()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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