Completed
Push — master ( 336a9b...8f9e8c )
by Antonio Carlos
01:54 queued 11s
created

Authenticator   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 92.86%

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 9
dl 0
loc 153
ccs 39
cts 42
cp 0.9286
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A boot() 0 6 1
A bootStateless() 0 8 1
A fireLoginEvent() 0 10 2
A getOneTimePassword() 0 14 4
A isAuthenticated() 0 4 2
A canPassWithoutCheckingOTP() 0 8 4
A checkOTP() 0 19 4
A verifyOneTimePassword() 0 4 1
1
<?php
2
3
namespace PragmaRX\Google2FALaravel\Support;
4
5
use Illuminate\Http\Request as IlluminateRequest;
6
use PragmaRX\Google2FALaravel\Events\EmptyOneTimePasswordReceived;
7
use PragmaRX\Google2FALaravel\Events\LoginFailed;
8
use PragmaRX\Google2FALaravel\Events\LoginSucceeded;
9
use PragmaRX\Google2FALaravel\Exceptions\InvalidOneTimePassword;
10
use PragmaRX\Google2FALaravel\Google2FA;
11
12
class Authenticator extends Google2FA
13
{
14
    use ErrorBag;
15
    use Input;
16
    use Response;
17
    use Session;
18
    /**
19
     * The current password.
20
     *
21
     * @var
22
     */
23
    protected $password;
24
25
    /**
26
     * Authenticator constructor.
27
     *
28
     * @param \Illuminate\Http\Request $request
29
     */
30 9
    public function __construct(IlluminateRequest $request)
31
    {
32 9
        parent::__construct($request);
33 9
    }
34
35
    /**
36
     * Authenticator boot.
37
     *
38
     * @param $request
39
     *
40
     * @return Google2FA
41
     */
42 9
    public function boot($request)
43
    {
44 9
        parent::boot($request);
45
46 9
        return $this;
47
    }
48
49
    /**
50
     * Authenticator boot for API usage.
51
     *
52
     * @param $request
53
     *
54
     * @return Google2FA
55
     */
56 1
    public function bootStateless($request)
57
    {
58 1
        $this->boot($request);
59
60 1
        $this->setStateless();
61
62 1
        return $this;
63
    }
64
65
    /**
66
     * Fire login (success or failed).
67
     *
68
     * @param $succeeded
69
     */
70 5
    private function fireLoginEvent($succeeded)
71
    {
72 5
        event(
73 5
            $succeeded
74 4
                ? new LoginSucceeded($this->getUser())
75 5
                : new LoginFailed($this->getUser())
76
        );
77
78 5
        return $succeeded;
79
    }
80
81
    /**
82
     * Get the OTP from user input.
83
     *
84
     * @throws InvalidOneTimePassword
85
     *
86
     * @return mixed
87
     */
88 5
    protected function getOneTimePassword()
89
    {
90 5
        $password = $this->getInputOneTimePassword();
91
92 5
        if (is_null($password) || empty($password)) {
93
            event(new EmptyOneTimePasswordReceived());
94
95
            if ($this->config('throw_exceptions', true)) {
96
                throw new InvalidOneTimePassword(config('google2fa.error_messages.cannot_be_empty'));
97
            }
98
        }
99
100 5
        return $password;
101
    }
102
103
    /**
104
     * Check if the current use is authenticated via OTP.
105
     *
106
     * @return bool
107
     */
108 9
    public function isAuthenticated()
109
    {
110 9
        return $this->canPassWithoutCheckingOTP() || ($this->checkOTP() === Constants::OTP_VALID);
111
    }
112
113
    /**
114
     * Check if it is already logged in or passable without checking for an OTP.
115
     *
116
     * @return bool
117
     */
118 9
    protected function canPassWithoutCheckingOTP()
119
    {
120
        return
121 9
            !$this->isEnabled() ||
122 9
            $this->noUserIsAuthenticated() ||
123 9
            !$this->isActivated() ||
124 9
            $this->twoFactorAuthStillValid();
125
    }
126
127
    /**
128
     * Check if the input OTP is valid. Returns one of the possible OTP_STATUS codes:
129
     * 'empty', 'valid' or 'invalid'.
130
     *
131
     * @return string
132
     */
133 9
    protected function checkOTP()
134
    {
135 9
        if (!$this->inputHasOneTimePassword() || empty($this->getInputOneTimePassword())) {
136 7
            return Constants::OTP_EMPTY;
137
        }
138
139 5
        $isValid = $this->verifyOneTimePassword();
140
141 5
        if ($isValid) {
142 4
            $this->login();
143 4
            $this->fireLoginEvent($isValid);
144
145 4
            return Constants::OTP_VALID;
146
        }
147
148 1
        $this->fireLoginEvent($isValid);
149
150 1
        return Constants::OTP_INVALID;
151
    }
152
153
    /**
154
     * Verify the OTP.
155
     *
156
     * @throws InvalidOneTimePassword
157
     *
158
     * @return mixed
159
     */
160 5
    protected function verifyOneTimePassword()
161
    {
162 5
        return $this->verifyAndStoreOneTimePassword($this->getOneTimePassword());
163
    }
164
}
165