From ccd44e3560ba8ee4d579e2124cba65f106d307d6 Mon Sep 17 00:00:00 2001 From: Charles Date: Thu, 7 Aug 2025 12:06:31 +0200 Subject: [PATCH] Review of access logic --- src/Controller/UserController.php | 55 +++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 5db81f3..02d29d7 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -165,33 +165,60 @@ class UserController extends AbstractController #[Route('/edit/{id}', name: 'edit', requirements: ['id' => '\d+'], methods: ['GET', 'PUT', 'POST'])] public function edit(int $id, EntityManagerInterface $entityManager, Request $request): Response { - //Handle access control - if (!$this->isGranted('ROLE_SUPER_ADMIN')) { - throw $this->createAccessDeniedException(self::ACCESS_DENIED); - } - - //Fetch user by ID and handle not found case + // Fetch user by ID and handle not found case $user = $entityManager->getRepository(User::class)->find($id); if (!$user) { throw $this->createNotFoundException(self::NOT_FOUND); } - //Create form for editing user + // Get the acting user (the one making the request) + $actingUser = $this->getUser() ?? throw $this->createNotFoundException(self::NOT_FOUND); + $actingUser = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $actingUser->getUserIdentifier()]); + + // Check if acting user is the same as the user being edited + $isSameUser = $user->getUserIdentifier() === $actingUser->getUserIdentifier(); + + // Get all organizations of the user being edited + $userOrganizations = $this->userOrganizationService->getUserOrganizations($user); + + // Check if acting user is admin in any of the user's organizations + $isAdminOrg = false; + foreach ($userOrganizations as $userOrganization) { + $organization = $userOrganization['organization']; + if ($this->userService->isUserAdminInOrganization($actingUser->getId(), $organization->getId())) { + $isAdminOrg = true; + break; + } + } + + // Access control: allow if super admin, same user, or admin in org + if ( + !$this->isGranted('ROLE_SUPER_ADMIN') && + !$isSameUser && + !$isAdminOrg + ) { + throw $this->createAccessDeniedException(self::ACCESS_DENIED); + } + + // Create form for editing user $form = $this->createForm(UserForm::class, $user); - //Handle form submission + // Handle form submission $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - //Persist changes to the user entity + // Persist changes to the user entity $entityManager->persist($user); - //Log the action - $user = $this->getUser() ?? throw $this->createNotFoundException(self::NOT_FOUND); - $user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $user->getUserIdentifier()]); - $this->actionService->createAction("Création d'une organisation", $user, null, "{$user->getIdentifier()} a modifié l'utilisateur {$user->getUserIdentifier()}"); + // Log the action + $this->actionService->createAction( + "Modification d'un utilisateur", + $actingUser, + null, + "{$actingUser->getIdentifier()} a modifié l'utilisateur {$user->getUserIdentifier()}" + ); $entityManager->flush(); - //Redirect to user profile after successful edit + // Redirect to user profile after successful edit return $this->redirectToRoute('user_show', ['id' => $user->getId()]); }