Completed
Push — master ( e8eaa8...b17f45 )
by Antonio Carlos
06:15
created

Google2FA   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 210
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 25
c 1
b 0
f 0
lcom 1
cbo 6
dl 0
loc 210
rs 10

17 Methods

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