<?php
namespace App\System\Voter\User;
use App\Entities\Rights\Right;
use App\Entities\Rights\Rights;
use App\Entities\User\UserAccess;
use App\Entities\User\UserInterface;
use App\UseCase\User\Read\Access\Integration\IsMainSystemIntegrationHandler;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class UserRightVoter extends Voter
{
public function __construct(
private readonly IsMainSystemIntegrationHandler $isMainSystemIntegrationHandler,
) {
}
protected function supports(string $attribute, mixed $subject): bool
{
return in_array(
$attribute,
[
Rights::ServicesView->value,
Rights::ServicesViewZpModel->value,
Rights::ServicesEdit->value,
Rights::FinAdminView->value,
Rights::FinAdminViewZpModel->value,
Rights::FinAdminEditPercent->value,
Rights::FinAdminEditFine->value,
Rights::FinAdminEditBonus->value,
Rights::PayoutView->value,
Rights::PayoutEdit->value,
Rights::MopView->value,
Rights::MopViewModelFio->value,
Rights::MopViewOperatorFio->value,
Rights::MopNotViewModelAndOperatorFio->value,
Rights::OperatorView->value,
Rights::OperatorViewZpOperator->value,
Rights::OperatorEditBonus->value,
Rights::OperatorEditFine->value,
Rights::OperatorEditTotal->value,
Rights::OperatorEditPercent->value,
Rights::OperatorViewModelFio->value,
Rights::MainSystemIntegration->value,
],
true
);
}
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof UserInterface) {
return false;
}
if ($user->isAdmin()) {
return true;
}
if ($this->isMainSystemIntegrationHandler->__invoke($user) && $attribute === Rights::MainSystemIntegration->value) {
return true;
}
/** @var UserAccess $user */
if (!$rights = $user->getRights()) {
return false;
}
$rights = $rights->toArray();
return match ($attribute) {
Rights::MopView->value =>
$this->checkRight($rights, Rights::MopViewModelFio->value)
|| $this->checkRight($rights, Rights::MopViewOperatorFio->value)
|| $this->checkRight($rights, Rights::MopNotViewModelAndOperatorFio->value),
Rights::MopViewModelFio->value =>
$this->checkRight($rights, Rights::MopViewModelFio->value)
&& !$this->checkRight($rights, Rights::MopNotViewModelAndOperatorFio->value),
Rights::MopViewOperatorFio->value =>
$this->checkRight($rights, Rights::MopViewOperatorFio->value)
&& !$this->checkRight($rights, Rights::MopNotViewModelAndOperatorFio->value),
default => $this->checkRight($rights, $attribute),
};
}
/**
* @param array<Right> $rights
* @param string $rightCode
*
* @return bool
*/
private function checkRight(array $rights, string $rightCode): bool
{
return !empty(array_filter($rights, fn(Right $right) => $right->getCode() === $rightCode));
}
}