Passed
Push — task/laravel-breadcrumbs ( 3beccb...a96280 )
by Yonathan
10:46 queued 10s
created

TwoFactorController::confirm()   B

Complexity

Conditions 9
Paths 9

Size

Total Lines 50
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 34
dl 0
loc 50
rs 8.0555
c 0
b 0
f 0
cc 9
nc 9
nop 1
1
<?php
2
3
namespace App\Http\Controllers\Auth;
4
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Facades\Cookie;
7
use Facades\App\Services\WhichPortal;
8
use Illuminate\Support\Facades\Lang;
9
use PragmaRX\Google2FALaravel\Support\Authenticator;
10
11
class TwoFactorController extends AuthController
12
{
13
    public function activate(Request $request)
1 ignored issue
show
Coding Style Documentation introduced by
Missing doc comment for function activate()
Loading history...
14
    {
15
        $user = $request->user();
16
        $google2fa = app('pragmarx.google2fa');
17
        $secret = $google2fa->generateSecretKey();
0 ignored issues
show
Bug introduced by
The method generateSecretKey() does not exist on Illuminate\Contracts\Foundation\Application. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

17
        /** @scrutinizer ignore-call */ 
18
        $secret = $google2fa->generateSecretKey();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
18
        $qrImage = $google2fa->getQRCodeInline(
0 ignored issues
show
Bug introduced by
The method getQRCodeInline() does not exist on Illuminate\Contracts\Foundation\Application. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

18
        /** @scrutinizer ignore-call */ 
19
        $qrImage = $google2fa->getQRCodeInline(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
19
            config('app.name'),
20
            $user->email,
21
            $secret
22
        );
23
            $profile_url = '';
24
        if (WhichPortal::isApplicantPortal()) {
25
            $profile_url = route('settings.edit');
26
        } elseif (WhichPortal::isManagerPortal()) {
27
            $profile_url = route('manager.settings.edit');
28
        } elseif (WhichPortal::isAdminPortal()) {
29
            $profile_url = backpack_url('2fa');
30
        }
31
32
        return view('auth.two_factor', [
33
            'qr_image' => $qrImage,
34
            'secret' => $secret,
35
            'profile_url' => $profile_url,
36
        ]);
37
    }
38
39
    public function deactivate(Request $request)
1 ignored issue
show
Coding Style Documentation introduced by
Missing doc comment for function deactivate()
Loading history...
40
    {
41
        $user = $request->user();
42
        $user->google2fa_secret = null;
43
        $user->recovery_codes = null;
44
        $user->save();
45
        $user->refresh();
46
47
        $profile_url = '';
48
        if (WhichPortal::isApplicantPortal()) {
49
            $profile_url = route('settings.edit');
50
        } elseif (WhichPortal::isManagerPortal()) {
51
            $profile_url = route('manager.settings.edit');
52
        } elseif (WhichPortal::isAdminPortal()) {
53
            $profile_url = backpack_url('2fa');
54
        }
55
56
        return redirect($profile_url)->withSuccess(Lang::get('success.two_factor_deactivate'));
57
    }
58
59
    public function confirm(Request $request)
1 ignored issue
show
Coding Style Documentation introduced by
Missing doc comment for function confirm()
Loading history...
60
    {
61
        $user = $request->user();
62
        $validatedData = $request->validate([
63
            'secret' => 'required|string',
64
            'one_time_password' => 'required|string',
65
        ]);
66
        $secret = $validatedData['secret'];
67
        $one_time_password = $validatedData['one_time_password'];
68
69
        // A 2fa secret is already set up, no need to do anything.
70
        if (!empty($user->google2fa_secret)) {
71
            return redirect()->route('home');
72
        }
73
74
        // Check that the one time password matches the secret.
75
        $authenticator = app(Authenticator::class)->boot($request);
76
        $isCorrect = $authenticator->verifyGoogle2FA($secret, $one_time_password);
77
78
        if ($isCorrect) {
79
            // The password matched the secret! Save the secret, and authenticate.
80
            $user->google2fa_secret = $secret;
81
            $user->save();
82
            $user->refresh();
83
            $authenticator->login();
84
85
            $this->rememberDevice($request);
86
87
            $recovery_codes_url = '';
88
            if (WhichPortal::isApplicantPortal()) {
89
                $recovery_codes_url = route('recovery_codes.show');
90
            } elseif (WhichPortal::isManagerPortal()) {
91
                $recovery_codes_url = route('manager.recovery_codes.show');
92
            } elseif (WhichPortal::isAdminPortal()) {
93
                $recovery_codes_url = route('admin.recovery_codes.show');
94
            }
95
96
            return redirect($recovery_codes_url);
97
        } else {
98
            $activation_url = '';
99
            if (WhichPortal::isApplicantPortal()) {
100
                $activation_url = route('two_factor.activate');
101
            } elseif (WhichPortal::isManagerPortal()) {
102
                $activation_url = route('manager.two_factor.activate');
103
            } elseif (WhichPortal::isAdminPortal()) {
104
                $activation_url = backpack_url('admin.two_factor.activate');
105
            }
106
107
            return redirect($activation_url)
108
                ->withErrors(['otp' => Lang::get('two_factor.activation_otp_error')]);
109
        }
110
    }
111
112
    public function redirectToExpected(Request $request)
1 ignored issue
show
Coding Style Documentation introduced by
Missing doc comment for function redirectToExpected()
Loading history...
113
    {
114
        $this->rememberDevice($request);
115
        // Assuming 2fa passes, redirect to the expected url and remove it from session.
116
        // NOTE: the url.expected is set in app\Http\Middleware\Google2FA.php.
117
        $expectedUrl = session()->get('url.expected');
118
        session()->remove('url.expected');
119
120
        return redirect($expectedUrl);
121
    }
122
123
    protected function rememberDevice(Request $request)
1 ignored issue
show
Coding Style Documentation introduced by
Missing doc comment for function rememberDevice()
Loading history...
124
    {
125
        $user = $request->user();
126
        $remember = $request->input('remember_device');
127
128
        if ($remember) {
129
            if (empty($user->getRememberDeviceToken())) {
130
                $user->cycleRememberDeviceToken();
131
            }
132
            Cookie::queue(
133
                $user->getRememberDeviceKey(),
134
                $user->getRememberDeviceToken(),
135
                config('google2fa.lifetime')
136
            );
137
        }
138
    }
139
140
    protected function forget(Request $request)
1 ignored issue
show
Coding Style Documentation introduced by
Missing doc comment for function forget()
Loading history...
141
    {
142
        $user = $request->user();
143
        $user->cycleRememberDeviceToken();
144
        return redirect()->back()->withSuccess(Lang::get('success.two_factor_forget'));
145
    }
146
}
147