Make sure 2fa requirement is enforced (#1289)

This commit is contained in:
Boy132 2025-04-23 16:03:10 +02:00 committed by GitHub
parent 914e215bc0
commit 544aaab960
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 29 additions and 14 deletions

View File

@ -5,6 +5,9 @@ namespace App\Http\Middleware;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Exceptions\Http\TwoFactorAuthRequiredException;
use App\Filament\Pages\Auth\EditProfile;
use App\Livewire\AlertBanner;
use App\Models\User;
class RequireTwoFactorAuthentication
{
@ -14,11 +17,6 @@ class RequireTwoFactorAuthentication
public const LEVEL_ALL = 2;
/**
* The route to redirect a user to enable 2FA.
*/
protected string $redirectRoute = '/account';
/**
* Check the user state on the incoming request to determine if they should be allowed to
* proceed or not. This checks if the Panel is configured to require 2FA on an account in
@ -29,31 +27,37 @@ class RequireTwoFactorAuthentication
*/
public function handle(Request $request, \Closure $next): mixed
{
/** @var ?User $user */
$user = $request->user();
$uri = rtrim($request->getRequestUri(), '/') . '/';
$current = $request->route()->getName();
if (!$user || Str::startsWith($uri, ['/auth/']) || Str::startsWith($current, ['auth.', 'account.'])) {
if (!$user || Str::startsWith($uri, ['/auth/', '/profile']) || Str::startsWith($current, ['auth.', 'account.', 'filament.app.auth.'])) {
return $next($request);
}
/** @var \App\Models\User $user */
$level = (int) config('panel.auth.2fa_required');
// If this setting is not configured, or the user is already using 2FA then we can just
// send them right through, nothing else needs to be checked.
//
// If the level is set as admin and the user is not an admin, pass them through as well.
if ($level === self::LEVEL_NONE || $user->use_totp) {
// If this setting is not configured, or the user is already using 2FA then we can just send them right through, nothing else needs to be checked.
return $next($request);
} elseif ($level === self::LEVEL_ADMIN && !$user->isRootAdmin()) {
} elseif ($level === self::LEVEL_ADMIN && !$user->isAdmin()) {
// If the level is set as admin and the user is not an admin, pass them through as well.
return $next($request);
}
// For API calls return an exception which gets rendered nicely in the API response.
// For API calls return an exception which gets rendered nicely in the API response...
if ($request->isJson() || Str::startsWith($uri, '/api/')) {
throw new TwoFactorAuthRequiredException();
}
return redirect()->to($this->redirectRoute);
// ... otherwise display banner and redirect to profile
AlertBanner::make('2fa_must_be_enabled')
->body(trans('auth.2fa_must_be_enabled'))
->warning()
->send();
return redirect(EditProfile::getUrl(['tab' => '-2fa-tab'], panel: 'app'));
}
}

View File

@ -5,6 +5,7 @@ namespace App\Providers\Filament;
use App\Filament\Pages\Auth\Login;
use App\Filament\Pages\Auth\EditProfile;
use App\Http\Middleware\LanguageMiddleware;
use App\Http\Middleware\RequireTwoFactorAuthentication;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
@ -72,6 +73,7 @@ class AdminPanelProvider extends PanelProvider
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
LanguageMiddleware::class,
RequireTwoFactorAuthentication::class,
])
->authMiddleware([
Authenticate::class,

View File

@ -4,6 +4,8 @@ namespace App\Providers\Filament;
use App\Filament\Pages\Auth\Login;
use App\Filament\Pages\Auth\EditProfile;
use App\Http\Middleware\LanguageMiddleware;
use App\Http\Middleware\RequireTwoFactorAuthentication;
use Filament\Facades\Filament;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\DisableBladeIconComponents;
@ -57,6 +59,8 @@ class AppPanelProvider extends PanelProvider
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
LanguageMiddleware::class,
RequireTwoFactorAuthentication::class,
])
->authMiddleware([
Authenticate::class,

View File

@ -7,6 +7,8 @@ use App\Filament\Pages\Auth\Login;
use App\Filament\Admin\Resources\ServerResource\Pages\EditServer;
use App\Filament\Pages\Auth\EditProfile;
use App\Http\Middleware\Activity\ServerSubject;
use App\Http\Middleware\LanguageMiddleware;
use App\Http\Middleware\RequireTwoFactorAuthentication;
use App\Models\Server;
use Filament\Facades\Filament;
use Filament\Http\Middleware\Authenticate;
@ -79,6 +81,8 @@ class ServerPanelProvider extends PanelProvider
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
LanguageMiddleware::class,
RequireTwoFactorAuthentication::class,
ServerSubject::class,
])
->authMiddleware([

View File

@ -18,5 +18,6 @@ return [
'two-factor-code' => 'Two Factor Code',
'password' => 'The provided password is incorrect.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
'2fa_must_be_enabled' => 'The administrator has required that 2-Factor Authentication must be enabled for your account in order to use the Panel.',
];