2021-10-06 23:05:26 +01:00
|
|
|
<?php
|
|
|
|
|
|
2023-05-17 17:56:55 +01:00
|
|
|
namespace BookStack\Access\Controllers;
|
2021-10-06 23:05:26 +01:00
|
|
|
|
2023-05-17 17:56:55 +01:00
|
|
|
use BookStack\Access\Oidc\OidcException;
|
|
|
|
|
use BookStack\Access\Oidc\OidcService;
|
2023-05-18 20:53:39 +01:00
|
|
|
use BookStack\Http\Controller;
|
2021-10-06 23:05:26 +01:00
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
|
2021-10-13 16:51:27 +01:00
|
|
|
class OidcController extends Controller
|
2021-10-06 23:05:26 +01:00
|
|
|
{
|
2025-12-03 13:34:00 +00:00
|
|
|
public function __construct(
|
|
|
|
|
protected OidcService $oidcService
|
|
|
|
|
) {
|
2021-10-06 23:05:26 +01:00
|
|
|
$this->middleware('guard:oidc');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Start the authorization login flow via OIDC.
|
|
|
|
|
*/
|
|
|
|
|
public function login()
|
|
|
|
|
{
|
2022-02-24 14:16:09 +00:00
|
|
|
try {
|
|
|
|
|
$loginDetails = $this->oidcService->login();
|
|
|
|
|
} catch (OidcException $exception) {
|
|
|
|
|
$this->showErrorNotification($exception->getMessage());
|
2022-02-24 15:04:09 +00:00
|
|
|
|
2022-02-24 14:16:09 +00:00
|
|
|
return redirect('/login');
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-03 13:34:00 +00:00
|
|
|
session()->put('oidc_state', time() . ':' . $loginDetails['state']);
|
2021-10-06 23:05:26 +01:00
|
|
|
|
|
|
|
|
return redirect($loginDetails['url']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2021-10-13 16:51:27 +01:00
|
|
|
* Authorization flow redirect callback.
|
2021-10-06 23:05:26 +01:00
|
|
|
* Processes authorization response from the OIDC Authorization Server.
|
|
|
|
|
*/
|
2021-10-13 16:51:27 +01:00
|
|
|
public function callback(Request $request)
|
2021-10-06 23:05:26 +01:00
|
|
|
{
|
|
|
|
|
$responseState = $request->query('state');
|
2025-12-03 13:34:00 +00:00
|
|
|
$splitState = explode(':', session()->pull('oidc_state', ':'), 2);
|
|
|
|
|
if (count($splitState) !== 2) {
|
|
|
|
|
$splitState = [null, null];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[$storedStateTime, $storedState] = $splitState;
|
|
|
|
|
$threeMinutesAgo = time() - 3 * 60;
|
2021-10-06 23:05:26 +01:00
|
|
|
|
2025-12-03 13:34:00 +00:00
|
|
|
if (!$storedState || $storedState !== $responseState || intval($storedStateTime) < $threeMinutesAgo) {
|
2021-10-06 23:05:26 +01:00
|
|
|
$this->showErrorNotification(trans('errors.oidc_fail_authed', ['system' => config('oidc.name')]));
|
2021-10-16 16:01:59 +01:00
|
|
|
|
2021-10-06 23:05:26 +01:00
|
|
|
return redirect('/login');
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-24 14:16:09 +00:00
|
|
|
try {
|
|
|
|
|
$this->oidcService->processAuthorizeResponse($request->query('code'));
|
|
|
|
|
} catch (OidcException $oidcException) {
|
|
|
|
|
$this->showErrorNotification($oidcException->getMessage());
|
2022-02-24 15:04:09 +00:00
|
|
|
|
2022-02-24 14:16:09 +00:00
|
|
|
return redirect('/login');
|
|
|
|
|
}
|
2021-10-16 16:01:59 +01:00
|
|
|
|
2021-10-06 23:05:26 +01:00
|
|
|
return redirect()->intended();
|
|
|
|
|
}
|
2023-08-29 13:07:21 +08:00
|
|
|
|
|
|
|
|
/**
|
2025-12-03 13:34:00 +00:00
|
|
|
* Log the user out, then start the OIDC RP-initiated logout process.
|
2023-08-29 13:07:21 +08:00
|
|
|
*/
|
|
|
|
|
public function logout()
|
|
|
|
|
{
|
2023-12-06 13:49:53 +00:00
|
|
|
return redirect($this->oidcService->logout());
|
2023-08-29 13:07:21 +08:00
|
|
|
}
|
2021-10-06 23:05:26 +01:00
|
|
|
}
|