Update role logic for organization management
This commit is contained in:
parent
252fc775bb
commit
4fc059b2a5
|
|
@ -95,14 +95,14 @@ class OrganizationController extends AbstractController
|
|||
try {
|
||||
$this->entityManager->persist($organization);
|
||||
$this->entityManager->flush();
|
||||
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getId(), "Organization Created");
|
||||
$this->loggerService->logSuperAdmin($actingUser->getId(), $actingUser->getId(), "Organization Created", $organization->getId());
|
||||
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getUserIdentifier(), "Organization Created");
|
||||
$this->loggerService->logSuperAdmin($actingUser->getUserIdentifier(), $actingUser->getUserIdentifier(), "Organization Created", $organization->getId());
|
||||
$this->actionService->createAction("Create Organization", $actingUser, $organization, $organization->getName());
|
||||
$this->addFlash('success', 'Organisation crée avec succès.');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
} catch (Exception $e) {
|
||||
$this->addFlash('danger', 'Erreur lors de la création de l\'organization');
|
||||
$this->loggerService->logError('Error creating organization', ['acting_user_id' => $actingUser->getId(), 'error' => $e->getMessage()]);
|
||||
$this->loggerService->logError('Error creating organization', ['acting_user_id' => $actingUser->getUserIdentifier(), 'error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
return $this->render('organization/new.html.twig', [
|
||||
|
|
@ -125,35 +125,12 @@ class OrganizationController extends AbstractController
|
|||
if (!$organization) {
|
||||
$this->loggerService->logEntityNotFound('Organization', [
|
||||
'org_id' => $id,
|
||||
'message' => 'Organization not found for edit'], $actingUser->getId()
|
||||
'message' => 'Organization not found for edit'], $actingUser->getUserIdentifier()
|
||||
);
|
||||
$this->addFlash('danger', 'Erreur, l\'organization est introuvable.');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
}
|
||||
if (!$this->isGranted("ROLE_SUPER_ADMIN")) {
|
||||
//check if the user is admin of the organization
|
||||
$uo = $this->entityManager->getRepository(UsersOrganizations::class)->findOneBy(['users' => $actingUser, 'organization' => $organization]);
|
||||
if (!$uo) {
|
||||
$this->loggerService->logEntityNotFound('UO link', [
|
||||
'user_id' => $actingUser->getId(),
|
||||
'org_id' => $organization->getId(),
|
||||
'message' => 'UO link not found for edit organization'
|
||||
], $actingUser->getId());
|
||||
$this->addFlash('danger', 'Erreur, accès refusé.');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
}
|
||||
$roleAdmin = $this->entityManager->getRepository(Roles::class)->findOneBy(['name' => 'ADMIN']);
|
||||
$uoaAdmin = $this->entityManager->getRepository(UserOrganizatonApp::class)->findOneBy(['userOrganization' => $uo, 'role' => $roleAdmin]);
|
||||
if (!$uoaAdmin) {
|
||||
$this->loggerService->logEntityNotFound('UOA link', [
|
||||
'uo_id' => $uo->getId(),
|
||||
'role_id' => $roleAdmin->getId(),
|
||||
'message' => 'UOA link not found for edit organization, user is not admin of organization'
|
||||
], $actingUser->getId());
|
||||
$this->addFlash('danger', 'Erreur, accès refusé.');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
}
|
||||
}
|
||||
|
||||
$form = $this->createForm(OrganizationForm::class, $organization);
|
||||
$form->handleRequest($request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
|
|
@ -164,16 +141,16 @@ class OrganizationController extends AbstractController
|
|||
try {
|
||||
$this->entityManager->persist($organization);
|
||||
$this->entityManager->flush();
|
||||
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getId(), "Organization Edited");
|
||||
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getUserIdentifier(), "Organization Edited");
|
||||
if ($this->isGranted("ROLE_SUPER_ADMIN")) {
|
||||
$this->loggerService->logSuperAdmin($actingUser->getId(), $actingUser->getId(), "Organization Edited", $organization->getId());
|
||||
$this->loggerService->logSuperAdmin($actingUser->getUserIdentifier(), $actingUser->getUserIdentifier(), "Organization Edited", $organization->getId());
|
||||
}
|
||||
$this->actionService->createAction("Edit Organization", $actingUser, $organization, $organization->getName());
|
||||
$this->addFlash('success', 'Organisation modifiée avec succès.');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
}catch (Exception $e) {
|
||||
$this->addFlash('danger', 'Erreur lors de la modification de l\'organization');
|
||||
$this->loggerService->logError('Error editing organization', ['acting_user_id' => $actingUser->getId(), 'error' => $e->getMessage()]);
|
||||
$this->loggerService->logError('Error editing organization', ['acting_user_id' => $actingUser->getUserIdentifier(), 'error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
return $this->render('organization/edit.html.twig', [
|
||||
|
|
@ -192,17 +169,18 @@ class OrganizationController extends AbstractController
|
|||
$this->loggerService->logEntityNotFound('Organization', [
|
||||
'org_id' => $id,
|
||||
'message' => 'Organization not found for view'
|
||||
], $actingUser->getId());
|
||||
], $actingUser->getUserIdentifier());
|
||||
$this->addFlash('danger', 'Erreur, l\'organization est introuvable.');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
}
|
||||
//check if the user is admin of the organization
|
||||
if (!$this->userService->isAdminOfOrganization($organization) && !$this->isGranted("ROLE_ADMIN")) {
|
||||
$this->loggerService->logAccessDenied($actingUser->getId());
|
||||
$this->loggerService->logAccessDenied($actingUser->getUserIdentifier());
|
||||
$this->addFlash('danger', 'Erreur, accès refusé.');
|
||||
throw new AccessDeniedHttpException('Access denied');
|
||||
}
|
||||
|
||||
//TODO: add project to the response
|
||||
$allApps = $this->entityManager->getRepository(Apps::class)->findAll(); // appsAll
|
||||
$orgApps = $organization->getApps()->toArray(); // apps
|
||||
|
||||
|
|
@ -222,14 +200,14 @@ class OrganizationController extends AbstractController
|
|||
#[Route(path: '/delete/{id}', name: 'delete', methods: ['POST'])]
|
||||
public function delete($id): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted("ROLE_ADMIN");
|
||||
$this->denyAccessUnlessGranted("ROLE_SUPER_ADMIN");
|
||||
$actingUser = $this->getUser();
|
||||
$organization = $this->organizationsRepository->find($id);
|
||||
if (!$organization) {
|
||||
$this->loggerService->logEntityNotFound('Organization', [
|
||||
'org_id' => $id,
|
||||
'message' => 'Organization not found for delete'
|
||||
], $actingUser->getId());
|
||||
], $actingUser->getUserIdentifier());
|
||||
$this->addFlash('danger', 'Erreur, l\'organization est introuvable.');
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
|
|
@ -243,13 +221,13 @@ class OrganizationController extends AbstractController
|
|||
$this->entityManager->persist($organization);
|
||||
$this->actionService->createAction("Delete Organization", $actingUser, $organization, $organization->getName());
|
||||
$this->entityManager->flush();
|
||||
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getId(),'Organization Deleted');
|
||||
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getUserIdentifier(),'Organization Deleted');
|
||||
if ($this->isGranted("ROLE_SUPER_ADMIN")) {
|
||||
$this->loggerService->logSuperAdmin($actingUser->getId(), $actingUser->getId(),'Organization Deleted', $organization->getId());
|
||||
$this->loggerService->logSuperAdmin($actingUser->getUserIdentifier(), $actingUser->getUserIdentifier(),'Organization Deleted', $organization->getId());
|
||||
}
|
||||
$this->addFlash('success', 'Organisation supprimée avec succès.');
|
||||
}catch (\Exception $e){
|
||||
$this->loggerService->logError($actingUser->getId(), ['message' => 'Error deleting organization: '.$e->getMessage()]);
|
||||
$this->loggerService->logError($actingUser->getUserIdentifier(), ['message' => 'Error deleting organization: '.$e->getMessage()]);
|
||||
$this->addFlash('danger', 'Erreur lors de la suppression de l\'organization.');
|
||||
}
|
||||
|
||||
|
|
@ -266,16 +244,15 @@ class OrganizationController extends AbstractController
|
|||
$this->loggerService->logEntityNotFound('Organization', [
|
||||
'org_id' => $id,
|
||||
'message' => 'Organization not found for deactivate'
|
||||
], $actingUser->getId());
|
||||
], $actingUser->getUserIdentifier());
|
||||
$this->addFlash('danger', 'Erreur, l\'organization est introuvable.');
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
|
||||
$organization->setIsActive(false);
|
||||
// $this->userOrganizationService->deactivateAllUserOrganizationLinks($actingUser, null, $organization);
|
||||
$this->entityManager->persist($organization);
|
||||
$this->actionService->createAction("Deactivate Organization", $actingUser, $organization, $organization->getName());
|
||||
$this->loggerService->logSuperAdmin($actingUser->getId(), $actingUser->getId(),'Organization deactivated', $organization->getId());
|
||||
$this->loggerService->logSuperAdmin($actingUser->getUserIdentifier(), $actingUser->getUserIdentifier(),'Organization deactivated', $organization->getId());
|
||||
$this->addFlash('success', 'Organisation désactivé avec succès.');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
}
|
||||
|
|
@ -290,14 +267,14 @@ class OrganizationController extends AbstractController
|
|||
$this->loggerService->logEntityNotFound('Organization', [
|
||||
'org_id' => $id,
|
||||
'message' => 'Organization not found for activate'
|
||||
], $actingUser->getId());
|
||||
], $actingUser->getUserIdentifier());
|
||||
$this->addFlash('danger', 'Erreur, l\'organization est introuvable.');
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
$organization->setIsActive(true);
|
||||
$this->entityManager->persist($organization);
|
||||
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getId(),'Organization Activated');
|
||||
$this->loggerService->logSuperAdmin($actingUser->getId(), $actingUser->getId(),'Organization Activated', $organization->getId());
|
||||
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getUserIdentifier(),'Organization Activated');
|
||||
$this->loggerService->logSuperAdmin($actingUser->getUserIdentifier(), $actingUser->getUserIdentifier(),'Organization Activated', $organization->getId());
|
||||
$this->actionService->createAction("Activate Organization", $actingUser, $organization, $organization->getName());
|
||||
$this->addFlash('success', 'Organisation activée avec succès.');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
|
|
@ -309,54 +286,21 @@ class OrganizationController extends AbstractController
|
|||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_USER');
|
||||
|
||||
|
||||
$page = max(1, (int)$request->query->get('page', 1));
|
||||
$size = max(1, (int)$request->query->get('size', 10));
|
||||
|
||||
$page = max(1, $request->query->getInt('page', 1));
|
||||
$size = max(1, $request->query->getInt('size', 10));
|
||||
$filters = $request->query->all('filter');
|
||||
|
||||
// Fetch paginated results
|
||||
$paginator = $this->organizationsRepository->findAdmissibleOrganizations(
|
||||
$this->getUser(),
|
||||
$this->isGranted('ROLE_ADMIN'), // Super Admin check
|
||||
$page,
|
||||
$size,
|
||||
$filters
|
||||
);
|
||||
|
||||
$qb = $this->organizationsRepository->createQueryBuilder('o')
|
||||
->where('o.isDeleted = :del')->setParameter('del', false);
|
||||
$total = count($paginator);
|
||||
|
||||
if (!empty($filters['name'])) {
|
||||
$qb->andWhere('o.name LIKE :name')
|
||||
->setParameter('name', '%' . $filters['name'] . '%');
|
||||
}
|
||||
if (!empty($filters['email'])) {
|
||||
$qb->andWhere('o.email LIKE :email')
|
||||
->setParameter('email', '%' . $filters['email'] . '%');
|
||||
}
|
||||
if (!$this->isGranted('ROLE_ADMIN')) {
|
||||
$actingUser = $this->getUser();
|
||||
$uo = $this->entityManager->getRepository(UsersOrganizations::class)->findBy(['users' => $actingUser]);
|
||||
|
||||
$allowedOrgIds = [];
|
||||
foreach ($uo as $item) {
|
||||
if ($this->userService->isAdminOfOrganization($item->getOrganization())) {
|
||||
$allowedOrgIds[] = $item->getOrganization()->getId();
|
||||
}
|
||||
}
|
||||
|
||||
// If user has no organizations, ensure query returns nothing (or handle typically)
|
||||
if (empty($allowedOrgIds)) {
|
||||
$qb->andWhere('1 = 0'); // Force empty result
|
||||
} else {
|
||||
$qb->andWhere('o.id IN (:orgIds)')
|
||||
->setParameter('orgIds', $allowedOrgIds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Count total
|
||||
$countQb = clone $qb;
|
||||
$total = (int)$countQb->select('COUNT(o.id)')->getQuery()->getSingleScalarResult();
|
||||
|
||||
// Pagination
|
||||
$offset = ($page - 1) * $size;
|
||||
$rows = $qb->setFirstResult($offset)->setMaxResults($size)->getQuery()->getResult();
|
||||
|
||||
// Map to array
|
||||
$data = array_map(function (Organizations $org) {
|
||||
return [
|
||||
'id' => $org->getId(),
|
||||
|
|
@ -366,17 +310,12 @@ class OrganizationController extends AbstractController
|
|||
'active' => $org->isActive(),
|
||||
'showUrl' => $this->generateUrl('organization_show', ['id' => $org->getId()]),
|
||||
];
|
||||
}, $rows);
|
||||
|
||||
$lastPage = (int)ceil($total / $size);
|
||||
}, iterator_to_array($paginator));
|
||||
|
||||
return $this->json([
|
||||
'data' => $data,
|
||||
'last_page' => $lastPage,
|
||||
'total' => $total, // optional, useful for debugging
|
||||
'last_page' => (int)ceil($total / $size),
|
||||
'total' => $total,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,11 @@
|
|||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Organizations;
|
||||
use App\Entity\User;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\ORM\Tools\Pagination\Paginator;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use App\Entity\UsersOrganizations;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Organizations>
|
||||
|
|
@ -16,28 +19,37 @@ class OrganizationsRepository extends ServiceEntityRepository
|
|||
parent::__construct($registry, Organizations::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Organizations[] Returns an array of Organizations objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('o')
|
||||
// ->andWhere('o.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('o.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
public function findAdmissibleOrganizations(User $user, bool $isSuperAdmin, int $page, int $size, array $filters = []): Paginator
|
||||
{
|
||||
$qb = $this->createQueryBuilder('o')
|
||||
->where('o.isDeleted = :del')
|
||||
->setParameter('del', false);
|
||||
|
||||
// public function findOneBySomeField($value): ?Organizations
|
||||
// {
|
||||
// return $this->createQueryBuilder('o')
|
||||
// ->andWhere('o.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
// 1. Security Logic: If not Super Admin, join UsersOrganizations to filter
|
||||
if (!$isSuperAdmin) {
|
||||
$qb->innerJoin(UsersOrganizations::class, 'uo', 'WITH', 'uo.organization = o')
|
||||
->andWhere('uo.users = :user')
|
||||
->andWhere('uo.role = :roleAdmin')
|
||||
->andWhere('uo.isActive = true')
|
||||
->setParameter('user', $user)
|
||||
// You can pass the actual Role entity or the string name depending on your mapping
|
||||
->setParameter('roleAdmin', $this->_em->getRepository(\App\Entity\Roles::class)->findOneBy(['name' => 'ADMIN']));
|
||||
}
|
||||
|
||||
// 2. Filters
|
||||
if (!empty($filters['name'])) {
|
||||
$qb->andWhere('o.name LIKE :name')
|
||||
->setParameter('name', '%' . $filters['name'] . '%');
|
||||
}
|
||||
if (!empty($filters['email'])) {
|
||||
$qb->andWhere('o.email LIKE :email')
|
||||
->setParameter('email', '%' . $filters['email'] . '%');
|
||||
}
|
||||
|
||||
// 3. Pagination
|
||||
$qb->setFirstResult(($page - 1) * $size)
|
||||
->setMaxResults($size);
|
||||
|
||||
return new Paginator($qb);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue