Passed
Push — master ( 4393f1...8816bb )
by Ashish
02:47
created

AuthenticatesUsersWith2FA::getUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Thecodework\TwoFactorAuthentication;
4
5
use Auth;
6
use Illuminate\Http\Request;
7
use OTPHP\TOTP;
8
use Validator;
9
10
trait AuthenticatesUsersWith2FA
11
{
12
    /*
13
     * Priveate variable to store user object.
14
     */
15
    private $user;
16
17
    /**
18
     * If username/password is authenticated then the authenticted.
19
     * If 2FA enabled it will redirect user to enter TOTP Token else
20
     * Logs the user in normally.
21
     *
22
     * @param \Illuminate\Http\Request $request
23
     * @param \App\User                $user
24
     *
25
     * @return \Illuminate\Http\RedirectResponse
26
     */
27
    protected function authenticated(Request $request, $user)
28
    {
29
        if ($user->is_two_factor_enabled) {
30
            $request->session()->put('2fa:user:id', encrypt($user->id));
31
            $secret = getenv('HMAC_SECRET');
32
            $signature = hash_hmac('sha256', $user->id, $secret);
33
            Auth::logout();
34
35
            return redirect()->intended('verify-2fa?signature=' . $signature);
36
        }
37
38
        return redirect()->intended(config('2fa-config.redirect_to'));
39
    }
40
41
    /**
42
     * Verify token and sign in the user.
43
     *
44
     * @param \Illuminate\Http\Request $request
45
     *
46
     * @return \Illuminate\Http\RedirectResponse
47
     */
48
    public function verifyToken(Request $request)
49
    {
50
        $TwoFAModel = TwoFactorAuthenticationServiceProvider::getTwoFAModelInstance();
51
        // Pulling encrypted user id from session and getting user details
52
        $userId = $request->session()->get('2fa:user:id');
53
        $this->user = $TwoFAModel->find(decrypt($userId));
54
55
        // If token is not valid then custom validation error message will be shown.
56
        $messages = [
57
            'totp_token.valid_token' => 'Token is not valid',
58
        ];
59
60
        // Impllicitly adding an validation rule to check if token is valid or not.
61
        Validator::extendImplicit('valid_token', function ($attribute, $value) {
62
            $totp = new TOTP(
63
                config('2fa-config.account_name'),
64
                $this->user->two_factor_secret_key
65
            );
66
67
            return $value == $totp->now();
68
        });
69
70
        // If Validation fails, it will return the error else sign in the user.
71
        $validator = Validator::make($request->all(), [
72
            'totp_token' => 'required|digits:6|valid_token',
73
        ], $messages);
74
75
        $secret = getenv('HMAC_SECRET');
76
        $signature = hash_hmac('sha256', $this->user->id, $secret);
77
        if ($validator->fails()) {
78
            return redirect('verify-2fa?signature=' . $signature)
79
                ->withErrors($validator)
80
                ->withInput();
81
        }
82
83
        // Flush the session.
84
        $request->session()->forget('2fa:user:id');
85
86
        Auth::loginUsingId($this->user->id);
87
88
        return redirect()->intended(config('2fa-config.redirect_to'));
89
    }
90
91
    public function setUser($user)
92
    {
93
        $this->user = $user;
94
    }
95
96
    public function getUser()
97
    {
98
        return $this->user;
99
    }
100
}
101