From 79e5a3c12d80ed1cbfaae5b53be29e8f46b79663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Fri, 12 Dec 2025 15:55:47 +0100 Subject: [PATCH] feat: adjust oauth2 implementation for TYPO3 backend login --- config/packages/league_oauth2_server.yaml | 2 +- src/BusProNet/Model/PersonalData.php | 4 ++++ src/Controller/Api/UserinfoController.php | 9 +++++++++ src/Controller/SecurityController.php | 6 +++--- src/EventListener/AccessDeniedListener.php | 2 -- src/Security/BpnAuthenticator.php | 8 ++++++-- templates/base.html.twig | 2 +- 7 files changed, 24 insertions(+), 9 deletions(-) diff --git a/config/packages/league_oauth2_server.yaml b/config/packages/league_oauth2_server.yaml index 84d15c6..b8a24c4 100644 --- a/config/packages/league_oauth2_server.yaml +++ b/config/packages/league_oauth2_server.yaml @@ -11,7 +11,7 @@ league_oauth2_server: resource_server: public_key: '%env(resolve:OAUTH_PUBLIC_KEY)%' scopes: - available: ['email','profile','api'] + available: ['email','id','profile','roles','api'] default: ['email'] persistence: doctrine: null diff --git a/src/BusProNet/Model/PersonalData.php b/src/BusProNet/Model/PersonalData.php index 15784e2..d811f3b 100644 --- a/src/BusProNet/Model/PersonalData.php +++ b/src/BusProNet/Model/PersonalData.php @@ -49,6 +49,8 @@ class PersonalData #[Assert\Valid(groups: ['personal_data'])] public Communication $communication; + public array $roles = []; + public function __construct() { $this->address = new Address(); @@ -124,7 +126,9 @@ class PersonalData public function getClaims(): array { return [ + 'id' => $this->personId, 'email' => $this->communication->email, + 'roles' => $this->roles, 'profile' => [ 'first_name' => $this->firstName, 'last_name' => $this->name, diff --git a/src/Controller/Api/UserinfoController.php b/src/Controller/Api/UserinfoController.php index 54bea4a..2e0f89c 100644 --- a/src/Controller/Api/UserinfoController.php +++ b/src/Controller/Api/UserinfoController.php @@ -29,9 +29,15 @@ class UserinfoController extends AbstractController $scopes = ['email']; // extend scopes depending on granted permissions + if ($this->isGranted('ROLE_OAUTH2_ID')) { + $scopes[] = 'id'; + } if ($this->isGranted('ROLE_OAUTH2_PROFILE')) { $scopes[] = 'profile'; } + if ($this->isGranted('ROLE_OAUTH2_ROLES')) { + $scopes[] = 'roles'; + } /** @var User $user */ $user = $this->getUser(); @@ -45,6 +51,9 @@ class UserinfoController extends AbstractController return new JsonResponse(['message' => $data->message, 'code' => $data->code], Response::HTTP_BAD_REQUEST); } + // Patch current user's roles + $data->roles = $user->getRoles(); + // extract userdata for resulting claims $userData = $this->getClaims($data, $scopes); diff --git a/src/Controller/SecurityController.php b/src/Controller/SecurityController.php index cf96230..1b9df58 100644 --- a/src/Controller/SecurityController.php +++ b/src/Controller/SecurityController.php @@ -43,9 +43,8 @@ class SecurityController extends AbstractController // authentication (see App\EventListener\AuthorizationCodeListener). $session = $request->getSession(); $targetPath = $session->get('_security.main.target_path'); - if (null !== $targetPath && str_contains($targetPath, '/authorize')) { - $session->set('_oauth2', true); - } + $isOauth2 = null !== $targetPath && str_contains($targetPath, '/authorize'); + $session->set('_oauth2', $isOauth2); // For booking flow, set target path to Step 1 (after successful auth, redirect there) if (true === $isBookingFlow) { @@ -71,6 +70,7 @@ class SecurityController extends AbstractController 'travel_date_from' => $bookingDto?->travel->dateFrom, 'travel_date_to' => $bookingDto?->travel->dateTo, 'cmsData' => $cmsData, + 'oauth2' => $isOauth2, ]); } diff --git a/src/EventListener/AccessDeniedListener.php b/src/EventListener/AccessDeniedListener.php index a5e27fc..c7284b1 100644 --- a/src/EventListener/AccessDeniedListener.php +++ b/src/EventListener/AccessDeniedListener.php @@ -37,8 +37,6 @@ class AccessDeniedListener implements EventSubscriberInterface // Treat OAuth2 routes differently if (in_array($route, ['oauth2_authorize', 'oauth2_token'])) { - $request->getSession()->getFlashBag()->add('info', 'Bitte melde dich an.'); - $this->authLogger->info('OAuth2 authorization request', [ 'uri' => $request->getRequestUri(), ]); diff --git a/src/Security/BpnAuthenticator.php b/src/Security/BpnAuthenticator.php index 57eb3d9..b90b188 100644 --- a/src/Security/BpnAuthenticator.php +++ b/src/Security/BpnAuthenticator.php @@ -117,9 +117,12 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent private function collectRoles(CrmAttributes $crmAttributes): array { - // Collect user's roles from CRM attributes - $roles = []; + // All users inherit the default role 'customer' + $roles = [ + 'ROLE_CUSTOMER', + ]; + // Get user's base role from CRM attributes if ($crmAttributes->admin) { $roles[] = 'ROLE_ADMIN'; } elseif ($crmAttributes->manager) { @@ -128,6 +131,7 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent $roles[] = 'ROLE_HOUSE_MANAGER'; } + // All users can have role 'teamer' additionally if ($crmAttributes->teamer) { $roles[] = 'ROLE_TEAMER'; } diff --git a/templates/base.html.twig b/templates/base.html.twig index 40881d5..87fcfad 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -11,7 +11,7 @@ {{ encore_entry_script_tags('app') }} {% endblock %} - + {% block body %}{% endblock %}