All checks were successful
Auto Tag Develop / tag (push) Successful in 5s
| Numéro du ticket | Titre du ticket | |------------------|-----------------| | #322 | Page horaire | ## Description de la PR [#322] Page horaire ## Modification du .env ## Check list - [ ] Pas de régression - [ ] TU/TI/TF rédigée - [ ] TU/TI/TF OK - [ ] CHANGELOG modifié Reviewed-on: #4 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
100 lines
2.7 KiB
PHP
100 lines
2.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Security;
|
|
|
|
use App\Entity\Employee;
|
|
use App\Entity\User;
|
|
use Doctrine\ORM\QueryBuilder;
|
|
|
|
class EmployeeScopeService
|
|
{
|
|
public const string SITE_ACCESS_ROLE = 'SITE_ACCESS';
|
|
|
|
/**
|
|
* Règle métier centrale d'accès à un employé.
|
|
* - Admin : accès global
|
|
* - Self : uniquement son employé lié
|
|
* - Site : uniquement les employés des sites autorisés.
|
|
*/
|
|
public function canAccessEmployee(User $user, Employee $employee): bool
|
|
{
|
|
if (in_array('ROLE_ADMIN', $user->getRoles(), true)) {
|
|
return true;
|
|
}
|
|
|
|
if (in_array('ROLE_SELF', $user->getRoles(), true)) {
|
|
return $user->getEmployee()?->getId() === $employee->getId();
|
|
}
|
|
|
|
$employeeSiteId = $employee->getSite()?->getId();
|
|
if (!$employeeSiteId) {
|
|
return false;
|
|
}
|
|
|
|
return in_array($employeeSiteId, $this->getAllowedSiteIds($user), true);
|
|
}
|
|
|
|
/**
|
|
* Retourne la liste des sites accessibles via user_site_roles.
|
|
*
|
|
* @return list<int>
|
|
*/
|
|
public function getAllowedSiteIds(User $user): array
|
|
{
|
|
$siteIds = [];
|
|
|
|
foreach ($user->getSiteRoles() as $siteRole) {
|
|
if (self::SITE_ACCESS_ROLE !== $siteRole->getRole()) {
|
|
continue;
|
|
}
|
|
|
|
$siteId = $siteRole->getSite()?->getId();
|
|
if ($siteId) {
|
|
$siteIds[] = $siteId;
|
|
}
|
|
}
|
|
|
|
return array_values(array_unique($siteIds));
|
|
}
|
|
|
|
/**
|
|
* Applique le scope directement sur un QueryBuilder Doctrine.
|
|
* Cette méthode est utilisée pour filtrer les collections SQL
|
|
* avant sérialisation (plus sûr et plus performant).
|
|
*/
|
|
public function applyEmployeeScope(QueryBuilder $qb, string $employeeAlias, string $paramPrefix, User $user): void
|
|
{
|
|
if (in_array('ROLE_ADMIN', $user->getRoles(), true)) {
|
|
return;
|
|
}
|
|
|
|
if (in_array('ROLE_SELF', $user->getRoles(), true)) {
|
|
$employeeId = $user->getEmployee()?->getId();
|
|
if (!$employeeId) {
|
|
$qb->andWhere('1 = 0');
|
|
|
|
return;
|
|
}
|
|
|
|
$qb->andWhere(sprintf('%s.id = :%s_employee_id', $employeeAlias, $paramPrefix))
|
|
->setParameter(sprintf('%s_employee_id', $paramPrefix), $employeeId)
|
|
;
|
|
|
|
return;
|
|
}
|
|
|
|
$siteIds = $this->getAllowedSiteIds($user);
|
|
if ([] === $siteIds) {
|
|
$qb->andWhere('1 = 0');
|
|
|
|
return;
|
|
}
|
|
|
|
$qb->andWhere(sprintf('%s.site IN (:%s_site_ids)', $employeeAlias, $paramPrefix))
|
|
->setParameter(sprintf('%s_site_ids', $paramPrefix), $siteIds)
|
|
;
|
|
}
|
|
}
|