diff --git a/.env b/.env index 8aa660d..5b250b9 100644 --- a/.env +++ b/.env @@ -55,7 +55,7 @@ APP_BPN_DEBUG=false # This hotel code will be assigned to admin users together with ROLE_HOTEL_MANAGER # in dev and staging environments for testing purposes APP_BPN_DEFAULT_HOTEL_CODE= -APP_BPN_CRM_ID_ADMIN=1292 +APP_BPN_CRM_ID_TEAM_ADMIN=1484 APP_BPN_CRM_ID_MANAGER=1293 APP_BPN_CRM_ID_TEAMER=1070 diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 6812335..2be9228 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -9,7 +9,7 @@ security: property: email role_hierarchy: - ROLE_ADMIN: [ ROLE_ADMINISTRATIVE ] + ROLE_TEAM_ADMIN: [ ROLE_ADMINISTRATIVE ] ROLE_MANAGER: [ ROLE_ADMINISTRATIVE ] firewalls: diff --git a/config/services.yaml b/config/services.yaml index 99cce9e..adac2f1 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -1,6 +1,6 @@ # yaml-language-server: $schema=../vendor/symfony/dependency-injection/Loader/schema/services.schema.json parameters: - bpn_crm_id_admin: '%env(int:APP_BPN_CRM_ID_ADMIN)%' + bpn_crm_id_team_admin: '%env(int:APP_BPN_CRM_ID_TEAM_ADMIN)%' bpn_crm_id_manager: '%env(int:APP_BPN_CRM_ID_MANAGER)%' bpn_crm_id_teamer: '%env(int:APP_BPN_CRM_ID_TEAMER)%' bpn_default_hotel_code: '%env(default::APP_BPN_DEFAULT_HOTEL_CODE)%' @@ -162,7 +162,7 @@ services: App\BusProNet\ResponseParser: arguments: $options: - bpn_crm_id_admin: '%bpn_crm_id_admin%' + bpn_crm_id_team_admin: '%bpn_crm_id_team_admin%' bpn_crm_id_manager: '%bpn_crm_id_manager%' bpn_crm_id_teamer: '%bpn_crm_id_teamer%' bpn_crm_house_manager_ids: '%bpn_crm_house_manager_ids%' diff --git a/docs/user-roles.md b/docs/user-roles.md index 7587ac5..9fa66b5 100644 --- a/docs/user-roles.md +++ b/docs/user-roles.md @@ -30,17 +30,35 @@ assign: | Role | Label | Granted by | Revoked by | Hierarchy | |------|-------|-----------|------------|-----------| -| `ROLE_ADMIN` | Admin | super admin, approving a CRM claim | the CRM, automatically | ⇒ `ROLE_ADMINISTRATIVE` | +| `ROLE_TEAM_ADMIN` | Admin | super admin, approving a CRM claim | the CRM, automatically | ⇒ `ROLE_ADMINISTRATIVE` | | `ROLE_MANAGER` | Reisemanager | super admin, approving a CRM claim | the CRM, automatically | ⇒ `ROLE_ADMINISTRATIVE` | | `ROLE_HOUSE_MANAGER` | Hausleitung | super admin, approving a CRM claim | the CRM, automatically | — | | `ROLE_TEAMER` | Teamer | the CRM, automatically | the CRM, automatically | — | +### A note on the `TEAM_` prefix + +`ROLE_TEAM_ADMIN`, `ROLE_TEAM_ADMIN_PENDING` and `ROLE_TEAM_SUPER_ADMIN` were renamed from +`ROLE_ADMIN`, `ROLE_ADMIN_PENDING` and `ROLE_SUPER_ADMIN`. The MyE&P identity provider is +shared with a sibling portal that uses `ROLE_ADMIN` for a different privilege, so the plain +name was ambiguous across the estate; the prefix makes it unambiguously *this* application's +admin. The German label is unchanged — it still reads "Admin" everywhere in the UI. + +Two consequences worth remembering: + +- **`ROLE_ADMINISTRATIVE` is a different role and was not renamed.** It is granted only by + the hierarchy, never stored, and it shares the old `ROLE_ADMIN` prefix — so any + search-and-replace over role names must match on a word boundary + (`ROLE_TEAM_ADMIN(?![A-Z_])`) or it will corrupt ~100 call sites silently. +- **`ELIGIBLE_ROLES` in `MyEpAuthenticator` is a wire contract**, not an internal name: it is + compared directly against the IdP's `roles` claim. It only works while MyE&P emits + `ROLE_TEAM_ADMIN`, so the two sides have to move together. + `User::PENDING_ROLES` holds a marker for each of the three administrative roles, keyed by the role it stands for: | Marker | Meaning | |--------|---------| -| `ROLE_ADMIN_PENDING` | the CRM claims this person is an admin, nobody has confirmed it | +| `ROLE_TEAM_ADMIN_PENDING` | the CRM claims this person is an admin, nobody has confirmed it | | `ROLE_MANAGER_PENDING` | likewise for Reisemanager | | `ROLE_HOUSE_MANAGER_PENDING` | likewise for Hausleitung | @@ -50,10 +68,10 @@ effects are cosmetic (rendered as "Admin (nicht freigeschaltet)") and organisati put the user on the approval list). `ROLE_TEAMER` has no marker: it needs no approval. Two further roles are synthesized by `User::getRoles()` and never stored: `ROLE_USER` for -everybody, and `ROLE_SUPER_ADMIN` when the separate `superAdmin` boolean column is set. A +everybody, and `ROLE_TEAM_SUPER_ADMIN` when the separate `superAdmin` boolean column is set. A validation callback (`User::validateSuperAdmin()`) refuses `superAdmin` without -`ROLE_ADMIN` alongside it — super admin is an elevation, never a standalone grant. The sync -enforces the same rule from the other side: revoking `ROLE_ADMIN` clears the flag, or the one +`ROLE_TEAM_ADMIN` alongside it — super admin is an elevation, never a standalone grant. The sync +enforces the same rule from the other side: revoking `ROLE_TEAM_ADMIN` clears the flag, or the one role that outranks every check in the application would outlive the role it depends on. ### Storage and accessors @@ -63,7 +81,7 @@ slice it, and picking the right one matters: | Accessor | Returns | |----------|---------| -| `getRoles()` | the column **plus** synthesized `ROLE_USER` / `ROLE_SUPER_ADMIN` — what Symfony authorises against | +| `getRoles()` | the column **plus** synthesized `ROLE_USER` / `ROLE_TEAM_SUPER_ADMIN` — what Symfony authorises against | | `getAssignedRoles()` | only the four real roles from the column — what the sync works on | | `getPendingRoles()` | only the markers | | `getNominatedRoles()` | the roles behind those markers, as `role => label` — what an approver acts on | @@ -77,7 +95,7 @@ slice it, and picking the right one matters: | CRM attribute | Recognised by | Sets | |---------------|---------------|------| -| admin | attribute id `%bpn_crm_id_admin%`, selected | `isAdmin` | +| admin | attribute id `%bpn_crm_id_team_admin%`, selected | `isAdmin` | | Reisemanager | attribute id `%bpn_crm_id_manager%`, selected | `isManager` | | teamer | attribute id `%bpn_crm_id_teamer%`, selected | `isTeamer` | | Hausleitung | attribute id listed in `%bpn_crm_house_manager_ids%`, selected | `isHouseManager` + the hotel code that id maps to | @@ -111,12 +129,26 @@ roles were revoked. > > | Parameter | Attribute | > |-----------|-----------| -> | `APP_BPN_CRM_ID_ADMIN` | `Admin` | +> | `APP_BPN_CRM_ID_TEAM_ADMIN` | the team-admin selection — **not** the old portal-wide `Admin` (1292) | > | `APP_BPN_CRM_ID_MANAGER` | `Manager` | > | `APP_BPN_CRM_ID_TEAMER` | `E&P Teamer - allg. Merkmal` | > > Matching is by id and never by label, so `Preisrechner Admin` does not trip the admin flag. > +> `APP_BPN_CRM_ID_TEAM_ADMIN` was renamed from `APP_BPN_CRM_ID_ADMIN` with the +> `ROLE_TEAM_ADMIN` rename, and its **value has to change too**. The old value 1292 is the +> portal-wide admin selection, which still means `ROLE_ADMIN` in the sibling portal — keeping +> it would have left this app granting its admin off the very selection the rename was meant +> to stop sharing. It ships as `0` — a valid int that matches no attribute, so the container +> boots but nobody is granted the role — and must be set to the new selection's id. +> +> **This is a hard cutover.** `revokeUnclaimedRoles()` withdraws any granted role the CRM no +> longer claims, and `revokeSuperAdminWithoutRoleAdmin()` takes the super admin flag down with +> `ROLE_TEAM_ADMIN`. So the new selection must exist **and already be assigned to every admin** +> in BusPro before this is deployed; otherwise each of them is demoted on their next login and +> needs a super admin to re-approve. Admins who also hold `ROLE_TEAMER` degrade to teamer +> access; an admin without it is blocked outright by `disableForRevokedCrmRoles()`. +> > `bpn_crm_house_manager_ids` (`config/services.yaml`) is deployment-critical for the same > reason, and more sharply so: since roles are synced, an id missing from that map does not > merely fail to nominate a Hausleitung, it **revokes** the role from everyone holding it, one @@ -137,7 +169,7 @@ roles were revoked. `BpnAuthenticator::getOrCreateLocalUser()` → `UserDataHandler::createLocalUser()` writes `collectRoles()` verbatim, together with the hotel codes from the Hausleitung attributes. -A CRM admin who is not also a teamer therefore starts with `['ROLE_ADMIN_PENDING']` and no +A CRM admin who is not also a teamer therefore starts with `['ROLE_TEAM_ADMIN_PENDING']` and no privileges at all: they can authenticate, but `UserChecker` refuses the session until a super admin approves them. @@ -148,7 +180,7 @@ the roles to **`syncRoles()`**, which is the whole policy in four steps: 1. **revoke** every granted role the CRM no longer claims. This is what makes BusPro the source of truth, and it applies to `ROLE_TEAMER` as much as to the administrative roles. -2. **clear the super admin flag** when `ROLE_ADMIN` was among them — `ROLE_SUPER_ADMIN` is +2. **clear the super admin flag** when `ROLE_TEAM_ADMIN` was among them — `ROLE_TEAM_SUPER_ADMIN` is synthesized from a separate column and would otherwise survive its own precondition. 3. **`refreshPendingRoles()`** recomputes the marker set from the current claims. A marker whose real role is already granted is dropped — an approved role is never marked again. @@ -189,7 +221,7 @@ runs again on submit to catch a sync that revoked the claim while the dialog was A denial is not recorded anywhere: as long as the CRM keeps claiming the role, the nomination is back on the next login. -**Super admin** is only offered to somebody who already holds `ROLE_ADMIN` — approve first, +**Super admin** is only offered to somebody who already holds `ROLE_TEAM_ADMIN` — approve first, elevate afterwards. The one exception is a flag that outlived its role, which stays editable so the account can be saved at all while `User::validateSuperAdmin()` is violated; the sync clears it (see 2), so it should never occur in practice. @@ -243,7 +275,7 @@ administrative users, teamers are an admin's business: | Surface | Who | Notes | |---------|-----|-------| -| `/admin/teamer/disable-user/{uuid}` and `/administrative/teamer/enable-user/{uuid}` | `ROLE_ADMIN` | teamers; public reason mandatory, internal optional | +| `/admin/teamer/disable-user/{uuid}` and `/administrative/teamer/enable-user/{uuid}` | `ROLE_TEAM_ADMIN` | teamers; public reason mandatory, internal optional | | "Account gesperrt" checkbox on the user edit form | super admin (`UserVoter`) | everyone else; both reasons optional | Both go through `User::setDisabled()`, which is a no-op when the state is unchanged — saving diff --git a/src/BusProNet/ResponseParser.php b/src/BusProNet/ResponseParser.php index a9c3037..2af29bf 100644 --- a/src/BusProNet/ResponseParser.php +++ b/src/BusProNet/ResponseParser.php @@ -200,7 +200,7 @@ class ResponseParser $isHouseManager = true; $hotelCodes[] = $houseManagerCode; } - if ($this->config['bpn_crm_id_admin'] === $attribute->getId() && true === $attribute->isSelected()) { + if ($this->config['bpn_crm_id_team_admin'] === $attribute->getId() && true === $attribute->isSelected()) { $isAdmin = true; } if ($this->config['bpn_crm_id_manager'] === $attribute->getId() && true === $attribute->isSelected()) { @@ -305,11 +305,11 @@ class ResponseParser private function resolveOptions(array $options): array { $optionsResolver = new OptionsResolver(); - $optionsResolver->setRequired(['bpn_crm_id_admin', 'bpn_crm_id_manager', 'bpn_crm_id_teamer', 'bpn_crm_house_manager_ids']); + $optionsResolver->setRequired(['bpn_crm_id_team_admin', 'bpn_crm_id_manager', 'bpn_crm_id_teamer', 'bpn_crm_house_manager_ids']); $optionsResolver->setDefaults([ 'bpn_default_hotel_code' => null, ]); - $optionsResolver->setAllowedTypes('bpn_crm_id_admin', 'int'); + $optionsResolver->setAllowedTypes('bpn_crm_id_team_admin', 'int'); $optionsResolver->setAllowedTypes('bpn_crm_id_manager', 'int'); $optionsResolver->setAllowedTypes('bpn_crm_id_teamer', 'int'); $optionsResolver->setAllowedTypes('bpn_crm_house_manager_ids', 'array'); diff --git a/src/BusProNet/UserDataHandler.php b/src/BusProNet/UserDataHandler.php index 5b8da4b..f58e2c7 100644 --- a/src/BusProNet/UserDataHandler.php +++ b/src/BusProNet/UserDataHandler.php @@ -69,7 +69,7 @@ class UserDataHandler $claimedRoles = []; if ($crmAttributes->isAdmin()) { - $claimedRoles[] = 'ROLE_ADMIN'; + $claimedRoles[] = 'ROLE_TEAM_ADMIN'; } if ($crmAttributes->isManager()) { @@ -370,7 +370,7 @@ class UserDataHandler * The whole policy, in the order it has to run: * * 1. revoke what is no longer claimed - the identity source leads; - * 2. drop the super admin flag along with ROLE_ADMIN, or the highest privilege in the + * 2. drop the super admin flag along with ROLE_TEAM_ADMIN, or the highest privilege in the * application would outlive the role it depends on; * 3. refresh the pending markers, after the revocation so that a role just revoked is * not immediately marked again - it is unclaimed in both steps; @@ -424,7 +424,7 @@ class UserDataHandler * * Only the roles of User::ROLES are touched: getAssignedRoles() excludes the pending * markers as well as the implicit ROLE_USER, and the markers are dealt with by - * refreshPendingRoles(). ROLE_SUPER_ADMIN is not a stored role at all but a flag, so + * refreshPendingRoles(). ROLE_TEAM_SUPER_ADMIN is not a stored role at all but a flag, so * it is handled separately below. * * @param string[] $claimedRoles @@ -450,22 +450,22 @@ class UserDataHandler } /** - * Takes the super admin flag down with ROLE_ADMIN. + * Takes the super admin flag down with ROLE_TEAM_ADMIN. * - * The flag is stored on its own and getRoles() turns it into ROLE_SUPER_ADMIN whatever + * The flag is stored on its own and getRoles() turns it into ROLE_TEAM_SUPER_ADMIN whatever * else the user holds, so without this a person the CRM no longer calls an admin would * keep the one role that outranks every check in the application. User::validateSuperAdmin() * enforces the same rule on the edit form, but only there. */ private function revokeSuperAdminWithoutRoleAdmin(User $user): void { - if (false === $user->isSuperAdmin() || true === $user->hasRole('ROLE_ADMIN')) { + if (false === $user->isSuperAdmin() || true === $user->hasRole('ROLE_TEAM_ADMIN')) { return; } $user->setSuperAdmin(false); - $this->logger->info('Revoke super admin flag along with ROLE_ADMIN', [ + $this->logger->info('Revoke super admin flag along with ROLE_TEAM_ADMIN', [ 'user_id' => $user->getId(), 'user_email' => $user->getEmail(), ]); diff --git a/src/Controller/Admin/Autocomplete/UserController.php b/src/Controller/Admin/Autocomplete/UserController.php index 71a5cbd..b64e4c7 100644 --- a/src/Controller/Admin/Autocomplete/UserController.php +++ b/src/Controller/Admin/Autocomplete/UserController.php @@ -16,7 +16,7 @@ class UserController extends AbstractController } #[Route('/admin/autocomplete/user', name: 'app_admin_autocomplete_user')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Request $request): JsonResponse { try { diff --git a/src/Controller/Admin/Feedback/ApproveController.php b/src/Controller/Admin/Feedback/ApproveController.php index c46e580..b5738cb 100644 --- a/src/Controller/Admin/Feedback/ApproveController.php +++ b/src/Controller/Admin/Feedback/ApproveController.php @@ -22,7 +22,7 @@ class ApproveController extends AbstractController } #[Route('/admin/feedback/approve/{uuid}', name: 'app_admin_feedback_approve')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Feedback $feedback, Request $request): Response { $form = $this->createForm(FeedbackApproveType::class, $feedback); diff --git a/src/Controller/Admin/Feedback/ProvideController.php b/src/Controller/Admin/Feedback/ProvideController.php index 6523b0b..ce0a7d0 100644 --- a/src/Controller/Admin/Feedback/ProvideController.php +++ b/src/Controller/Admin/Feedback/ProvideController.php @@ -24,7 +24,7 @@ class ProvideController extends AbstractController } #[Route('/admin/feedback/provide', name: 'app_admin_feedback_provide')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Request $request): Response { $form = $this->getFeedbackForm(); @@ -58,7 +58,7 @@ class ProvideController extends AbstractController } #[Route('/admin/feedback/provide/form', name: 'app_admin_feedback_provide_form')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function form(Request $request): Response { $form = $this->getFeedbackForm(); diff --git a/src/Controller/Admin/IndexController.php b/src/Controller/Admin/IndexController.php index 297e6b6..73ebdd1 100644 --- a/src/Controller/Admin/IndexController.php +++ b/src/Controller/Admin/IndexController.php @@ -21,7 +21,7 @@ class IndexController extends AbstractController } #[Route('/admin', name: 'app_admin_index')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(): Response { $applicationRepository = $this->entityManager->getRepository(Application::class); diff --git a/src/Controller/Admin/Log/IndexController.php b/src/Controller/Admin/Log/IndexController.php index f649917..6ae6cb6 100644 --- a/src/Controller/Admin/Log/IndexController.php +++ b/src/Controller/Admin/Log/IndexController.php @@ -20,7 +20,7 @@ class IndexController extends AbstractController } #[Route('/admin/log', name: 'app_admin_log_index')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Request $request): Response { $qb = $this diff --git a/src/Controller/Admin/System/Availability/CreateController.php b/src/Controller/Admin/System/Availability/CreateController.php index 83b8d5d..f5b8712 100644 --- a/src/Controller/Admin/System/Availability/CreateController.php +++ b/src/Controller/Admin/System/Availability/CreateController.php @@ -22,7 +22,7 @@ class CreateController extends AbstractController } #[Route('/admin/system/availability/create', name: 'app_admin_system_availability_create')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Request $request): Response { $availability = new Availability(); diff --git a/src/Controller/Admin/System/Availability/DeleteController.php b/src/Controller/Admin/System/Availability/DeleteController.php index dd4bbf0..99f3e9c 100644 --- a/src/Controller/Admin/System/Availability/DeleteController.php +++ b/src/Controller/Admin/System/Availability/DeleteController.php @@ -21,7 +21,7 @@ class DeleteController extends AbstractController } #[Route('/admin/system/availability/delete/{id}', name: 'app_admin_system_availability_delete', methods: ['POST'])] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Availability $availability, Request $request): Response { if (true === $request->isMethod('POST')) { diff --git a/src/Controller/Admin/System/Availability/DuplicateController.php b/src/Controller/Admin/System/Availability/DuplicateController.php index 8bd2135..218bd8d 100644 --- a/src/Controller/Admin/System/Availability/DuplicateController.php +++ b/src/Controller/Admin/System/Availability/DuplicateController.php @@ -22,7 +22,7 @@ class DuplicateController extends AbstractController } #[Route('/admin/system/availability/duplicate/{id}', name: 'app_admin_system_availability_duplicate')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Availability $availability, Request $request): Response { $copy = Availability::duplicate($availability); diff --git a/src/Controller/Admin/System/Availability/EditController.php b/src/Controller/Admin/System/Availability/EditController.php index 5a20d88..319ace6 100644 --- a/src/Controller/Admin/System/Availability/EditController.php +++ b/src/Controller/Admin/System/Availability/EditController.php @@ -22,7 +22,7 @@ class EditController extends AbstractController } #[Route('/admin/system/availability/edit/{id}', name: 'app_admin_system_availability_edit')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Availability $availability, Request $request): Response { $form = $this->createForm(AvailabilityType::class, $availability); diff --git a/src/Controller/Admin/System/Availability/IndexController.php b/src/Controller/Admin/System/Availability/IndexController.php index 3932eb1..b4feffc 100644 --- a/src/Controller/Admin/System/Availability/IndexController.php +++ b/src/Controller/Admin/System/Availability/IndexController.php @@ -19,7 +19,7 @@ class IndexController extends AbstractController } #[Route('/admin/system/availability', name: 'app_admin_system_availability_index')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Request $request): Response { $query = $this diff --git a/src/Controller/Admin/System/EmailText/EditController.php b/src/Controller/Admin/System/EmailText/EditController.php index f303b5d..4a66a77 100644 --- a/src/Controller/Admin/System/EmailText/EditController.php +++ b/src/Controller/Admin/System/EmailText/EditController.php @@ -28,7 +28,7 @@ class EditController extends AbstractController } #[Route('/admin/system/email-text/edit/{key}', name: 'app_admin_system_email_text_edit')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(EmailTextKey $key, Request $request): Response { $definition = $this->catalog->get($key); diff --git a/src/Controller/Admin/System/EmailText/IndexController.php b/src/Controller/Admin/System/EmailText/IndexController.php index c584777..1b32dae 100644 --- a/src/Controller/Admin/System/EmailText/IndexController.php +++ b/src/Controller/Admin/System/EmailText/IndexController.php @@ -18,7 +18,7 @@ class IndexController extends AbstractController } #[Route('/admin/system/email-text', name: 'app_admin_system_email_text_index')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(): Response { // The list is driven by the catalogue, not by the table: a mail that has never diff --git a/src/Controller/Admin/System/EmailText/PreviewController.php b/src/Controller/Admin/System/EmailText/PreviewController.php index be89c26..4111475 100644 --- a/src/Controller/Admin/System/EmailText/PreviewController.php +++ b/src/Controller/Admin/System/EmailText/PreviewController.php @@ -25,7 +25,7 @@ class PreviewController extends AbstractController * a real mail is being assembled. */ #[Route('/admin/system/email-text/preview/{key}', name: 'app_admin_system_email_text_preview')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(EmailTextKey $key): Response { $definition = $this->catalog->get($key); diff --git a/src/Controller/Admin/System/EmailText/PreviewDraftController.php b/src/Controller/Admin/System/EmailText/PreviewDraftController.php index adf8b69..f3f0872 100644 --- a/src/Controller/Admin/System/EmailText/PreviewDraftController.php +++ b/src/Controller/Admin/System/EmailText/PreviewDraftController.php @@ -27,7 +27,7 @@ class PreviewDraftController extends AbstractController * the submitted values instead of the stored ones. */ #[Route('/admin/system/email-text/preview-draft/{key}', name: 'app_admin_system_email_text_preview_draft', methods: ['POST'])] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(EmailTextKey $key, Request $request): Response { $definition = $this->catalog->get($key); diff --git a/src/Controller/Admin/System/EmailText/ResetController.php b/src/Controller/Admin/System/EmailText/ResetController.php index d8c22cd..1bdfb60 100644 --- a/src/Controller/Admin/System/EmailText/ResetController.php +++ b/src/Controller/Admin/System/EmailText/ResetController.php @@ -25,7 +25,7 @@ class ResetController extends AbstractController } #[Route('/admin/system/email-text/reset/{key}', name: 'app_admin_system_email_text_reset')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(EmailTextKey $key, Request $request): Response { $emailText = $this->emailTextRepository->findByKey($key); diff --git a/src/Controller/Admin/System/Fee/CreateController.php b/src/Controller/Admin/System/Fee/CreateController.php index 71c784b..57bc62c 100644 --- a/src/Controller/Admin/System/Fee/CreateController.php +++ b/src/Controller/Admin/System/Fee/CreateController.php @@ -22,7 +22,7 @@ class CreateController extends AbstractController } #[Route('/admin/system/fee/create', name: 'app_admin_system_fee_create')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Request $request): Response { $fee = new Fee(); diff --git a/src/Controller/Admin/System/Fee/DeleteController.php b/src/Controller/Admin/System/Fee/DeleteController.php index 068ef20..871b8d4 100644 --- a/src/Controller/Admin/System/Fee/DeleteController.php +++ b/src/Controller/Admin/System/Fee/DeleteController.php @@ -21,7 +21,7 @@ class DeleteController extends AbstractController } #[Route('/admin/system/fee/delete/{id}', name: 'app_admin_system_fee_delete')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Fee $fee, Request $request): Response { if (true === $request->isMethod('POST')) { diff --git a/src/Controller/Admin/System/Fee/DuplicateController.php b/src/Controller/Admin/System/Fee/DuplicateController.php index 6acbf8f..1440d1f 100644 --- a/src/Controller/Admin/System/Fee/DuplicateController.php +++ b/src/Controller/Admin/System/Fee/DuplicateController.php @@ -22,7 +22,7 @@ class DuplicateController extends AbstractController } #[Route('/admin/system/fee/duplicate/{id}', name: 'app_admin_system_fee_duplicate')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Fee $fee, Request $request): Response { $copy = Fee::duplicate($fee); diff --git a/src/Controller/Admin/System/Fee/EditController.php b/src/Controller/Admin/System/Fee/EditController.php index e9a831d..64c28d0 100644 --- a/src/Controller/Admin/System/Fee/EditController.php +++ b/src/Controller/Admin/System/Fee/EditController.php @@ -22,7 +22,7 @@ class EditController extends AbstractController } #[Route('/admin/system/fee/edit/{id}', name: 'app_admin_system_fee_edit')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Fee $fee, Request $request): Response { $form = $this->createForm(FeeType::class, $fee); diff --git a/src/Controller/Admin/System/Fee/IndexController.php b/src/Controller/Admin/System/Fee/IndexController.php index 226e328..7c28e63 100644 --- a/src/Controller/Admin/System/Fee/IndexController.php +++ b/src/Controller/Admin/System/Fee/IndexController.php @@ -15,7 +15,7 @@ class IndexController extends AbstractController } #[Route('/admin/system/fee', name: 'app_admin_system_fee_index')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(): Response { $fees = $this->feeRepository->getList(); diff --git a/src/Controller/Admin/System/FeedbackSet/CreateController.php b/src/Controller/Admin/System/FeedbackSet/CreateController.php index 867e162..f01241a 100644 --- a/src/Controller/Admin/System/FeedbackSet/CreateController.php +++ b/src/Controller/Admin/System/FeedbackSet/CreateController.php @@ -21,7 +21,7 @@ class CreateController extends AbstractController } #[Route('/admin/system/feedback-set/create', name: 'app_admin_system_feedback_set_create')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Request $request): Response { $feedbackSet = new FeedbackSet(); diff --git a/src/Controller/Admin/System/FeedbackSet/DeleteController.php b/src/Controller/Admin/System/FeedbackSet/DeleteController.php index af61488..6f6fca9 100644 --- a/src/Controller/Admin/System/FeedbackSet/DeleteController.php +++ b/src/Controller/Admin/System/FeedbackSet/DeleteController.php @@ -21,7 +21,7 @@ class DeleteController extends AbstractController } #[Route('/admin/system/feedback-set/delete/{id}', name: 'app_admin_system_feedback_set_delete')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] #[IsGranted('DELETE', subject: 'feedbackSet')] public function index(FeedbackSet $feedbackSet, Request $request): Response { diff --git a/src/Controller/Admin/System/FeedbackSet/EditController.php b/src/Controller/Admin/System/FeedbackSet/EditController.php index 76de3d0..83117a9 100644 --- a/src/Controller/Admin/System/FeedbackSet/EditController.php +++ b/src/Controller/Admin/System/FeedbackSet/EditController.php @@ -21,7 +21,7 @@ class EditController extends AbstractController } #[Route('/admin/system/feedback-set/edit/{id}', name: 'app_admin_system_feedback_set_edit')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(FeedbackSet $feedbackSet, Request $request): Response { $form = $this->createForm(FeedbackSetType::class, $feedbackSet); diff --git a/src/Controller/Admin/System/FeedbackSet/IndexController.php b/src/Controller/Admin/System/FeedbackSet/IndexController.php index b10c37f..7308e13 100644 --- a/src/Controller/Admin/System/FeedbackSet/IndexController.php +++ b/src/Controller/Admin/System/FeedbackSet/IndexController.php @@ -15,7 +15,7 @@ class IndexController extends AbstractController } #[Route('/admin/system/feedback-set', name: 'app_admin_system_feedback_set_index')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(): Response { $feedbackSets = $this diff --git a/src/Controller/Admin/System/JobProfile/CreateController.php b/src/Controller/Admin/System/JobProfile/CreateController.php index 3662904..ec4680e 100644 --- a/src/Controller/Admin/System/JobProfile/CreateController.php +++ b/src/Controller/Admin/System/JobProfile/CreateController.php @@ -21,7 +21,7 @@ class CreateController extends AbstractController } #[Route('/admin/system/job-profile/create', name: 'app_admin_system_job_profile_create')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Request $request): Response { $jobProfile = new JobProfile(); diff --git a/src/Controller/Admin/System/JobProfile/DeleteController.php b/src/Controller/Admin/System/JobProfile/DeleteController.php index 5a131e4..adc7514 100644 --- a/src/Controller/Admin/System/JobProfile/DeleteController.php +++ b/src/Controller/Admin/System/JobProfile/DeleteController.php @@ -21,7 +21,7 @@ class DeleteController extends AbstractController } #[Route('/admin/system/job-profile/delete/{id}', name: 'app_admin_system_job_profile_delete')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(JobProfile $jobProfile, Request $request): Response { if (true === $request->isMethod('POST')) { diff --git a/src/Controller/Admin/System/JobProfile/EditController.php b/src/Controller/Admin/System/JobProfile/EditController.php index c60aedb..5f94ec6 100644 --- a/src/Controller/Admin/System/JobProfile/EditController.php +++ b/src/Controller/Admin/System/JobProfile/EditController.php @@ -21,7 +21,7 @@ class EditController extends AbstractController } #[Route('/admin/system/job-profile/edit/{id}', name: 'app_admin_system_job_profile_edit')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(JobProfile $jobProfile, Request $request): Response { $form = $this->createForm(JobProfileType::class, $jobProfile); diff --git a/src/Controller/Admin/System/JobProfile/IndexController.php b/src/Controller/Admin/System/JobProfile/IndexController.php index 99d74bc..3780c53 100644 --- a/src/Controller/Admin/System/JobProfile/IndexController.php +++ b/src/Controller/Admin/System/JobProfile/IndexController.php @@ -15,7 +15,7 @@ class IndexController extends AbstractController } #[Route('/admin/system/job-profile', name: 'app_admin_system_job_profile_index')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(): Response { $jobProfiles = $this diff --git a/src/Controller/Admin/System/Training/CreateController.php b/src/Controller/Admin/System/Training/CreateController.php index 6e401f5..e60ad1d 100644 --- a/src/Controller/Admin/System/Training/CreateController.php +++ b/src/Controller/Admin/System/Training/CreateController.php @@ -22,7 +22,7 @@ class CreateController extends AbstractController } #[Route('/admin/system/training/create', name: 'app_admin_system_training_create')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Request $request): Response { $training = new Training(); diff --git a/src/Controller/Admin/System/Training/DeleteController.php b/src/Controller/Admin/System/Training/DeleteController.php index 91b31dc..d778cc3 100644 --- a/src/Controller/Admin/System/Training/DeleteController.php +++ b/src/Controller/Admin/System/Training/DeleteController.php @@ -21,7 +21,7 @@ class DeleteController extends AbstractController } #[Route('/admin/system/training/delete/{id}', name: 'app_admin_system_training_delete')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Training $training, Request $request): Response { if (true === $request->isMethod('POST')) { diff --git a/src/Controller/Admin/System/Training/EditController.php b/src/Controller/Admin/System/Training/EditController.php index 9f2f34b..2a4f5e2 100644 --- a/src/Controller/Admin/System/Training/EditController.php +++ b/src/Controller/Admin/System/Training/EditController.php @@ -22,7 +22,7 @@ class EditController extends AbstractController } #[Route('/admin/system/training/edit/{id}', name: 'app_admin_system_training_edit')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Training $training, Request $request): Response { $form = $this->createForm(TrainingType::class, $training); diff --git a/src/Controller/Admin/System/Training/IndexController.php b/src/Controller/Admin/System/Training/IndexController.php index 13f203b..f741cae 100644 --- a/src/Controller/Admin/System/Training/IndexController.php +++ b/src/Controller/Admin/System/Training/IndexController.php @@ -15,7 +15,7 @@ class IndexController extends AbstractController } #[Route('/admin/system/training', name: 'app_admin_system_training_index')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(): Response { $trainings = $this diff --git a/src/Controller/Admin/System/User/IndexController.php b/src/Controller/Admin/System/User/IndexController.php index e1e29f5..3270ea0 100644 --- a/src/Controller/Admin/System/User/IndexController.php +++ b/src/Controller/Admin/System/User/IndexController.php @@ -15,7 +15,7 @@ class IndexController extends AbstractController } #[Route('/admin/system/user', name: 'app_admin_system_user_index')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(): Response { $users = $this->userRepository->getAdministrativeUsers(); diff --git a/src/Controller/Admin/Teamer/CrmSelectionsController.php b/src/Controller/Admin/Teamer/CrmSelectionsController.php index 10af5e0..62a4bdb 100644 --- a/src/Controller/Admin/Teamer/CrmSelectionsController.php +++ b/src/Controller/Admin/Teamer/CrmSelectionsController.php @@ -11,7 +11,7 @@ use Symfony\Component\Security\Http\Attribute\IsGranted; class CrmSelectionsController extends AbstractController { #[Route('/admin/teamer/crm-selections/{uuid}', name: 'app_admin_teamer_crm_selections')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Teamer $teamer): Response { return $this->render('admin/teamer/crm_selections.html.twig', [ diff --git a/src/Controller/Admin/Teamer/DeleteAccountController.php b/src/Controller/Admin/Teamer/DeleteAccountController.php index e503d5c..929645c 100644 --- a/src/Controller/Admin/Teamer/DeleteAccountController.php +++ b/src/Controller/Admin/Teamer/DeleteAccountController.php @@ -23,7 +23,7 @@ class DeleteAccountController extends AbstractController } #[Route('/admin/teamer/delete-account/{uuid}', name: 'app_admin_teamer_delete_account')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Teamer $teamer, Request $request): Response { if (true === $request->isMethod(Request::METHOD_POST)) { @@ -44,7 +44,7 @@ class DeleteAccountController extends AbstractController } #[Route('/admin/teamer/restore-account/{uuid}', name: 'app_admin_teamer_restore_account')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function restore(Teamer $teamer, Request $request): Response { if (true === $request->isMethod(Request::METHOD_POST)) { diff --git a/src/Controller/Admin/Teamer/DisableUserController.php b/src/Controller/Admin/Teamer/DisableUserController.php index 1f39983..783363c 100644 --- a/src/Controller/Admin/Teamer/DisableUserController.php +++ b/src/Controller/Admin/Teamer/DisableUserController.php @@ -22,7 +22,7 @@ class DisableUserController extends AbstractController } #[Route('/admin/teamer/disable-user/{uuid}', name: 'app_admin_teamer_disable_user')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Teamer $teamer, Request $request): Response { $user = $teamer->getUser(); @@ -50,7 +50,7 @@ class DisableUserController extends AbstractController } #[Route('/administrative/teamer/enable-user/{uuid}', name: 'app_admin_teamer_enable_user')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function enable(Teamer $teamer, Request $request): Response { $user = $teamer->getUser(); diff --git a/src/Controller/Admin/Teamer/MailingController.php b/src/Controller/Admin/Teamer/MailingController.php index c862ecd..4962089 100644 --- a/src/Controller/Admin/Teamer/MailingController.php +++ b/src/Controller/Admin/Teamer/MailingController.php @@ -39,7 +39,7 @@ class MailingController extends AbstractController * the real send goes through the confirmation modal below. */ #[Route('/admin/teamer/mailing', name: 'app_admin_teamer_mailing')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Request $request): Response { $form = $this->createMailingForm($request); @@ -82,7 +82,7 @@ class MailingController extends AbstractController * one that was parked. */ #[Route('/admin/teamer/mailing/draft', name: 'app_admin_teamer_mailing_draft', methods: ['POST'])] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function draft(Request $request): Response { $mailingDto = $this->createMailingForm($request)->getData(); @@ -93,7 +93,7 @@ class MailingController extends AbstractController } #[Route('/admin/teamer/mailing/discard', name: 'app_admin_teamer_mailing_discard')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function discard(): Response { $this->draftHandler->resetDraft(); @@ -102,7 +102,7 @@ class MailingController extends AbstractController } #[Route('/admin/teamer/mailing/confirm', name: 'app_admin_teamer_mailing_confirm', methods: ['POST'])] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function confirm(Request $request): Response { $form = $this->createMailingForm($request); @@ -119,7 +119,7 @@ class MailingController extends AbstractController } #[Route('/admin/teamer/mailing/send', name: 'app_admin_teamer_mailing_send', methods: ['POST'])] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function send(Request $request): Response { $form = $this->createMailingForm($request); diff --git a/src/Controller/Admin/Teamer/RemarksController.php b/src/Controller/Admin/Teamer/RemarksController.php index 269c3d8..4374b94 100644 --- a/src/Controller/Admin/Teamer/RemarksController.php +++ b/src/Controller/Admin/Teamer/RemarksController.php @@ -21,7 +21,7 @@ class RemarksController extends AbstractController } #[Route('/admin/teamer/remarks/{uuid}', name: 'app_admin_teamer_remarks_internal')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Teamer $teamer, Request $request): Response { $returnUrl = $this->getReturnUrl($request, 'app_administrative_teamer_index'); diff --git a/src/Controller/Admin/Teamer/SkillsController.php b/src/Controller/Admin/Teamer/SkillsController.php index 4d3371d..b2889e2 100644 --- a/src/Controller/Admin/Teamer/SkillsController.php +++ b/src/Controller/Admin/Teamer/SkillsController.php @@ -25,7 +25,7 @@ class SkillsController extends AbstractController } #[Route('/admin/teamer/skills/{uuid}', name: 'app_admin_teamer_skills')] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(Teamer $teamer, Request $request): Response { $trainings = $this->trainingRepository->getList(); diff --git a/src/Controller/Admin/Teamer/TrainingAttendance/CreateController.php b/src/Controller/Admin/Teamer/TrainingAttendance/CreateController.php index 8649c5a..7ce4f00 100644 --- a/src/Controller/Admin/Teamer/TrainingAttendance/CreateController.php +++ b/src/Controller/Admin/Teamer/TrainingAttendance/CreateController.php @@ -34,7 +34,7 @@ class CreateController extends AbstractController path: '/admin/teamer/skills/training-attendance/create/{training_id}/{teamer_id}', name: 'app_admin_teamer_skills_training_attendance_create' )] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index( #[MapEntity(mapping: ['training_id' => 'id'])] Training $training, diff --git a/src/Controller/Admin/Teamer/TrainingAttendance/DeleteController.php b/src/Controller/Admin/Teamer/TrainingAttendance/DeleteController.php index b5e4b3b..193c782 100644 --- a/src/Controller/Admin/Teamer/TrainingAttendance/DeleteController.php +++ b/src/Controller/Admin/Teamer/TrainingAttendance/DeleteController.php @@ -30,7 +30,7 @@ class DeleteController extends AbstractController path: '/admin/teamer/skills/training-attendance/delete/{uuid}', name: 'app_admin_teamer_skills_training_attendance_delete' )] - #[IsGranted('ROLE_ADMIN')] + #[IsGranted('ROLE_TEAM_ADMIN')] public function index(TrainingAttendance $attendance, Request $request): Response { if (true === $request->isMethod('POST')) { diff --git a/src/Entity/User.php b/src/Entity/User.php index ad14229..b9912a8 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -22,7 +22,7 @@ class User implements UserInterface, TimestampableEntityInterface, SoftDeletable * Assignable roles and their labels. */ public const ROLES = [ - 'ROLE_ADMIN' => 'Admin', + 'ROLE_TEAM_ADMIN' => 'Team Admin', 'ROLE_MANAGER' => 'Reisemanager', 'ROLE_HOUSE_MANAGER' => 'Hausleitung', 'ROLE_TEAMER' => 'Teamer', @@ -35,7 +35,7 @@ class User implements UserInterface, TimestampableEntityInterface, SoftDeletable * a super admin. */ public const PENDING_ROLES = [ - 'ROLE_ADMIN' => 'ROLE_ADMIN_PENDING', + 'ROLE_TEAM_ADMIN' => 'ROLE_TEAM_ADMIN_PENDING', 'ROLE_MANAGER' => 'ROLE_MANAGER_PENDING', 'ROLE_HOUSE_MANAGER' => 'ROLE_HOUSE_MANAGER_PENDING', ]; @@ -194,7 +194,7 @@ class User implements UserInterface, TimestampableEntityInterface, SoftDeletable $roles = ['ROLE_USER', ...$this->roles]; if (true === $this->isSuperAdmin()) { - $roles[] = 'ROLE_SUPER_ADMIN'; + $roles[] = 'ROLE_TEAM_SUPER_ADMIN'; } return array_unique($roles); @@ -223,7 +223,7 @@ class User implements UserInterface, TimestampableEntityInterface, SoftDeletable /** * The manually assignable roles held by the user, i.e. without the implicit ROLE_USER - * and ROLE_SUPER_ADMIN added by getRoles() and without any pending marker. Used to + * and ROLE_TEAM_SUPER_ADMIN added by getRoles() and without any pending marker. Used to * edit role assignments: saving them resolves the pending approvals. */ public function getAssignedRoles(): array @@ -283,12 +283,12 @@ class User implements UserInterface, TimestampableEntityInterface, SoftDeletable } /** - * Super admin is an elevation of ROLE_ADMIN, never a standalone grant. + * Super admin is an elevation of ROLE_TEAM_ADMIN, never a standalone grant. */ #[Assert\Callback] public function validateSuperAdmin(ExecutionContextInterface $context): void { - if (true === $this->superAdmin && false === in_array('ROLE_ADMIN', $this->roles, true)) { + if (true === $this->superAdmin && false === in_array('ROLE_TEAM_ADMIN', $this->roles, true)) { $context ->buildViolation('Nur Admins können zu Superadmins ernannt werden.') ->atPath('superAdmin') @@ -311,7 +311,7 @@ class User implements UserInterface, TimestampableEntityInterface, SoftDeletable public function getDefaultRoute(): string { - if ($this->hasRole('ROLE_ADMIN')) { + if ($this->hasRole('ROLE_TEAM_ADMIN')) { return 'app_admin_index'; } elseif ($this->hasRole('ROLE_MANAGER')) { return 'app_manager_index'; diff --git a/src/Form/UserType.php b/src/Form/UserType.php index 41a695b..492cfab 100644 --- a/src/Form/UserType.php +++ b/src/Form/UserType.php @@ -67,7 +67,7 @@ class UserType extends AbstractType }); // Super admin is an elevation of an existing role, never a grant of its own, so the - // field exists only for somebody who already holds ROLE_ADMIN - offering it to + // field exists only for somebody who already holds ROLE_TEAM_ADMIN - offering it to // anyone else would only produce the violation from User::validateSuperAdmin(). // A flag already set without the role is the exception: it has to stay editable, or // that user could not be saved at all until BusPro claims them an admin again. @@ -78,7 +78,7 @@ class UserType extends AbstractType return; } - if (false === in_array('ROLE_ADMIN', $user->getAssignedRoles(), true) && false === $user->isSuperAdmin()) { + if (false === in_array('ROLE_TEAM_ADMIN', $user->getAssignedRoles(), true) && false === $user->isSuperAdmin()) { return; } diff --git a/src/Menu/AbstractMenuBuilder.php b/src/Menu/AbstractMenuBuilder.php index d30a3ab..8fc4e07 100644 --- a/src/Menu/AbstractMenuBuilder.php +++ b/src/Menu/AbstractMenuBuilder.php @@ -19,7 +19,7 @@ abstract class AbstractMenuBuilder * Note that "app_admin_" does not match the shared "app_administrative_" routes. */ protected const AREA_ROUTE_PREFIXES = [ - 'app_admin_' => 'ROLE_ADMIN', + 'app_admin_' => 'ROLE_TEAM_ADMIN', 'app_manager_' => 'ROLE_MANAGER', 'app_house_manager_' => 'ROLE_HOUSE_MANAGER', 'app_teamer_' => 'ROLE_TEAMER', @@ -29,7 +29,7 @@ abstract class AbstractMenuBuilder * Priority order of the area roles, must stay in sync with User::getDefaultRoute(). */ protected const ROLE_PRIORITY = [ - 'ROLE_ADMIN', + 'ROLE_TEAM_ADMIN', 'ROLE_MANAGER', 'ROLE_HOUSE_MANAGER', 'ROLE_TEAMER', @@ -140,7 +140,7 @@ abstract class AbstractMenuBuilder protected function addAdminItem(ItemInterface $menu): void { - if ($this->security->isGranted('ROLE_ADMIN')) { + if ($this->security->isGranted('ROLE_TEAM_ADMIN')) { $this->addDivider($menu); $menu->addChild('zum Adminbereich', [ 'route' => 'app_admin_index', diff --git a/src/Menu/MenuBuilder.php b/src/Menu/MenuBuilder.php index 56ed8c0..957728c 100644 --- a/src/Menu/MenuBuilder.php +++ b/src/Menu/MenuBuilder.php @@ -32,7 +32,7 @@ class MenuBuilder extends AbstractMenuBuilder public function createMainMenu(array $options): ItemInterface { return match ($this->resolveArea()) { - 'ROLE_ADMIN' => $this->adminMenuBuilder->createMainMenu($options), + 'ROLE_TEAM_ADMIN' => $this->adminMenuBuilder->createMainMenu($options), 'ROLE_MANAGER' => $this->managerMenuBuilder->createMainMenu($options), 'ROLE_HOUSE_MANAGER' => $this->houseManagerMenuBuilder->createMainMenu($options), 'ROLE_TEAMER' => $this->teamerMenuBuilder->createMainMenu($options), @@ -43,7 +43,7 @@ class MenuBuilder extends AbstractMenuBuilder public function createTeamerMenu(array $options): ItemInterface { return match ($this->resolveArea()) { - 'ROLE_ADMIN' => $this->adminMenuBuilder->createTeamerMenu($options), + 'ROLE_TEAM_ADMIN' => $this->adminMenuBuilder->createTeamerMenu($options), 'ROLE_MANAGER' => $this->managerMenuBuilder->createTeamerMenu($options), default => $this->createRootElement(), }; diff --git a/src/RequiredTeamerCheck/AbstractRequiredTeamerCheck.php b/src/RequiredTeamerCheck/AbstractRequiredTeamerCheck.php index 09114ee..9c090af 100644 --- a/src/RequiredTeamerCheck/AbstractRequiredTeamerCheck.php +++ b/src/RequiredTeamerCheck/AbstractRequiredTeamerCheck.php @@ -7,7 +7,7 @@ use App\Entity\User; abstract class AbstractRequiredTeamerCheck implements RequiredTeamerCheckInterface { private const EXCLUDED_ROLES = [ - 'ROLE_ADMIN', + 'ROLE_TEAM_ADMIN', 'ROLE_MANAGER', 'ROLE_HOUSE_MANAGER', ]; diff --git a/src/Security/MyEpAuthenticator.php b/src/Security/MyEpAuthenticator.php index 034a1df..6d1109e 100644 --- a/src/Security/MyEpAuthenticator.php +++ b/src/Security/MyEpAuthenticator.php @@ -35,7 +35,7 @@ class MyEpAuthenticator extends AbstractAuthenticator * is dropped rather than stored, so that no role this application assigns a meaning * to can be set from the outside. */ - private const ELIGIBLE_ROLES = ['ROLE_ADMIN', 'ROLE_TEAMER', 'ROLE_MANAGER', 'ROLE_HOUSE_MANAGER']; + private const ELIGIBLE_ROLES = ['ROLE_TEAM_ADMIN', 'ROLE_TEAMER', 'ROLE_MANAGER', 'ROLE_HOUSE_MANAGER']; public function __construct( private readonly MyEpClient $client, diff --git a/src/Security/Voter/DispositionVoter.php b/src/Security/Voter/DispositionVoter.php index bc9877c..27d49c3 100644 --- a/src/Security/Voter/DispositionVoter.php +++ b/src/Security/Voter/DispositionVoter.php @@ -60,7 +60,7 @@ class DispositionVoter extends Voter static::CONTRACT, static::INVOICE => false === $disposition->isSkipFormalities() && ($this->security->isGranted('ROLE_ADMINISTRATIVE') || $this->assertTeamerAccess($token, $disposition)), - static::DELETE => $this->security->isGranted('ROLE_ADMIN'), + static::DELETE => $this->security->isGranted('ROLE_TEAM_ADMIN'), static::FEEDBACK => false === $disposition->isSkipFormalities() && ($this->security->isGranted('ROLE_ADMINISTRATIVE') || $this->assertHouseManagerAccess($token, $disposition)), @@ -162,7 +162,7 @@ class DispositionVoter extends Voter private function assertAdminDocumentUploadAllowed(Disposition $disposition): bool { if (false === $this->security->isGranted('ROLE_ADMINISTRATIVE') - && false === $this->security->isGranted('ROLE_ADMIN')) { + && false === $this->security->isGranted('ROLE_TEAM_ADMIN')) { return false; } diff --git a/src/Security/Voter/FeedbackVoter.php b/src/Security/Voter/FeedbackVoter.php index a690259..d216841 100644 --- a/src/Security/Voter/FeedbackVoter.php +++ b/src/Security/Voter/FeedbackVoter.php @@ -24,7 +24,7 @@ class FeedbackVoter extends Voter /** @var Feedback $feedback */ $feedback = $subject; - if (in_array('ROLE_ADMIN', $token->getRoleNames())) { + if (in_array('ROLE_TEAM_ADMIN', $token->getRoleNames())) { return true; } diff --git a/src/Security/Voter/ImpersonationVoter.php b/src/Security/Voter/ImpersonationVoter.php index 2e64668..d45e240 100644 --- a/src/Security/Voter/ImpersonationVoter.php +++ b/src/Security/Voter/ImpersonationVoter.php @@ -52,7 +52,7 @@ class ImpersonationVoter extends Voter } // Admin is the only role allowed to impersonate - if (false === $this->security->isGranted('ROLE_ADMIN')) { + if (false === $this->security->isGranted('ROLE_TEAM_ADMIN')) { return false; } diff --git a/src/Twig/AppRuntime.php b/src/Twig/AppRuntime.php index 13d39b7..c0ce112 100644 --- a/src/Twig/AppRuntime.php +++ b/src/Twig/AppRuntime.php @@ -33,7 +33,7 @@ class AppRuntime implements RuntimeExtensionInterface $user = $teamer->getUser(); if (null !== $user) { - if ($user->hasRole('ROLE_ADMIN')) { + if ($user->hasRole('ROLE_TEAM_ADMIN')) { $labelItems[] = 'Admin'; } diff --git a/templates/admin/system/user/_form.html.twig b/templates/admin/system/user/_form.html.twig index 19110e3..e34f536 100644 --- a/templates/admin/system/user/_form.html.twig +++ b/templates/admin/system/user/_form.html.twig @@ -1,6 +1,6 @@ {{ form_start(form) }}