<?php
namespace App\Security\Voter;
use App\Entity\User;
use App\Repository\UserRepository;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
class UserVoter extends Voter
{
public const EDIT = 'USER_EDIT';
public const VIEW = 'USER_VIEW';
public const ADD = 'USER_ADD';
public const DELETE = 'USER_DELETE';
public const CAN_BLOCK = 'USER_CAN_BLOCK';
public const CAN_RESET_PASSWORD = 'USER_CAN_RESET_PSWD';
public const CHANGE_COMPANY = 'USER_CHANGE_COMPANY';
public const ASSIGN_COMPANY_ADMIN = 'USER_ASSIGN_COMPANY_ADMIN';
public const ASSIGN_ADMIN = 'USER_ASSIGN_ADMIN';
/**
* @var Security
*/
protected $_security;
/**
* @var UserRepository
*/
protected $_userRepository;
/**
* @param Security $_security
*/
public function __construct(Security $_security, UserRepository $userRepository)
{
$this->_security = $_security;
$this->_userRepository = $userRepository;
}
protected function supports(string $attribute, $subject): bool
{
return in_array($attribute, [
self::EDIT,
self::VIEW,
self::ADD,
self::CAN_BLOCK,
self::CHANGE_COMPANY,
self::ASSIGN_COMPANY_ADMIN,
self::ASSIGN_ADMIN,
self::CAN_RESET_PASSWORD,
self::DELETE
]);
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
if ($this->_security->isGranted(User::ROLE_ADMIN)) {
return true;
}
$user = $token->getUser();
// if the user is anonymous, do not grant access
if (!$user instanceof UserInterface) {
return false;
}
$userForEdit = $subject;
// ... (check conditions and return true to grant permission) ...
switch ($attribute) {
case self::EDIT:
return $this->canEdit($user, $userForEdit);
case self::VIEW:
return $this->canView($user, $userForEdit);
case self::ADD:
return $this->canAdd($user);
case self::CAN_BLOCK:
return $this->canBlock($user, $userForEdit);
case self::CAN_RESET_PASSWORD:
return $this->canResetPassword($user, $userForEdit);
case self::CHANGE_COMPANY:
return $this->canChangeCompany($user, $userForEdit);
case self::ASSIGN_COMPANY_ADMIN:
return $this->canAssignCompanyAdmin($user, $userForEdit);
case self::ASSIGN_ADMIN:
return $this->canAssignAdmin($user, $userForEdit);
case self::DELETE:
return $this->canDelete($user, $userForEdit);
}
return false;
}
/**
* @param User $user
* @param User $userForEdit
* @return bool
*/
protected function canDelete(UserInterface $user, User $userForEdit)
{
if ($user->hasRole(User::ROLE_COMPANY_ADMIN)) {
return true;
}
return false;
}
/**
* @param User $user
* @param User $userForEdit
* @return bool
*/
protected function canBlock(UserInterface $user, User $userToBlock)
{
if ($user->hasRole(User::ROLE_COMPANY_ADMIN)) {
return true;
}
if($user->hasRole(User::ROLE_MERCHANT)){
$idsJuniors = [];
$this->_userRepository->getJuniorIdsRecursivly($user, $idsJuniors);
return in_array($user->getId(), $idsJuniors) || $user->getId() === $userToBlock->getId();
}
return false;
}
/**
* @param User $user
* @param User $userForEdit
* @return bool
*/
protected function canResetPassword(UserInterface $user, User $userToBlock)
{
if ($user->hasRole(User::ROLE_COMPANY_ADMIN)) {
return true;
}
if($user->hasRole(User::ROLE_MERCHANT)){
$idsJuniors = [];
$this->_userRepository->getJuniorIdsRecursivly($user, $idsJuniors);
return in_array($user->getId(), $idsJuniors) || $user->getId() === $userToBlock->getId();
}
return false;
}
/**
* @param User $user
* @param User $userForEdit
* @return bool
*/
protected function canEdit(UserInterface $user, User $userForEdit)
{
if ($user->hasRole(User::ROLE_COMPANY_ADMIN)) {
return true;
}
if ($user->hasRole(User::ROLE_COMPANY_USER)) {
return true;
}
if($user->hasRole(User::ROLE_MERCHANT)){
$idsJuniors = [];
$this->_userRepository->getJuniorIdsRecursivly($user, $idsJuniors);
return in_array($user->getId(), $idsJuniors) || $user->getId() === $userForEdit->getId();
}
if ($user->hasRole(User::ROLE_CUSTOMER)
) {
return $user->getId() === $userForEdit->getId();
}
return false;
}
/**
* @param User $user
* @param User $userForEdit
* @return bool
*/
protected function canView(UserInterface $user, User $userForEdit)
{
if ($user->hasRole(User::ROLE_COMPANY_ADMIN)) {
return true;
}
if($user->hasRole(User::ROLE_MERCHANT)){
$idsJuniors = [];
$this->_userRepository->getJuniorIdsRecursivly($user, $idsJuniors);
return in_array($user->getId(), $idsJuniors) || $user->getId() === $userForEdit->getId();
}
if (
$user->hasRole(User::ROLE_COMPANY_USER) ||
$user->hasRole(User::ROLE_CUSTOMER)
) {
return $user->getId() === $userForEdit->getId();
}
return false;
}
/**
* @param User $user
* @param User $userForEdit
* @return bool
*/
protected function canAdd(UserInterface $user)
{
if ($user->hasRole(User::ROLE_COMPANY_ADMIN)) {
return true;
}
return false;
}
/**
* @param User $user
* @param User|null $userForEdit
* @return bool
*/
protected function canChangeCompany(UserInterface $user, $userForEdit)
{
return false;
}
/**
* @param User $user
* @param User|null $userForEdit
* @return bool
*/
protected function canAssignCompanyAdmin(UserInterface $user, $userForEdit)
{
if($user->hasRole(User::ROLE_COMPANY_ADMIN)){
return true;
}
return false;
}
/**
* @param User $user
* @param User|null $userForEdit
* @return bool
*/
protected function canAssignAdmin(UserInterface $user, $userForEdit)
{
return false;
}
}