<?php
namespace App\Security;
use App\Entity\Utilisateur;
use Doctrine\DBAL\Connection;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* Gestion des permissions utilisateur
*/
class PermissionsVoter extends Voter
{
public const CREATE = 'create';
public const EDIT = 'edit';
/** @var Connection $dbconn */
private $dbconn;
private $activeStructure;
private $userLevel;
public function __construct(Connection $dbconn, RequestStack $requestStack)
{
$this->dbconn = $dbconn;
$session = $requestStack->getSession();
$this->activeStructure = $session->get('activeStructure');
$this->userLevel = $session->get('userLevel');
}
/**
* {@inheritdoc}
*/
protected function supports(string $attribute, $subject): bool
{
// if the attribute isn't one we support, return false
if (!in_array($attribute, [self::CREATE, self::EDIT])) {
return false;
}
$subject = (array) $subject;
if (!in_array($subject[0], ['antenne', 'couveuse', 'entrepreneur'])) {
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof Utilisateur) {
// the user must be logged in; if not, deny access
return false;
}
switch ($attribute) {
case self::CREATE:
return $this->canCreate($user, $subject);
case self::EDIT:
return $this->canEdit($user, ...$subject);
}
throw new \LogicException('This code should not be reached!');
}
/** @param Utilisateur $user */
private function canCreate($user, $subject)
{
// 10 UCE
// 20 Couveuse/Pépinière
// 30 Antenne couveuse
// 100 Entrepreneur
$level = null;
$lvlMax = null;
switch ($subject) {
case 'antenne':
$level = 30;
$lvlMax = 0;
break;
case 'couveuse':
$level = 20;
$lvlMax = 0;
break;
case 'entrepreneur':
$level = 30;
$lvlMax = 10;
break;
}
if (
$this->userLevel == 'admin'
&& $this->activeStructure->getNiveau() < $level
&& $this->activeStructure->getNiveau() > $lvlMax
) {
return true;
}
$query = '
SELECT *
FROM structure s, utilisateur_structure us
WHERE us.idstructure = s.idstructure
AND s.idparent = ' . $this->activeStructure->getIdstructure() . '
AND us.idutilisateur = ' . $user->getId();
$droits = $this->dbconn->fetchAllAssociative($query);
if ($subject != 'couveuse') {
return !empty($droits);
}
return false;
}
/** @param Utilisateur $user */
private function canEdit($user, $subject, $id)
{
$canEdit = false;
if ($this->userLevel == 'admin') {
return true;
}
if ($subject != 'entrepreneur') {
$query = 'SELECT * FROM structure s, ' . $subject . ' e, utilisateur_structure us WHERE us.idstructure = s.idstructure AND s.idstructure = e.idstructure AND id' . $subject . ' = ' . $id . ' AND us.idutilisateur = ' . $user->getId();
$structure = $this->dbconn->fetchAssociative($query);
// L'utilisateur peut modifier une antenne si il en fait partie
if ($subject == 'antenne') {
if ($structure) {
$canEdit = true;
}
}
// L'utilisateur peut modifier une couveuse si il en admin
else {
if ($structure['isadmin'] == 't') {
$canEdit = true;
}
}
}
// L'utilisateur peut modifier un entrepreneur si il en admin
else {
$query = 'SELECT us.isadmin FROM structure s, utilisateur_structure us, utilisateur u, entrepreneur e WHERE us.idstructure = s.idstructure AND s.idstructure = e.idstructure AND u.id = e.idutilisateur AND e.identrepreneur = ' . $id . ' AND us.idutilisateur = ' . $user->getId();
$droit = $this->dbconn->fetchAssociative($query);
if ($droit) {
$canEdit = true;
}
}
return $canEdit;
}
}