<?php
namespace App\Security\Voter;
use App\Entity\Eg\Admin\Role;
use App\Entity\Eg\Admin\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
/**
* Decyduje o dostępie do konta użytkownika. Dwie reguły:
* VIEW - rola okna "Użytkownicy" albo własne konto
* CHANGE_PASSWORD - własne konto albo rola edycji użytkowników
* Wyjątek na własne konto jest konieczny przez "Zmień hasło" w menu użytkownika
*/
final class UserVoter extends Voter
{
public const VIEW = 'EG_USER_VIEW';
public const CHANGE_PASSWORD = 'EG_USER_CHANGE_PASSWORD';
public const ATTRIBUTES = [self::VIEW, self::CHANGE_PASSWORD];
public function __construct(private readonly Security $security)
{
}
protected function supports(string $attribute, $subject): bool
{
return \in_array($attribute, self::ATTRIBUTES, true);
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
if ($this->isOwnAccount($subject, $token)) {
return true;
}
if ($attribute === self::CHANGE_PASSWORD) {
// Cudze hasło może zmienić tylko ten, kto może edytować użytkowników.
return $this->security->isGranted(Role::ROLE_USERS_EDIT);
}
return $this->security->isGranted(Role::ROLE_USERS_VIEW);
}
private function isOwnAccount($subject, TokenInterface $token): bool
{
if (!$subject instanceof User) {
return false;
}
$current = $token->getUser();
return $current instanceof User
&& $current->getId() !== null
&& $current->getId() === $subject->getId();
}
}