<?php
namespace App\Security;
use App\Entity\MajDossier;
use App\Entity\PracticalFile;
use App\Entity\User;
use App\Service\UserManager;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* Voter pour l'article et fiche Pratique
*
* @author Ismail mezrani <[email protected]>
*/
class IcoVoter extends Voter
{
const APP_PERMISSION_PREFIX = 'ICO_';
/**
* Cache facultatif des permissions (la session de l'utilisateur courant par défaut)
*
* @var \Symfony\Component\HttpFoundation\Session\Session
*/
protected $session;
/**
* Manager des utilisateurs
* @var \App\Service\UserManager
*/
protected $userManager;
/**
* @var AuthorizationCheckerInterface
*/
protected $authorizationChecker;
/**
* Constructeur du voteur
*
* @param UserManager $userManager Manager des utilisateurs
* @param mixed $session Session
*/
public function __construct(UserManager $userManager, SessionInterface $session, AuthorizationCheckerInterface $authorizationChecker)
{
$this->userManager = $userManager;
$this->session = $session;
$this->authorizationChecker = $authorizationChecker;
}
/**
* @inheritdoc
*/
protected function supports($attribute, $subject)
{
return 0 === strpos($attribute, self::APP_PERMISSION_PREFIX);
}
/**
* @inheritdoc
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
if ($user->isAdmin()) {
return true;
}
switch ($attribute) {
case 'ICO_IMPORT_WORD_EZP':
$can = $this->canImportWordEzp($user, $attribute, $subject);
break;
case 'ICO_DOWNLOAD_MANUSCRIT_TOOLS':
$can = $this->canDownloadManuscritTools($subject);
break;
case 'ICO_VIEW_DROPZONE':
$can = $this->canViewDropzone($subject);
break;
default:
$can = $this->hasPermission($user, $attribute);
}
return $can;
}
/**
* Si un utilisateur peut importer un manuscrit depuis EZP
* Dans le contexte d'une fiche, la fiche doit être à l'étape en ligne.
*
* @param PracticalFile|MajDossier $subject
*/
protected function canImportWordEzp(User $user, string $permission, $subject): bool
{
$can = $this->hasPermission($user, $permission);
if ($subject instanceof PracticalFile) {
$can = $can && $subject->getCurrentStep()->getCode() === 'fiche_en_ligne';
}
return $can;
}
/**
* Si un utilisateur peut voir la dropzone d'upload du manuscrit et des outils
*/
protected function canViewDropzone(PracticalFile $practicalFile): bool
{
$currentStepCode = $practicalFile->getCurrentStep()->getCode();
return ($this->authorizationChecker->isGranted('ROLE_AUTEUR_FICHE') && $currentStepCode === 'fiche_en_ecriture')
|| ($this->authorizationChecker->isGranted('ROLE_ED-COORDINATEUR') && in_array($currentStepCode, ['fiche_en_ecriture', 'fiche_en_validation']))
|| $this->authorizationChecker->isGranted('ROLE_EDITEUR')
|| $this->authorizationChecker->isGranted('ROLE_CHARGE_PUBLICATION')
|| $this->authorizationChecker->isGranted('ROLE_PREPARATEUR')
;
}
/**
* Si un utilisateur peut télécharger le manuscrit et les outils d'une fiche dans le context d'une fiche
* ou d'une maj dossier
*/
protected function canDownloadManuscritTools(?PracticalFile $practicalFile = null): bool
{
if (!$practicalFile) {
return $this->authorizationChecker->isGranted('ROLE_AUTEUR_FICHE')
|| $this->authorizationChecker->isGranted('ROLE_ED-COORDINATEUR')
|| $this->authorizationChecker->isGranted('ROLE_COMPOSITEUR');
} else {
$currentStepCode = $practicalFile->getCurrentStep()->getCode();
return ($this->authorizationChecker->isGranted('ROLE_AUTEUR_FICHE') && $currentStepCode === 'fiche_en_ecriture')
|| ($this->authorizationChecker->isGranted('ROLE_ED-COORDINATEUR') && in_array($currentStepCode, ['fiche_en_ecriture', 'fiche_en_validation']))
|| ($this->authorizationChecker->isGranted('ROLE_COMPOSITEUR') && $currentStepCode === 'fiche_en_saisie');
}
}
/**
* Vérifie que l'utilisateur courant possède une autorisation
*
* @param User $user Utilisateur courant
* @param string $attribute Attribut contenant la permission à verifier sous la forme (ROLE_CODEPERMISSION)
* @return boolean
*/
protected function hasPermission(User $user, $attribute)
{
// On récupère les permissions de l'utilisateur courant
$userPermissions = $this->session ? $this->session->get('user-permissions', false) : false;
if ($userPermissions === false) {
$userPermissions = $this->userManager->getUserPermissions($user);
// Cache en session
if ($this->session) {
$this->session->set('user-permissions', $userPermissions);
}
}
return in_array($attribute, $userPermissions);
}
}