feat: admin-managed roles and hotel codes
This commit is contained in:
@@ -31,9 +31,13 @@ use Symfony\Component\Security\Http\Util\TargetPathTrait;
|
||||
/**
|
||||
* Authenticates users against the BPN API.
|
||||
*
|
||||
* Validates credentials via BPN's getPersonalData endpoint, creates or updates
|
||||
* local User entities, and retrieves CRM attributes (roles, hotel codes) for
|
||||
* authorization. Passwords are stored encrypted with RSA for subsequent API calls.
|
||||
* 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.
|
||||
*/
|
||||
class BpnAuthenticator extends AbstractLoginFormAuthenticator implements AuthenticationEntryPointInterface
|
||||
{
|
||||
@@ -96,15 +100,17 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
throw new CustomUserMessageAuthenticationException($message);
|
||||
}
|
||||
|
||||
$roles = $crmAttributes->roles;
|
||||
$hotelCodes = $crmAttributes->hotelCodes;
|
||||
|
||||
$encryptedPassword = $this->crypt->encrypt($password);
|
||||
|
||||
$userRepository = $this->entityManager->getRepository(User::class);
|
||||
|
||||
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)))
|
||||
;
|
||||
|
||||
$this->entityManager->persist($user);
|
||||
}
|
||||
|
||||
@@ -112,8 +118,6 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
->setPassword($encryptedPassword)
|
||||
->setPersonId($personalData->personId)
|
||||
->setAddressId($personalData->addressId)
|
||||
->setRoles($roles)
|
||||
->setHotelCodes($hotelCodes)
|
||||
->setLastLoginAt(new \DateTimeImmutable())
|
||||
->setProfileComplete($this->completenessChecker->isComplete($personalData))
|
||||
;
|
||||
@@ -123,6 +127,28 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $crmRoles
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function importableRoles(string $email, array $crmRoles): array
|
||||
{
|
||||
$roles = Role::filterImportable($crmRoles);
|
||||
$dropped = array_values(array_intersect($crmRoles, Role::PRIVILEGED));
|
||||
|
||||
if ([] !== $dropped) {
|
||||
// Somebody holds a privileged CRM selection in BusPro. We do not honour it, but it
|
||||
// should stay visible: it either needs to be revoked there or granted in /admin/user.
|
||||
$this->authLogger->warning('Ignored privileged roles from BPN CRM attributes', [
|
||||
'email' => $email,
|
||||
'roles' => $dropped,
|
||||
]);
|
||||
}
|
||||
|
||||
return $roles;
|
||||
}
|
||||
|
||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
|
||||
{
|
||||
$this->authLogger->info('Login', [
|
||||
|
||||
Reference in New Issue
Block a user