Update logic

This commit is contained in:
Charles 2026-02-11 12:17:16 +01:00
parent 6a286bff0a
commit 64317c226d
4 changed files with 90 additions and 68 deletions

View File

@ -88,8 +88,8 @@ class UserController extends AbstractController
$this->addFlash('danger', "L'utilisateur demandé n'existe pas."); $this->addFlash('danger', "L'utilisateur demandé n'existe pas.");
throw $this->createNotFoundException(self::NOT_FOUND); throw $this->createNotFoundException(self::NOT_FOUND);
} }
//if hasAccessTo is false, turn to true and denie access //if hasAccessTo is false, turn to true and deny access
if (!$this->userService->isAdminOfUser($user)) { if (!$this->userService->isAdminOfUser($user) && !$this->isGranted('ROLE_ADMIN')) {
$this->loggerService->logAccessDenied($actingUser->getUserIdentifier()); $this->loggerService->logAccessDenied($actingUser->getUserIdentifier());
$this->addFlash('danger', "Vous n'avez pas accès à cette information."); $this->addFlash('danger', "Vous n'avez pas accès à cette information.");
throw new AccessDeniedHttpException (self::ACCESS_DENIED); throw new AccessDeniedHttpException (self::ACCESS_DENIED);
@ -555,9 +555,15 @@ class UserController extends AbstractController
public function dataNew(Request $request): JsonResponse public function dataNew(Request $request): JsonResponse
{ {
$actingUser = $this->getUser(); $actingUser = $this->getUser();
if ($this->userService->hasAccessTo($actingUser, true) && $this->isGranted("ROLE_USER")) {
$orgId = $request->query->get('orgId'); $orgId = $request->query->get('orgId');
$uos = $this->uoRepository->findBy(['organization' => $orgId, 'statut' => ["ACCEPTED", "INVITED"]], $org = $this->organizationRepository->find($orgId);
if (!$org) {
$this->loggerService->logEntityNotFound('Organization', ['id' => $orgId], $actingUser->getUserIdentifier());
throw $this->createNotFoundException(self::NOT_FOUND);
}
if ($this->userService->isAdminOfOrganization($org) || $this->isGranted("ROLE_ADMIN")) {
$uos = $this->uoRepository->findBy(['organization' => $org, 'statut' => ["ACCEPTED", "INVITED"]],
orderBy: ['createdAt' => 'DESC'], limit: 5); orderBy: ['createdAt' => 'DESC'], limit: 5);
@ -591,9 +597,14 @@ class UserController extends AbstractController
public function dataAdmin(Request $request): JsonResponse public function dataAdmin(Request $request): JsonResponse
{ {
$actingUser = $this->getUser(); $actingUser = $this->getUser();
if ($this->userService->hasAccessTo($actingUser, true) && $this->isGranted("ROLE_USER")) {
$orgId = $request->query->get('orgId'); $orgId = $request->query->get('orgId');
$uos = $this->uoRepository->findBy(['organization' => $orgId]); $org = $this->organizationRepository->find($orgId);
if (!$org) {
$this->loggerService->logEntityNotFound('Organization', ['id' => $orgId], $actingUser->getUserIdentifier());
throw $this->createNotFoundException(self::NOT_FOUND);
}
if ($this->userService->isAdminOfOrganization($org) || $this->isGranted("ROLE_ADMIN")) {
$uos = $this->uoRepository->findBy(['organization' => $org]);
$roleAdmin = $this->entityManager->getRepository(Roles::class)->findOneBy(['name' => 'ADMIN']); $roleAdmin = $this->entityManager->getRepository(Roles::class)->findOneBy(['name' => 'ADMIN']);
$users = []; $users = [];
foreach ($uos as $uo) { foreach ($uos as $uo) {
@ -632,60 +643,38 @@ class UserController extends AbstractController
public function dataUserOrganization(Request $request): JsonResponse public function dataUserOrganization(Request $request): JsonResponse
{ {
$actingUser = $this->getUser(); $actingUser = $this->getUser();
if ($this->userService->hasAccessTo($actingUser, true) && $this->isGranted("ROLE_USER")) {
$orgId = $request->query->get('orgId'); $orgId = $request->query->get('orgId');
$page = max(1, (int)$request->query->get('page', 1));
$size = max(1, (int)$request->query->get('size', 10));
$org = $this->organizationRepository->find($orgId);
if (!$org) {
$this->loggerService->logEntityNotFound('Organization', ['id' => $orgId], $actingUser->getUserIdentifier());
throw $this->createNotFoundException(self::NOT_FOUND);
}
// Security Check
if (!$this->isGranted("ROLE_ADMIN") && !$this->userService->isAdminOfOrganization($org)) {
throw $this->createAccessDeniedException(self::ACCESS_DENIED);
}
// Params extraction
$page = max(1, $request->query->getInt('page', 1));
$size = max(1, $request->query->getInt('size', 10));
$filters = $request->query->all('filter') ?? []; $filters = $request->query->all('filter') ?? [];
$repo = $this->uoRepository; // Get paginated results from Repository
$paginator = $this->uoRepository->findByOrganizationWithFilters($org, $page, $size, $filters);
$total = count($paginator);
// Base query // Format the data using your existing service method
$qb = $repo->createQueryBuilder('uo') $data = $this->userService->formatStatutForOrganizations(iterator_to_array($paginator));
->join('uo.users', 'u')
->where('uo.organization = :orgId')
->setParameter('orgId', $orgId);
// Apply filters
if (!empty($filters['name'])) {
$qb->andWhere('u.surname LIKE :name')
->setParameter('name', '%' . $filters['name'] . '%');
}
if (!empty($filters['prenom'])) {
$qb->andWhere('u.name LIKE :prenom')
->setParameter('prenom', '%' . $filters['prenom'] . '%');
}
if (!empty($filters['email'])) {
$qb->andWhere('u.email LIKE :email')
->setParameter('email', '%' . $filters['email'] . '%');
}
$countQb = clone $qb;
$total = (int)$countQb->select('COUNT(uo.id)')->getQuery()->getSingleScalarResult();
$qb->orderBy('uo.isActive', 'DESC')
->addOrderBy('CASE WHEN uo.statut = :invited THEN 0 ELSE 1 END', 'ASC')
->setParameter('invited', 'INVITED');
$offset = ($page - 1) * $size;
$rows = $qb->setFirstResult($offset)->setMaxResults($size)->getQuery()->getResult();
$data = $this->userService->formatStatutForOrganizations($rows);
$lastPage = (int)ceil($total / $size);
return $this->json([ return $this->json([
'data' => $data, 'data' => $data,
'last_page' => $lastPage, 'last_page' => (int)ceil($total / $size),
'total' => $total, 'total' => $total,
]); ]);
} }
throw $this->createAccessDeniedException(self::ACCESS_DENIED);
}
#[Route(path: '/organization/resend-invitation/{userId}', name: 'resend_invitation', methods: ['POST'])] #[Route(path: '/organization/resend-invitation/{userId}', name: 'resend_invitation', methods: ['POST'])]
public function resendInvitation(int $userId, Request $request): JsonResponse public function resendInvitation(int $userId, Request $request): JsonResponse
{ {

View File

@ -6,8 +6,10 @@ use App\Entity\Organizations;
use App\Entity\User; use App\Entity\User;
use App\Entity\UsersOrganizations; use App\Entity\UsersOrganizations;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
/** /**
* @extends ServiceEntityRepository<UsersOrganizations> * @extends ServiceEntityRepository<UsersOrganizations>
*/ */
@ -47,4 +49,36 @@ class UsersOrganizationsRepository extends ServiceEntityRepository
->getQuery() ->getQuery()
->getSingleScalarResult() > 0; ->getSingleScalarResult() > 0;
} }
public function findByOrganizationWithFilters(Organizations $org, int $page, int $size, array $filters = []): Paginator
{
$qb = $this->createQueryBuilder('uo')
->innerJoin('uo.users', 'u')
->where('uo.organization = :org')
->setParameter('org', $org);
// Apply filters
if (!empty($filters['name'])) {
$qb->andWhere('u.surname LIKE :name')
->setParameter('name', '%' . $filters['name'] . '%');
}
if (!empty($filters['prenom'])) {
$qb->andWhere('u.name LIKE :prenom')
->setParameter('prenom', '%' . $filters['prenom'] . '%');
}
if (!empty($filters['email'])) {
$qb->andWhere('u.email LIKE :email')
->setParameter('email', '%' . $filters['email'] . '%');
}
// Apply complex sorting
$qb->orderBy('uo.isActive', 'DESC')
->addOrderBy("CASE WHEN uo.statut = 'INVITED' THEN 0 ELSE 1 END", 'ASC');
// Pagination
$qb->setFirstResult(($page - 1) * $size)
->setMaxResults($size);
return new Paginator($qb);
}
} }

View File

@ -23,7 +23,7 @@ readonly class LoggerService
// User Management Logs // User Management Logs
public function logUserCreated(int $userId, int $actingUserId): void public function logUserCreated(int $userId, int|string $actingUserId): void
{ {
$this->userManagementLogger->notice("New user created: $userId", [ $this->userManagementLogger->notice("New user created: $userId", [
'target_user_id' => $userId, 'target_user_id' => $userId,
@ -34,7 +34,7 @@ readonly class LoggerService
} }
// Organization Management Logs // Organization Management Logs
public function logUserOrganizationLinkCreated(int $userId, int $orgId, int $actingUserId, ?int $uoId): void public function logUserOrganizationLinkCreated(int $userId, int $orgId, int|string $actingUserId, ?int $uoId): void
{ {
$this->organizationManagementLogger->notice('User-Organization link created', [ $this->organizationManagementLogger->notice('User-Organization link created', [
'target_user_id' => $userId, 'target_user_id' => $userId,
@ -46,7 +46,7 @@ readonly class LoggerService
]); ]);
} }
public function logExistingUserAddedToOrg(int $userId, int $orgId, int $actingUserId, int $uoId): void public function logExistingUserAddedToOrg(int $userId, int $orgId, int|string $actingUserId, int $uoId): void
{ {
$this->organizationManagementLogger->notice('Existing user added to organization', [ $this->organizationManagementLogger->notice('Existing user added to organization', [
'target_user_id' => $userId, 'target_user_id' => $userId,
@ -87,7 +87,7 @@ readonly class LoggerService
])); ]));
} }
public function logSuperAdmin(int $userId, int $actingUserId, string $message, ?int $orgId = null): void public function logSuperAdmin(int $userId, int|string $actingUserId, string $message, ?int $orgId = null): void
{ {
$this->adminActionsLogger->notice($message, [ $this->adminActionsLogger->notice($message, [
'target_user_id' => $userId, 'target_user_id' => $userId,
@ -116,7 +116,7 @@ readonly class LoggerService
} }
// Security Logs // Security Logs
public function logAccessDenied(?int $actingUserId): void public function logAccessDenied(int|string $actingUserId): void
{ {
$this->securityLogger->warning('Access denied', [ $this->securityLogger->warning('Access denied', [
'acting_user_id' => $actingUserId, 'acting_user_id' => $actingUserId,
@ -133,7 +133,7 @@ readonly class LoggerService
} }
public function logUserAction(int $targetId, int $actingUserId, string $message): void public function logUserAction(int $targetId, int|string $actingUserId, string $message): void
{ {
$this->userManagementLogger->notice($message, [ $this->userManagementLogger->notice($message, [
'target_user_id'=> $targetId, 'target_user_id'=> $targetId,
@ -143,7 +143,7 @@ readonly class LoggerService
]); ]);
} }
public function logAdminAction(int $targetId, int $actingUserId, int $organizationId, string $message): void public function logAdminAction(int $targetId, int|string $actingUserId, int $organizationId, string $message): void
{ {
$this->adminActionsLogger->notice($message, [ $this->adminActionsLogger->notice($message, [
'target_id' => $targetId, 'target_id' => $targetId,
@ -154,7 +154,7 @@ readonly class LoggerService
]); ]);
} }
public function logEntityNotFound(string $entityType, array $criteria, ?int $actingUserId): void public function logEntityNotFound(string $entityType, array $criteria, int|string $actingUserId): void
{ {
$this->errorLogger->error('Entity not found', array_merge($criteria, [ $this->errorLogger->error('Entity not found', array_merge($criteria, [
'entity_type' => $entityType, 'entity_type' => $entityType,
@ -192,7 +192,7 @@ readonly class LoggerService
]); ]);
} }
public function logOrganizationInformation(int $organizationId, int $actingUserId, string $message): void public function logOrganizationInformation(int $organizationId, int|string $actingUserId, string $message): void
{ {
$this->organizationManagementLogger->info($message, [ $this->organizationManagementLogger->info($message, [
'organization_id' => $organizationId, 'organization_id' => $organizationId,
@ -202,7 +202,7 @@ readonly class LoggerService
]); ]);
} }
public function logRoleEntityAssignment(int $userId, int $organizationId, int $roleId, int $actingUserId, string $message): void public function logRoleEntityAssignment(int $userId, int $organizationId, int $roleId, int|string $actingUserId, string $message): void
{ {
$this->accessControlLogger->info($message, [ $this->accessControlLogger->info($message, [
'target_user_id' => $userId, 'target_user_id' => $userId,
@ -252,7 +252,7 @@ readonly class LoggerService
])); ]));
} }
public function logApplicationInformation(string $string, array $array, int $actingUser) public function logApplicationInformation(string $string, array $array, int|string $actingUser)
{ {
$this->accessControlLogger->info($string, array_merge($array, [ $this->accessControlLogger->info($string, array_merge($array, [
'acting_user_id' => $actingUser, 'acting_user_id' => $actingUser,

View File

@ -147,7 +147,6 @@ class UserService
return false; return false;
} }
// Call the optimized repository method
return $this->entityManager return $this->entityManager
->getRepository(UsersOrganizations::class) ->getRepository(UsersOrganizations::class)
->isUserAdminOfTarget($actingUser, $user, $adminRole); ->isUserAdminOfTarget($actingUser, $user, $adminRole);