src/Service/Security.php line 169

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\Entity\AccountOrganization;
  4. use App\Entity\Organization;
  5. use App\Entity\Praticien;
  6. use App\Entity\Programme\Programme;
  7. use App\Entity\UserInterface;
  8. use App\Enum\PermissionEnum;
  9. use App\Repository\LicenceRepository;
  10. use App\Repository\OrganizationRepository;
  11. use Doctrine\ORM\EntityManagerInterface;
  12. use Exception;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\RequestStack;
  15. use function get_class;
  16. use function password_hash;
  17. use function password_verify;
  18. use const PASSWORD_DEFAULT;
  19. class Security
  20. {
  21.     protected EntityManagerInterface $entityManager;
  22.     private UserInterface|Organization|null $user null;
  23.     private RequestStack $requestStack;
  24.     private ConnexionLoginService $connexionLoginService;
  25.     private OrganizationRepository $organizationRepository;
  26.     private PermissionEnum $permissionEnum;
  27.     private LicenceRepository $licenceRepository;
  28.     public function __construct(
  29.         RequestStack $requestStack,
  30.         EntityManagerInterface $entityManager,
  31.         ConnexionLoginService $connexionLoginService,
  32.         OrganizationRepository $organizationRepository,
  33.         PermissionEnum $permissionEnum,
  34.         LicenceRepository $licenceRepository
  35.     ) {
  36.         $this->requestStack $requestStack;
  37.         $this->entityManager $entityManager;
  38.         $this->connexionLoginService $connexionLoginService;
  39.         $this->organizationRepository $organizationRepository;
  40.         $this->permissionEnum $permissionEnum;
  41.         $this->licenceRepository $licenceRepository;
  42.     }
  43.     /**
  44.      * Retourne une version hashée d'un mot de passe
  45.      */
  46.     public static function passwordhash(string $password):string
  47.     {
  48.         return password_hash($passwordPASSWORD_DEFAULT);
  49.     }
  50.     /**
  51.      * Vérifie un mot de passe par rapport à un hash
  52.      * @param $password
  53.      * @param $hash
  54.      * @return bool
  55.      */
  56.     public static function isValidePassword($password$hash):bool
  57.     {
  58.         return password_verify($password$hash);
  59.     }
  60.     /**
  61.      * Permet de générer un token aléatoire
  62.      * @return string
  63.      */
  64.     public static function generateToken():string
  65.     {
  66.         try {
  67.             return bin2hex(random_bytes(32));
  68.         } catch (Exception) {
  69.             return md5(uniqid('token_'true));
  70.         }
  71.     }
  72.     /**
  73.      * Monte un utilisateur en session
  74.      */
  75.     public function login(
  76.         UserInterface|AccountOrganization $user,
  77.         Request $request
  78.     ):null|UserInterface|Organization {
  79.         $this->connexionLoginService->log($user$request);
  80.         if ($user instanceof AccountOrganization) {
  81.             $this->requestStack->getSession()->set('Organization'$user->getOrganization());
  82.             $this->requestStack->getSession()->remove('User');
  83.             return $this->getOrganization();
  84.         }
  85.         $this->requestStack->getSession()->remove('Organization');
  86.         $this->requestStack->getSession()->set('User'$user);
  87.         return $this->getUser();
  88.     }
  89.     /**
  90.      * Monte une session Organisation en conservant la session admin de côté
  91.      */
  92.     public function logtoOrganization(Organization $organization): void
  93.     {
  94.         $this->requestStack->getSession()->set('Organization'$organization);
  95.         // Stocke la session admin afin de pouvoir la restaurer.
  96.         $this->requestStack->getSession()->set('previousSessionUser',
  97.             $this->requestStack->getSession()->get('User')
  98.         );
  99.         $this->requestStack->getSession()->remove('User');
  100.     }
  101.     /**
  102.      * Restaure une session admin après une prise de contrôle
  103.      */
  104.     public function restore(): void
  105.     {
  106.         $this->requestStack->getSession()->set('User',
  107.             $this->requestStack->getSession()->get('previousSessionUser')
  108.         );
  109.         $this->requestStack->getSession()->remove('previousSessionUser');
  110.         $this->requestStack->getSession()->remove('Organization');
  111.     }
  112.     /**
  113.      * Vérifie si on est en prise de contrôle
  114.      */
  115.     public function hasPreviousSession():bool
  116.     {
  117.         return $this->requestStack->getSession()->has('previousSessionUser');
  118.     }
  119.     /**
  120.      * @return UserInterface|null Récupère l'utilisateur identifié
  121.      */
  122.     public function getUser():?UserInterface
  123.     {
  124.         // Si on l'a déjà synchronisé avec l'entityManager
  125.         if ($this->user instanceof UserInterface) {
  126.             return $this->user;
  127.         }
  128.         // Si on a un utilisateur, on récupère via l'entitymanager pour permettre des requêtes doctrine (impossible avec l'objet en session)
  129.         $user $this->requestStack->getSession()->get('User');
  130.         if ($user instanceof UserInterface) {
  131.             $this->user $this->entityManager->getRepository(get_class($user))->find($this->requestStack->getSession()
  132.                                                                                                          ->get('User')
  133.                                                                                                          ->getId());
  134.             $this->requestStack->getSession()->set('User'$this->user);
  135.             return $this->user;
  136.         }
  137.         return null;
  138.     }
  139.     public function getOrganization():?Organization
  140.     {
  141.         // Si on l'a déjà synchronisé avec l'entityManager
  142.         if ($this->user instanceof Organization) {
  143.             return $this->user;
  144.         }
  145.         $organization $this->requestStack->getSession()->get('Organization');
  146.         if ($organization instanceof Organization) {
  147.             // Récupère depuis Doctrine pour que l'entité et ses dépendances soient dans l'EntityManager
  148.             $organization $this->organizationRepository->find($organization->getId());
  149.             $this->user $organization;
  150.             return $this->user;
  151.         }
  152.         return null;
  153.     }
  154.     /**
  155.      * @return void Déconnecte la session en cours
  156.      */
  157.     public function logout():void
  158.     {
  159.         unset($this->user);
  160.         $this->requestStack->getSession()->clear();
  161.     }
  162.     public function isGranted(string $permission):bool
  163.     {
  164.         $permissionList $this->requestStack->getSession()->get('Permission');
  165.         // Si la permission n'est pas dans la liste
  166.         if (!in_array($permission$permissionListtrue)) {
  167.             return false;
  168.         }
  169.         // Sinon, autorisé
  170.         return true;
  171.     }
  172.     public function getAllowedPathologieSlugs():array
  173.     {
  174.         $pathologiesPermissions $this->permissionEnum->getPathologieSlugsPermissions();
  175.         $userPermissions $this->requestStack->getSession()->get('Permission');
  176.         return array_flip(array_intersect($pathologiesPermissions$userPermissions));
  177.     }
  178.     public function isAllowPathology(string $pathologySlug):bool
  179.     {
  180.         return in_array($pathologySlug$this->getAllowedPathologieSlugs());
  181.     }
  182.     public function isAllowProgram(Programme $programme):bool
  183.     {
  184.         return $this->isAllowPathology($programme->getPathologie()->getSlug());
  185.     }
  186.     public function isAllowAccessAffiliatedPatient(Praticien $praticien):bool
  187.     {
  188.         return $this->organizationRepository->isAllowAccessAffiliatedPatient($praticien);
  189.     }
  190.     public function isOrganization():bool
  191.     {
  192.         return $this->requestStack->getSession()->has('Organization');
  193.     }
  194. }