GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Issues (724)

app/Http/Controllers/Auth/TwoFactorController.php (8 issues)

1
<?php
2
/**
3
 * TwoFactorController.php
4
 * Copyright (c) 2019 [email protected]
5
 *
6
 * This file is part of Firefly III (https://github.com/firefly-iii).
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as
10
 * published by the Free Software Foundation, either version 3 of the
11
 * License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
declare(strict_types=1);
22
23
namespace FireflyIII\Http\Controllers\Auth;
24
25
use FireflyIII\Http\Controllers\Controller;
26
use FireflyIII\User;
27
use Illuminate\Http\RedirectResponse;
28
use Illuminate\Http\Request;
29
use Illuminate\Routing\Redirector;
30
use PragmaRX\Google2FALaravel\Support\Authenticator;
31
use Preferences;
32
33
/**
34
 * Class TwoFactorController.
35
 */
36
class TwoFactorController extends Controller
37
{
38
    /**
39
     * What to do if 2FA lost?
40
     *
41
     * @return mixed
42
     */
43
    public function lostTwoFactor()
44
    {
45
        /** @var User $user */
46
        $user      = auth()->user();
47
        $siteOwner = config('firefly.site_owner');
48
        $title     = (string) trans('firefly.two_factor_forgot_title');
49
50
        return view('auth.lost-two-factor', compact('user', 'siteOwner', 'title'));
51
    }
52
53
    /**
54
     * @param Request $request
55
     *
56
     * @return RedirectResponse|Redirector
57
     */
58
    public function submitMFA(Request $request)
59
    {
60
        /** @var array $mfaHistory */
61
        $mfaHistory = Preferences::get('mfa_history', [])->data;
0 ignored issues
show
Bug Best Practice introduced by
The method FireflyIII\Support\Facades\Preferences::get() is not static, but was called statically. ( Ignorable by Annotation )

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

61
        $mfaHistory = Preferences::/** @scrutinizer ignore-call */ get('mfa_history', [])->data;
Loading history...
62
        $mfaCode    = $request->get('one_time_password');
63
64
        // is in history? then refuse to use it.
65
        if ($this->inMFAHistory($mfaCode, $mfaHistory)) {
66
            $this->filterMFAHistory();
67
            session()->flash('error', trans('firefly.wrong_mfa_code'));
68
69
            return redirect(route('home'));
70
        }
71
72
        /** @var Authenticator $authenticator */
73
        $authenticator = app(Authenticator::class)->boot($request);
74
75
        if ($authenticator->isAuthenticated()) {
76
            // save MFA in preferences
77
            $this->addToMFAHistory($mfaCode);
78
79
            // otp auth success!
80
            return redirect(route('home'));
81
        }
82
83
        // could be user has a backup code.
84
        if ($this->isBackupCode($mfaCode)) {
85
            $this->removeFromBackupCodes($mfaCode);
86
            $authenticator->login();
87
88
            session()->flash('info', trans('firefly.mfa_backup_code'));
89
90
            return redirect(route('home'));
91
        }
92
93
        session()->flash('error', trans('firefly.wrong_mfa_code'));
94
95
        return redirect(route('home'));
96
    }
97
98
    /**
99
     * @param string $mfaCode
100
     */
101
    private function addToMFAHistory(string $mfaCode): void
102
    {
103
        /** @var array $mfaHistory */
104
        $mfaHistory   = Preferences::get('mfa_history', [])->data;
0 ignored issues
show
Bug Best Practice introduced by
The method FireflyIII\Support\Facades\Preferences::get() is not static, but was called statically. ( Ignorable by Annotation )

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

104
        $mfaHistory   = Preferences::/** @scrutinizer ignore-call */ get('mfa_history', [])->data;
Loading history...
105
        $entry        = [
106
            'time' => time(),
107
            'code' => $mfaCode,
108
        ];
109
        $mfaHistory[] = $entry;
110
111
        Preferences::set('mfa_history', $mfaHistory);
0 ignored issues
show
Bug Best Practice introduced by
The method FireflyIII\Support\Facades\Preferences::set() is not static, but was called statically. ( Ignorable by Annotation )

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

111
        Preferences::/** @scrutinizer ignore-call */ 
112
                     set('mfa_history', $mfaHistory);
Loading history...
112
        $this->filterMFAHistory();
113
    }
114
115
    /**
116
     * Remove old entries from the preferences array.
117
     */
118
    private function filterMFAHistory(): void
119
    {
120
        /** @var array $mfaHistory */
121
        $mfaHistory = Preferences::get('mfa_history', [])->data;
0 ignored issues
show
Bug Best Practice introduced by
The method FireflyIII\Support\Facades\Preferences::get() is not static, but was called statically. ( Ignorable by Annotation )

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

121
        $mfaHistory = Preferences::/** @scrutinizer ignore-call */ get('mfa_history', [])->data;
Loading history...
122
        $newHistory = [];
123
        $now        = time();
124
        foreach ($mfaHistory as $entry) {
125
            $time = $entry['time'];
126
            $code = $entry['code'];
127
            if ($now - $time <= 300) {
128
                $newHistory[] = [
129
                    'time' => $time,
130
                    'code' => $code,
131
                ];
132
            }
133
        }
134
        Preferences::set('mfa_history', $newHistory);
0 ignored issues
show
Bug Best Practice introduced by
The method FireflyIII\Support\Facades\Preferences::set() is not static, but was called statically. ( Ignorable by Annotation )

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

134
        Preferences::/** @scrutinizer ignore-call */ 
135
                     set('mfa_history', $newHistory);
Loading history...
135
    }
136
137
    /**
138
     * Each MFA history has a timestamp and a code, saving the MFA entries for 5 minutes. So if the
139
     * submitted MFA code has been submitted in the last 5 minutes, it won't work despite being valid.
140
     *
141
     * @param string $mfaCode
142
     * @param array  $mfaHistory
143
     *
144
     * @return bool
145
     */
146
    private function inMFAHistory(string $mfaCode, array $mfaHistory): bool
147
    {
148
        $now = time();
149
        foreach ($mfaHistory as $entry) {
150
            $time = $entry['time'];
151
            $code = $entry['code'];
152
            if ($code === $mfaCode && $now - $time <= 300) {
153
                return true;
154
            }
155
        }
156
157
        return false;
158
    }
159
160
    /**
161
     * Checks if code is in users backup codes.
162
     *
163
     * @param string $mfaCode
164
     *
165
     * @return bool
166
     */
167
    private function isBackupCode(string $mfaCode): bool
168
    {
169
        $list = Preferences::get('mfa_recovery', [])->data;
0 ignored issues
show
Bug Best Practice introduced by
The method FireflyIII\Support\Facades\Preferences::get() is not static, but was called statically. ( Ignorable by Annotation )

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

169
        $list = Preferences::/** @scrutinizer ignore-call */ get('mfa_recovery', [])->data;
Loading history...
170
        if (in_array($mfaCode, $list, true)) {
171
            return true;
172
        }
173
174
        return false;
175
    }
176
177
    /**
178
     * Remove the used code from the list of backup codes.
179
     *
180
     * @param string $mfaCode
181
     */
182
    private function removeFromBackupCodes(string $mfaCode): void
183
    {
184
        $list    = Preferences::get('mfa_recovery', [])->data;
0 ignored issues
show
Bug Best Practice introduced by
The method FireflyIII\Support\Facades\Preferences::get() is not static, but was called statically. ( Ignorable by Annotation )

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

184
        $list    = Preferences::/** @scrutinizer ignore-call */ get('mfa_recovery', [])->data;
Loading history...
185
        $newList = array_values(array_diff($list, [$mfaCode]));
186
        Preferences::set('mfa_recovery', $newList);
0 ignored issues
show
Bug Best Practice introduced by
The method FireflyIII\Support\Facades\Preferences::set() is not static, but was called statically. ( Ignorable by Annotation )

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

186
        Preferences::/** @scrutinizer ignore-call */ 
187
                     set('mfa_recovery', $newList);
Loading history...
187
    }
188
}
189