feat: sync non-privileged BusPro roles on every login
This commit is contained in:
@@ -34,10 +34,13 @@ use Symfony\Component\Security\Http\Util\TargetPathTrait;
|
||||
* Validates credentials via BPN's getPersonalData endpoint and creates or updates
|
||||
* local User entities. Passwords are stored encrypted with RSA for subsequent API calls.
|
||||
*
|
||||
* CRM attributes (roles, hotel codes) seed a *new* account only: BusPro backend users can
|
||||
* edit their own CRM selections, so taking roles over on every login would let anybody grant
|
||||
* themselves Role::PRIVILEGED here. Privileged roles are never imported at all, and from the
|
||||
* second login on both roles and hotel codes are managed by an administrator in /admin/user.
|
||||
* Roles have two owners. The non-privileged ones mirror the CRM selections on every login, in
|
||||
* both directions, so somebody who becomes (or stops being) a Teamer in BusPro is granted (or
|
||||
* loses) ROLE_TEAMER here — the sibling app myep-team gates on it. Role::PRIVILEGED is never
|
||||
* imported: BusPro backend users can edit their own CRM selections, so honouring those would
|
||||
* let anybody make themselves an administrator; they are granted in /admin/user only.
|
||||
*
|
||||
* Hotel codes still seed a *new* account only and are managed in /admin/user afterwards.
|
||||
*/
|
||||
class BpnAuthenticator extends AbstractLoginFormAuthenticator implements AuthenticationEntryPointInterface
|
||||
{
|
||||
@@ -106,15 +109,13 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
|
||||
if (null === $user = $userRepository->findOneBy(['email' => $email])) {
|
||||
$user = new User($email);
|
||||
$user
|
||||
->setRoles($this->importableRoles($email, $crmAttributes->roles))
|
||||
->setHotelCodes(array_values(array_unique($crmAttributes->hotelCodes)))
|
||||
;
|
||||
$user->setHotelCodes(array_values(array_unique($crmAttributes->hotelCodes)));
|
||||
|
||||
$this->entityManager->persist($user);
|
||||
}
|
||||
|
||||
$user
|
||||
->setRoles($this->syncedRoles($email, $user->getRoles(), $crmAttributes->roles))
|
||||
->setPassword($encryptedPassword)
|
||||
->setPersonId($personalData->personId)
|
||||
->setAddressId($personalData->addressId)
|
||||
@@ -127,6 +128,21 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the two halves of the role set: the non-privileged roles the BusPro CRM currently
|
||||
* reports, and the privileged ones an administrator granted here. Anything the CRM no
|
||||
* longer reports is dropped, so revoking a selection there revokes it here too.
|
||||
*
|
||||
* @param string[] $storedRoles
|
||||
* @param string[] $crmRoles
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function syncedRoles(string $email, array $storedRoles, array $crmRoles): array
|
||||
{
|
||||
return Role::combine($this->importableRoles($email, $crmRoles), $storedRoles);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $crmRoles
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user