<?php
namespace App\Security\Voter;
use App\Entity\Profile\Profile;
use App\Entity\User\User;
use App\Enums\Constants;
use App\Repository\User\RoleRepository;
use App\Service\AuthenticationService;
use App\Service\ProfileService;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface;
class ProfileVoter extends Voter
{
private const PROFILE_ACCESS = 'PROFILE_ACCESS';
private const PROFILE_OWNER = 'PROFILE_OWNER';
private const PROFILE_ADMIN = 'PROFILE_ADMIN';
private const PROFILE_EDITOR = 'PROFILE_EDITOR';
private const PROFILE_ANALYTIC = 'PROFILE_ANALYTIC';
/**
* @var ProfileService
*/
private $profileService;
/**
* @var RoleRepository
*/
private $roleRepository;
/** @var AuthenticationService */
private $authenticationService;
public function __construct(
ProfileService $profileService,
RoleRepository $roleRepository,
AuthenticationService $authenticationService
)
{
$this->profileService = $profileService;
$this->roleRepository = $roleRepository;
$this->authenticationService = $authenticationService;
}
protected function supports($attribute, $subject)
{
return in_array($attribute, [
self::PROFILE_ACCESS,
self::PROFILE_OWNER,
self::PROFILE_ADMIN,
self::PROFILE_EDITOR,
self::PROFILE_ANALYTIC,
], true) && $subject instanceof Profile;
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
if($_ENV['CWR_ENVIROMENT'] === "local"){
return true;
}
/** @var User $user */
$user = $token->getUser();
// if the user is anonymous, do not grant access
if (!$user instanceof UserInterface) {
return false;
}
if($this->authenticationService->userIsMmpzServiceAdmin($user)){
return true;
}
switch ($attribute) {
case self::PROFILE_ACCESS:
return $this->profileService->userCanAccessProfile($user, $subject);
case self::PROFILE_OWNER:
$ownerRole = $this->roleRepository->findOneByName(Constants::PROFILE_ROLE_NAME_OWNER);
return
$this->profileService->roleSupportedBetweenUserAndProfile($user, $subject, $ownerRole);
case self::PROFILE_ADMIN:
$adminRole = $this->roleRepository->findOneByName(Constants::PROFILE_ROLE_NAME_ADMIN);
return
$this->profileService->roleSupportedBetweenUserAndProfile($user, $subject, $adminRole);
case self::PROFILE_EDITOR:
$editorRole = $this->roleRepository->findOneByName(Constants::PROFILE_ROLE_NAME_EDITOR);
return
$this->profileService->checkTheRolByUserInAProfile($subject, $user);
case self::PROFILE_ANALYTIC:
$role = $this->profileService->checkTheRolByUserInAProfile($subject, $user);
if($role->getName() !== Constants::PROFILE_ROLE_NAME_EDITOR){
return true;
}
}
return false;
}
}