feat: streamlined role-revocation logic
This commit is contained in:
1 parent
b39a78da82
commit
fd5d478a5c
14 files changed
+426
-22
No files matched your search
@@ -87,12 +87,13 @@ class CrmAttributesResponse
|
||||
{
|
||||
$crmSelections = [];
|
||||
|
||||
foreach ($this->getAttributeGroups() as $group) {
|
||||
// a response the CRM sent no attributes in still has to flatten to an empty set
|
||||
foreach ($this->getAttributeGroups() ?? [] as $group) {
|
||||
/** @var CrmAttributeGroup $group */
|
||||
if (false === isset($crmSelections[$group->getLabel()])) {
|
||||
$crmSelections[$group->getLabel()] = [];
|
||||
}
|
||||
foreach ($group->getAttributes() as $attribute) {
|
||||
foreach ($group->getAttributes() ?? [] as $attribute) {
|
||||
/** @var CrmAttribute $attribute */
|
||||
if (false === $attribute->isSelected()) {
|
||||
continue;
|
||||
|
||||
@@ -165,10 +165,11 @@ class UserDataHandler
|
||||
/**
|
||||
* Updates an existing user from BusPro data.
|
||||
*
|
||||
* Roles and hotel codes are imported once on user creation only and are managed
|
||||
* manually afterwards, so they are intentionally left untouched here. The only
|
||||
* exception are the privilege-free pending markers, which keep tracking the
|
||||
* administrative roles claimed in the CRM.
|
||||
* Administrative roles and hotel codes are imported once on user creation only and are
|
||||
* managed manually afterwards, so they are intentionally left untouched here. The
|
||||
* exceptions are the privilege-free pending markers, which keep tracking the
|
||||
* administrative roles claimed in the CRM, and ROLE_TEAMER, which needs no approval
|
||||
* and is granted to whoever the CRM reports as a teamer.
|
||||
*
|
||||
* @param string[] $claimedRoles pending markers as returned by collectPendingRoles()
|
||||
*/
|
||||
@@ -188,6 +189,8 @@ class UserDataHandler
|
||||
$this->refreshPendingRoles($user, $claimedRoles);
|
||||
|
||||
if (true === $isTeamer) {
|
||||
$this->grantTeamerRole($user);
|
||||
|
||||
$address = Address::fromApiResponse($profileResponse);
|
||||
$communication = Communication::fromApiResponse($profileResponse);
|
||||
if (null === $user->getTeamer()) {
|
||||
@@ -221,15 +224,19 @@ class UserDataHandler
|
||||
/**
|
||||
* Blocks a user the CRM no longer grants anything in this application.
|
||||
*
|
||||
* The granted roles are deliberately kept: they stay visible for review and are what
|
||||
* makes the user reappear in the administrative list, where a super admin can unblock
|
||||
* them. Only the privilege-free markers are dropped, as they no longer reflect the CRM.
|
||||
* The granted roles are deliberately kept: they stay visible for review. Only the
|
||||
* privilege-free markers are dropped, as they no longer reflect the CRM. What keeps the
|
||||
* user reachable is the block itself, not the roles: a teamer stays in the teamer list,
|
||||
* everyone else is listed by getAdministrativeUsers() whatever roles are left.
|
||||
* Regaining a CRM role does not unblock the account, that is a manual decision.
|
||||
*/
|
||||
public function disableForRevokedCrmRoles(User $user): void
|
||||
{
|
||||
// an existing block may be a disciplinary one and must never be overwritten
|
||||
// an existing block may be a disciplinary one and must never be overwritten, but
|
||||
// findLocalUser() may have refreshed the BusPro ids and nothing else flushes here
|
||||
if (true === $user->isDisabled()) {
|
||||
$this->entityManager->flush();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -249,6 +256,33 @@ class UserDataHandler
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grants ROLE_TEAMER to a user the CRM reports as a teamer.
|
||||
*
|
||||
* Unlike the administrative roles this one needs no approval, so it may be granted on
|
||||
* any login rather than on creation only: it carries no privileges beyond the teamer
|
||||
* area, and a teamer without it would be left with a teamer record they cannot reach,
|
||||
* or locked out entirely for holding no assignable role at all.
|
||||
*
|
||||
* It is never withdrawn here. Losing the CRM attribute while holding no other role
|
||||
* blocks the account anyway, and a role handed out manually must survive a login.
|
||||
*/
|
||||
private function grantTeamerRole(User $user): void
|
||||
{
|
||||
$grantedRoles = $user->getAssignedRoles();
|
||||
|
||||
if (true === in_array('ROLE_TEAMER', $grantedRoles, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user->setRoles([...$grantedRoles, 'ROLE_TEAMER', ...$user->getPendingRoles()]);
|
||||
|
||||
$this->logger->info('Grant teamer role', [
|
||||
'user_id' => $user->getId(),
|
||||
'user_email' => $user->getEmail(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps the pending markers in sync with the administrative roles claimed in the CRM.
|
||||
* The markers grant no privileges, so tracking them on every login is safe: only a
|
||||
|
||||
Reference in new issue
Block a user