feat: bpn as single source of truth for role and hotel code assignments
This commit is contained in:
@@ -128,8 +128,15 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
// Determine teamer status from CRM attributes
|
||||
$isTeamer = $crmAttributes->isTeamer();
|
||||
|
||||
// Everything the CRM grants this person here: pending markers plus ROLE_TEAMER
|
||||
// What the CRM claims, as plain role names, and what this application makes of it:
|
||||
// pending markers plus ROLE_TEAMER. The first drives the sync, the second is what
|
||||
// a new account starts with.
|
||||
$claimedRoles = $this
|
||||
->userDataHandler
|
||||
->collectClaimedRoles($crmAttributes)
|
||||
;
|
||||
|
||||
$grantedRoles = $this
|
||||
->userDataHandler
|
||||
->collectRoles($crmAttributes)
|
||||
;
|
||||
@@ -180,8 +187,8 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
return $user;
|
||||
}
|
||||
|
||||
// Update existing user's teamer data and return it, leaving roles and hotel
|
||||
// codes alone: they are imported once on creation and managed manually after
|
||||
// Update the existing user, re-syncing roles and hotel codes from the CRM: it
|
||||
// leads, so a role or a house it no longer reports is withdrawn here
|
||||
if (null !== $user) {
|
||||
$this
|
||||
->userDataHandler
|
||||
@@ -190,7 +197,8 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
$profileResponse,
|
||||
$isTeamer,
|
||||
$crmSelections,
|
||||
$this->userDataHandler->collectPendingRoles($crmAttributes),
|
||||
$claimedRoles,
|
||||
$crmAttributes->getHotelCodes(),
|
||||
)
|
||||
;
|
||||
|
||||
@@ -202,7 +210,7 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
->userDataHandler
|
||||
->createLocalUser(
|
||||
$profileResponse,
|
||||
$claimedRoles,
|
||||
$grantedRoles,
|
||||
$isTeamer,
|
||||
$crmSelections,
|
||||
$crmAttributes->getHotelCodes(),
|
||||
|
||||
@@ -161,6 +161,7 @@ class MyEpAuthenticator extends AbstractAuthenticator
|
||||
|
||||
$isTeamer = in_array('ROLE_TEAMER', $claimedRoles, true);
|
||||
$pendingRoles = $this->userDataHandler->toPendingRoles($claimedRoles);
|
||||
$hotelCodes = $this->collectHotelCodes($userinfo);
|
||||
|
||||
$user = $this->findLocalUser($userinfo);
|
||||
|
||||
@@ -177,23 +178,20 @@ class MyEpAuthenticator extends AbstractAuthenticator
|
||||
return $user;
|
||||
}
|
||||
|
||||
// Update existing user, leaving granted roles and hotel codes alone: they are
|
||||
// imported once on creation and managed manually afterwards. Only the
|
||||
// privilege-free markers and ROLE_TEAMER track MyE&P on every login.
|
||||
// Update existing user. MyE&P leads here exactly as BusPro does on the other login
|
||||
// path - the shared policy in UserDataHandler withdraws what is no longer claimed
|
||||
// and marks administrative claims for approval rather than granting them.
|
||||
if (null !== $user) {
|
||||
$this->refreshBusProIds($user, $userinfo);
|
||||
$this->userDataHandler->refreshPendingRoles($user, $pendingRoles);
|
||||
|
||||
if (true === $isTeamer) {
|
||||
$this->userDataHandler->grantTeamerRole($user);
|
||||
}
|
||||
$this->userDataHandler->syncRoles($user, $claimedRoles);
|
||||
$this->userDataHandler->syncHotelCodes($user, $hotelCodes);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
return $this->createLocalUser($userinfo, $pendingRoles, $isTeamer);
|
||||
return $this->createLocalUser($userinfo, $pendingRoles, $isTeamer, $hotelCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,6 +231,19 @@ class MyEpAuthenticator extends AbstractAuthenticator
|
||||
return $claimedRoles;
|
||||
}
|
||||
|
||||
/**
|
||||
* The houses MyE&P reports for this person. Read on both the create and the update
|
||||
* path, since they are led by the identity provider just like the roles are.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function collectHotelCodes(array $userinfo): array
|
||||
{
|
||||
$profile = is_array($userinfo['profile'] ?? null) ? $userinfo['profile'] : [];
|
||||
|
||||
return is_array($profile['hotel_codes'] ?? null) ? array_values($profile['hotel_codes']) : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the local account on the BusPro ids first and falls back to the email, the
|
||||
* same precedence UserDataHandler::findLocalUser() applies to a BusPro login, so that
|
||||
@@ -300,8 +311,9 @@ class MyEpAuthenticator extends AbstractAuthenticator
|
||||
|
||||
/**
|
||||
* @param string[] $pendingRoles
|
||||
* @param string[] $hotelCodes
|
||||
*/
|
||||
private function createLocalUser(array $userinfo, array $pendingRoles, bool $isTeamer): ?User
|
||||
private function createLocalUser(array $userinfo, array $pendingRoles, bool $isTeamer, array $hotelCodes): ?User
|
||||
{
|
||||
$addressId = $userinfo['address_id'] ?? null;
|
||||
$personId = $userinfo['person_id'] ?? null;
|
||||
@@ -318,7 +330,6 @@ class MyEpAuthenticator extends AbstractAuthenticator
|
||||
}
|
||||
|
||||
$profile = is_array($userinfo['profile'] ?? null) ? $userinfo['profile'] : [];
|
||||
$hotelCodes = is_array($profile['hotel_codes'] ?? null) ? $profile['hotel_codes'] : [];
|
||||
|
||||
$user = new User();
|
||||
$user
|
||||
|
||||
Reference in New Issue
Block a user