1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-28 17:02:04 +03:00

Added login redirect system to confirm/mfa

Also continued a bit on the MFA verification system.
Moved some MFA routes to public space using updated login service to get
the current user that is either logged in or last attempted login (With
correct creds).
This commit is contained in:
Dan Brown
2021-07-18 16:52:31 +01:00
parent 1278fb4969
commit 1af5bbf3f7
11 changed files with 186 additions and 37 deletions

View File

@ -47,12 +47,11 @@ class ConfirmEmailController extends Controller
/**
* Shows a notice that a user's email address has not been confirmed,
* Also has the option to re-send the confirmation email.
*
* @return View
*/
public function showAwaiting()
{
return view('auth.user-unconfirmed');
$user = $this->loginService->getLastLoginAttemptUser();
return view('auth.user-unconfirmed', ['user' => $user]);
}
/**

View File

@ -0,0 +1,22 @@
<?php
namespace BookStack\Http\Controllers\Auth;
use BookStack\Auth\Access\LoginService;
use BookStack\Auth\User;
use BookStack\Exceptions\NotFoundException;
trait HandlesPartialLogins
{
protected function currentOrLastAttemptedUser(): User
{
$loginService = app()->make(LoginService::class);
$user = auth()->user() ?? $loginService->getLastLoginAttemptUser();
if (!$user) {
throw new NotFoundException('A user for this action could not be found');
}
return $user;
}
}

View File

@ -10,6 +10,8 @@ use Exception;
class MfaBackupCodesController extends Controller
{
use HandlesPartialLogins;
protected const SETUP_SECRET_SESSION_KEY = 'mfa-setup-backup-codes';
/**
@ -39,7 +41,7 @@ class MfaBackupCodesController extends Controller
}
$codes = decrypt(session()->pull(self::SETUP_SECRET_SESSION_KEY));
MfaValue::upsertWithValue(user(), MfaValue::METHOD_BACKUP_CODES, json_encode($codes));
MfaValue::upsertWithValue($this->currentOrLastAttemptedUser(), MfaValue::METHOD_BACKUP_CODES, json_encode($codes));
$this->logActivity(ActivityType::MFA_SETUP_METHOD, 'backup-codes');
return redirect('/mfa/setup');

View File

@ -5,15 +5,19 @@ namespace BookStack\Http\Controllers\Auth;
use BookStack\Actions\ActivityType;
use BookStack\Auth\Access\Mfa\MfaValue;
use BookStack\Http\Controllers\Controller;
use BookStack\Http\Request;
class MfaController extends Controller
{
use HandlesPartialLogins;
/**
* Show the view to setup MFA for the current user.
*/
public function setup()
{
$userMethods = user()->mfaValues()
$userMethods = $this->currentOrLastAttemptedUser()
->mfaValues()
->get(['id', 'method'])
->groupBy('method');
return view('mfa.setup', [
@ -41,14 +45,26 @@ class MfaController extends Controller
/**
* Show the page to start an MFA verification.
*/
public function verify()
public function verify(Request $request)
{
$userMethods = user()->mfaValues()
// TODO - Test this
$desiredMethod = $request->get('method');
$userMethods = $this->currentOrLastAttemptedUser()
->mfaValues()
->get(['id', 'method'])
->groupBy('method');
// Basic search for the default option for a user.
// (Prioritises totp over backup codes)
$method = $userMethods->has($desiredMethod) ? $desiredMethod : $userMethods->keys()->sort()->reverse()->first();
$otherMethods = $userMethods->keys()->filter(function($userMethod) use ($method) {
return $method !== $userMethod;
})->all();
return view('mfa.verify', [
'userMethods' => $userMethods,
'method' => $method,
'otherMethods' => $otherMethods,
]);
}
}

View File

@ -6,12 +6,15 @@ use BookStack\Actions\ActivityType;
use BookStack\Auth\Access\Mfa\MfaValue;
use BookStack\Auth\Access\Mfa\TotpService;
use BookStack\Auth\Access\Mfa\TotpValidationRule;
use BookStack\Exceptions\NotFoundException;
use BookStack\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
class MfaTotpController extends Controller
{
use HandlesPartialLogins;
protected const SETUP_SECRET_SESSION_KEY = 'mfa-setup-totp-secret';
/**
@ -39,6 +42,7 @@ class MfaTotpController extends Controller
* Confirm the setup of TOTP and save the auth method secret
* against the current user.
* @throws ValidationException
* @throws NotFoundException
*/
public function confirm(Request $request)
{
@ -51,7 +55,7 @@ class MfaTotpController extends Controller
]
]);
MfaValue::upsertWithValue(user(), MfaValue::METHOD_TOTP, $totpSecret);
MfaValue::upsertWithValue($this->currentOrLastAttemptedUser(), MfaValue::METHOD_TOTP, $totpSecret);
session()->remove(static::SETUP_SECRET_SESSION_KEY);
$this->logActivity(ActivityType::MFA_SETUP_METHOD, 'totp');

View File

@ -140,9 +140,9 @@ class SocialController extends Controller
}
$user = $this->registrationService->registerUser($userData, $socialAccount, $emailVerified);
$this->showSuccessNotification(trans('auth.register_success'));
$this->loginService->login($user, $socialDriver);
$this->showSuccessNotification(trans('auth.register_success'));
return redirect('/');
}
}