Files
BookStack/app/Access/Controllers/OidcController.php
2026-04-20 11:48:04 -03:00

93 lines
2.7 KiB
PHP

<?php
namespace BookStack\Access\Controllers;
use BookStack\Access\Oidc\OidcException;
use BookStack\Access\Oidc\OidcService;
use BookStack\Http\Controller;
use Illuminate\Http\Request;
class OidcController extends Controller
{
public function __construct(
protected OidcService $oidcService
) {
$this->middleware('guard:oidc');
}
/**
* Start the authorization login flow via OIDC.
*/
public function login()
{
try {
$loginDetails = $this->oidcService->login();
} catch (OidcException $exception) {
$this->showErrorNotification($exception->getMessage());
return redirect('/login');
}
session()->put('oidc_state', time() . ':' . $loginDetails['state']);
return redirect($loginDetails['url']);
}
/**
* Authorization flow redirect callback.
* Processes authorization response from the OIDC Authorization Server.
*/
public function callback(Request $request)
{
$responseState = $request->query('state');
$splitState = explode(':', session()->pull('oidc_state', ':'), 2);
if (count($splitState) !== 2) {
$splitState = [null, null];
}
[$storedStateTime, $storedState] = $splitState;
$threeMinutesAgo = time() - 3 * 60;
if (!$storedState || $storedState !== $responseState || intval($storedStateTime) < $threeMinutesAgo) {
$this->showErrorNotification(trans('errors.oidc_fail_authed', ['system' => config('oidc.name')]));
return redirect('/login');
}
try {
$this->_catchCustomErrorAndFail($request);
$this->oidcService->processAuthorizeResponse($request->query('code'));
} catch (OidcException $oidcException) {
$this->showErrorNotification($oidcException->getMessage());
return redirect('/login');
}
return redirect()->intended();
}
/**
* Log the user out, then start the OIDC RP-initiated logout process.
*/
public function logout()
{
return redirect($this->oidcService->logout());
}
private function _catchCustomErrorAndFail(Request $request):void {
$_errorCode = $request->query('error');
if ($_errorCode) {
if ($_errorCode === 'need_auth') {
if ( null === ($errorMsg = $request->query('error_description')) ){
$customError = trans('errors.oidc_need_auth', ['system' => config('oidc.name')]);
}else {
$customError = $errorMsg;
}
}
throw new OidcException($customError);
}
}
}