Test Failed
Push — master ( 06feab...820423 )
by Ashish
02:16
created

TwoFactorAuthenticationController::__construct()   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\Http\Controllers;
4
5
use App\Http\Controllers\Controller;
6
use App\User;
7
use Base32\Base32;
8
use Illuminate\Http\Request;
9
use Illuminate\Support\Facades\Schema;
10
use OTPHP\TOTP;
11
use Thecodework\TwoFactorAuthentication\AuthenticatesUsersWith2FA;
12
use Thecodework\TwoFactorAuthentication\Contracts\TwoFactorAuthenticationInterface;
13
use Thecodework\TwoFactorAuthentication\Exceptions\TwoFactorAuthenticationExceptions;
14
use Thecodework\TwoFactorAuthentication\TwoFactorAuthenticationServiceProvider;
15
16
class TwoFactorAuthenticationController extends Controller implements TwoFactorAuthenticationInterface
17
{
18
    use AuthenticatesUsersWith2FA;
19
20
    /**
21
     * User Model
22
     */
23
    protected $userModel;
24
25
    /**
26
     * Assigns $usersModel Property a Model instance.
27
     */
28
    public function __construct()
29
    {
30
        $this->userModel = TwoFactorAuthenticationServiceProvider::getUserModelInstance();
31
    }
32
    /**
33
     * Setup two factor authentication.
34
     *
35
     * @param \Illuminate\Http\Request
36
     * @param \Illuminate\Http\Response
37
     * @throws \Thecodework\TwoFactorAuthentications\Exceptions\TwoFactorAuthenticationExceptions
38
     */
39
    public function setupTwoFactorAuthentication(Request $request)
40
    {
41
        $user = $this->userModel->find($request->user()->id);
42
        if (!Schema::hasColumn(config('2fa-config.table'), 'two_factor_secret_key') ||
43
            !Schema::hasColumn(config('2fa-config.table'), 'is_two_factor_enabled')) {
44
            throw TwoFactorAuthenticationExceptions::columnNotFound();
45
        }
46
        $user->two_factor_secret_key = $user->two_factor_secret_key ?? $this->base32EncodedString(config('2fa-config.number_of_digits'));
47
        $user->update();
48
49
        $totp = new TOTP(
50
            config('2fa-config.account_name'),
51
            $user->two_factor_secret_key,
52
            10,
53
            config('2fa-config.digest_algorithm'),
54
            config('2fa-config.number_of_digits')
55
        );
56
57
        $barcode = $totp->getQrCodeUri();
58
59
        // Return Barcode image if ajax Request
60
        if ($request->ajax()) {
61
            return $barcode;
62
        }
63
64
        return view('2fa::setup', compact('barcode', 'user'));
65
    }
66
67
    /**
68
     * Disable 2FA.
69
     *
70
     * @param \Illuminate\Http\Request
71
     *
72
     * @return mixed
73
     */
74 View Code Duplication
    public function enableTwoFactorAuthentication(Request $request)
75
    {
76
        $user                        = $this->userModel->find($request->user()->id);
77
        $user->is_two_factor_enabled = 1;
78
        $user->update();
79
80
        if ($request->ajax()) {
81
            return [
82
                'data' => [
83
                    'message'     => 'success',
84
                    'description' => '2FA Enabled',
85
                ],
86
            ];
87
        }
88
89
        return redirect('home');
90
    }
91
92
    /**
93
     * Enable 2FA.
94
     *
95
     * @param \Illuminate\Http\Request
96
     *
97
     * @return mixed
98
     */
99 View Code Duplication
    public function disableTwoFactorAuthentication(Request $request)
100
    {
101
        $user                        = $this->userModel->find($request->user()->id);
102
        $user->is_two_factor_enabled = 0;
103
        $user->two_factor_secret_key = null;
104
        $user->update();
105
106
        if ($request->ajax()) {
107
            return [
108
                'data' => [
109
                    'message'     => 'success',
110
                    'description' => '2FA Disabled',
111
                ],
112
            ];
113
        }
114
115
        return redirect('home');
116
    }
117
118
    /**
119
     * Verify Two Factor Authentication.
120
     *
121
     * @param \Illuminate\Http\Request $request
122
     */
123
    public function verifyTwoFactorAuthentication(Request $request)
124
    {
125
        if ($request->session()->has('2fa:user:id')) {
126
            $secret    = getenv('HMAC_SECRET');
127
            $signature = hash_hmac('sha256', decrypt($request->session()->get('2fa:user:id')), $secret);
128
129
            if (md5($signature) !== md5($request->signature)) {
130
                return redirect()->intended('login');
131
            }
132
133
            return view('2fa::verify');
134
        }
135
136
        return redirect()->back(); //shoud be configurabel
137
    }
138
139
    /**
140
     * Encode Random String to 32 Base Transfer Encoding.
141
     *
142
     * @param int $length Length of the encoded string.
143
     *
144
     * @return string
145
     */
146
    private function base32EncodedString($length = 30):
147
    string {
148
        return Base32::encode($this->strRandom($length));
149
    }
150
151
    /**
152
     * Generate a more truly "random" alpha-numeric string.
153
     *
154
     * @param int $length
155
     *
156
     * @return string
157
     */
158
    private function strRandom($length = 30):
159
    string{
160
        $string = '';
161
162
        while (($len = strlen($string)) < $length) {
163
            $size = $length - $len;
164
165
            $bytes = random_bytes($size);
166
167
            $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
168
        }
169
170
        return $string;
171
    }
172
}
173