feat: pending roles from crm to be confirmed by superadmins
This commit is contained in:
@@ -64,8 +64,7 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
}
|
||||
|
||||
// Final checks and local user loading/creation
|
||||
$preferredRole = $request->request->get('_role');
|
||||
$user = $this->getOrCreateLocalUser($response, $email, $password, $preferredRole);
|
||||
$user = $this->getOrCreateLocalUser($response, $email, $password);
|
||||
|
||||
if (null === $user) {
|
||||
return null;
|
||||
@@ -110,7 +109,6 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
ProfileResponse $profileResponse,
|
||||
string $email,
|
||||
string $password,
|
||||
?string $preferredRole,
|
||||
): ?User {
|
||||
// Fetch CRM attributes, early return in case of an API error
|
||||
try {
|
||||
@@ -120,24 +118,6 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
return null;
|
||||
}
|
||||
|
||||
// Collect user's roles from CRM attributes
|
||||
$roles = $this
|
||||
->userDataHandler
|
||||
->collectRoles($crmAttributes, $preferredRole)
|
||||
;
|
||||
|
||||
// User is expected to have at least one role
|
||||
if (0 === count($roles)) {
|
||||
// Revoke roles on existing local user to invalidate any active session
|
||||
$existingUser = $this->userDataHandler->findLocalUser($profileResponse);
|
||||
if (null !== $existingUser) {
|
||||
$existingUser->setRoles([]);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Flatten selected CRM attributes
|
||||
$crmSelections = $crmAttributes->toArray();
|
||||
|
||||
@@ -150,19 +130,33 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
->findLocalUser($profileResponse)
|
||||
;
|
||||
|
||||
// Update existing user's roles and teamer data and return it
|
||||
// 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
|
||||
if (null !== $user) {
|
||||
$this
|
||||
->userDataHandler
|
||||
->updateLocalUser($user, $profileResponse, $roles, $isTeamer, $crmSelections, $crmAttributes->getHotelCodes())
|
||||
->updateLocalUser(
|
||||
$user,
|
||||
$profileResponse,
|
||||
$isTeamer,
|
||||
$crmSelections,
|
||||
$this->userDataHandler->collectPendingRoles($crmAttributes),
|
||||
)
|
||||
;
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
// Initial import of roles and hotel codes on user creation
|
||||
return $this
|
||||
->userDataHandler
|
||||
->createLocalUser($profileResponse, $roles, $isTeamer, $crmSelections, $crmAttributes->getHotelCodes())
|
||||
->createLocalUser(
|
||||
$profileResponse,
|
||||
$this->userDataHandler->collectRoles($crmAttributes),
|
||||
$isTeamer,
|
||||
$crmSelections,
|
||||
$crmAttributes->getHotelCodes(),
|
||||
)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,6 @@ use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
class UserChecker implements UserCheckerInterface
|
||||
{
|
||||
private const APPLICATION_ROLES = [
|
||||
'ROLE_ADMIN',
|
||||
'ROLE_MANAGER',
|
||||
'ROLE_HOUSE_MANAGER',
|
||||
'ROLE_TEAMER',
|
||||
];
|
||||
|
||||
public function checkPreAuth(UserInterface $user): void
|
||||
{
|
||||
if (!$user instanceof User) {
|
||||
@@ -26,7 +19,11 @@ class UserChecker implements UserCheckerInterface
|
||||
throw new CustomUserMessageAccountStatusException('Dein Account wurde gesperrt: '.$user->getDisabledReason());
|
||||
}
|
||||
|
||||
if ([] === array_intersect($user->getRoles(), self::APPLICATION_ROLES)) {
|
||||
if ([] === array_intersect($user->getRoles(), array_keys(User::ROLES))) {
|
||||
if ([] !== $user->getPendingRoles()) {
|
||||
throw new CustomUserMessageAccountStatusException('Deine Rolle wurde noch nicht freigeschaltet.');
|
||||
}
|
||||
|
||||
throw new CustomUserMessageAccountStatusException('Keine gültige Rolle zugewiesen.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Security\Voter;
|
||||
|
||||
use App\Entity\User;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
|
||||
class UserVoter extends Voter
|
||||
{
|
||||
public const EDIT = 'CAN_EDIT_USER';
|
||||
|
||||
public function __construct(private readonly Security $security)
|
||||
{
|
||||
}
|
||||
|
||||
protected function supports(string $attribute, mixed $subject): bool
|
||||
{
|
||||
return self::EDIT === $attribute && $subject instanceof User;
|
||||
}
|
||||
|
||||
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
|
||||
{
|
||||
$currentUser = $token->getUser();
|
||||
$targetUser = $subject;
|
||||
|
||||
if (!$currentUser instanceof User || !$targetUser instanceof User) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// editing your own roles or super admin flag is not allowed
|
||||
if ($currentUser === $targetUser) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the current user is impersonating, do not grant access
|
||||
if ($this->security->isGranted('IS_IMPERSONATOR')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $currentUser->isSuperAdmin();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user