*/ final class UserVoter extends Voter { public const string VIEW = 'USER_VIEW'; public const string CREATE = 'USER_CREATE'; public const string BLOCK = 'USER_BLOCK'; public const string UNBLOCK = 'USER_UNBLOCK'; public const string RESEND_INVITATION = 'USER_RESEND_INVITATION'; public const string MANAGE_ROLES = 'USER_MANAGE_ROLES'; private const array SUPPORTED_ATTRIBUTES = [ self::VIEW, self::CREATE, self::BLOCK, self::UNBLOCK, self::RESEND_INVITATION, self::MANAGE_ROLES, ]; #[Override] protected function supports(string $attribute, mixed $subject): bool { if (!in_array($attribute, self::SUPPORTED_ATTRIBUTES, true)) { return false; } if ($subject === null) { return true; } return $subject instanceof User || $subject instanceof UserResource; } #[Override] protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool { $user = $token->getUser(); if (!$user instanceof UserInterface) { return false; } $roles = $user->getRoles(); return match ($attribute) { self::VIEW => $this->canView($roles), self::CREATE, self::BLOCK, self::UNBLOCK, self::RESEND_INVITATION, self::MANAGE_ROLES => $this->canManage($roles), default => false, }; } /** * @param string[] $roles */ private function canView(array $roles): bool { return $this->hasAnyRole($roles, [ Role::SUPER_ADMIN->value, Role::ADMIN->value, Role::SECRETARIAT->value, ]); } /** * @param string[] $roles */ private function canManage(array $roles): bool { return $this->hasAnyRole($roles, [ Role::SUPER_ADMIN->value, Role::ADMIN->value, ]); } /** * @param string[] $userRoles * @param string[] $allowedRoles */ private function hasAnyRole(array $userRoles, array $allowedRoles): bool { foreach ($userRoles as $role) { if (in_array($role, $allowedRoles, true)) { return true; } } return false; } }