You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.4KB

  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controllers;
  4. use App\Services\AuthService;
  5. use Core\Controller;
  6. use Core\Request;
  7. class AuthController extends Controller
  8. {
  9. public function login(Request $request): mixed
  10. {
  11. $returnTo = trim((string) $request->input('returnTo', ''));
  12. if ($returnTo !== '') {
  13. $_SESSION['auth_return_to'] = $returnTo;
  14. }
  15. $provider = AuthService::provider();
  16. $authUrl = $provider->getAuthorizationUrl();
  17. $_SESSION['oauth2_state'] = $provider->getState();
  18. return $this->redirect($authUrl);
  19. }
  20. public function callback(Request $request): mixed
  21. {
  22. $state = (string) $request->input('state', '');
  23. $code = (string) $request->input('code', '');
  24. if ($state === '' || $state !== ($_SESSION['oauth2_state'] ?? '')) {
  25. unset($_SESSION['oauth2_state']);
  26. return $this->view('auth.callback-error', [
  27. 'pageTitle' => 'Authentication Error',
  28. 'error' => 'Invalid state parameter. Please try logging in again.',
  29. ]);
  30. }
  31. unset($_SESSION['oauth2_state']);
  32. try {
  33. $provider = AuthService::provider();
  34. $token = $provider->getAccessToken('authorization_code', ['code' => $code]);
  35. $userInfo = AuthService::claimsFromToken($token->getToken());
  36. if (empty($userInfo)) {
  37. throw new \RuntimeException('Access token payload was empty or undecodable.');
  38. }
  39. AuthService::storeUser($userInfo);
  40. $redirectTo = $_SESSION['auth_return_to'] ?? '/boards';
  41. unset($_SESSION['auth_return_to']);
  42. return $this->redirect($redirectTo);
  43. } catch (\Throwable $e) {
  44. error_log('Keycloak callback error: ' . $e->getMessage());
  45. $debug = filter_var(getenv('APP_DEBUG'), FILTER_VALIDATE_BOOLEAN);
  46. $error = $debug
  47. ? get_class($e) . ': ' . $e->getMessage()
  48. : 'Authentication failed. Please try again.';
  49. return $this->view('auth.callback-error', [
  50. 'pageTitle' => 'Authentication Error',
  51. 'error' => $error,
  52. ]);
  53. }
  54. }
  55. public function logout(): mixed
  56. {
  57. AuthService::clearSession();
  58. return $this->redirect(AuthService::logoutUrl());
  59. }
  60. }

Powered by TurnKey Linux.