refonte base v2
This commit is contained in:
parent
9dc79eaa7d
commit
2d9b44ddb6
|
|
@ -30,206 +30,5 @@ class OrganizationController extends AbstractController
|
|||
{
|
||||
}
|
||||
|
||||
#[Route('/', name: 'index', methods: ['GET'])]
|
||||
public function index(): Response
|
||||
{
|
||||
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||
$organizations = $this->entityManager->getRepository(Organizations::class)->findBy(['isDeleted' => false]);
|
||||
} else {
|
||||
$user = $this->getUser();
|
||||
if (!$user) {
|
||||
return $this->redirectToRoute('app_login');
|
||||
}
|
||||
$userIdentifier = $user->getUserIdentifier();
|
||||
|
||||
$organizations = $this->entityManager->getRepository(UsersOrganizations::class)->findOrganizationsByUserEmailAndRoleName($userIdentifier, 'ADMIN');
|
||||
if (!$organizations) {
|
||||
// if user is not admin in any organization, throw access denied
|
||||
throw $this->createNotFoundException(self::ACCESS_DENIED);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->render('organization/index.html.twig', [
|
||||
'organizations' => $organizations,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/new', name: 'new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request): Response
|
||||
{
|
||||
if (!$this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||
throw $this->createNotFoundException(self::ACCESS_DENIED);
|
||||
}
|
||||
$form = $this->createForm(OrganizationForm::class);
|
||||
$form->handleRequest($request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$organization = $form->getData();
|
||||
$logoFile = $form->get('logoUrl')->getData();
|
||||
|
||||
if ($logoFile) {
|
||||
$currentDate = (new \DateTime())->format('Y-m-d');
|
||||
$organizationName = preg_replace('/[^a-zA-Z0-9]/', '_', $organization->getName());
|
||||
$extension = $logoFile->guessExtension();
|
||||
$newFilename = $currentDate . '_' . $organizationName . $extension;
|
||||
// Move the file to the directory where logos are stored
|
||||
$logoFile->move(
|
||||
$this->getParameter('logos_directory'),
|
||||
$newFilename
|
||||
);
|
||||
|
||||
// Update the 'logoUrl' property to store the file name
|
||||
$organization->setLogoUrl($newFilename);
|
||||
}
|
||||
$this->entityManager->persist($organization);
|
||||
$this->entityManager->flush();
|
||||
$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->getUserIdentifier()} a crée l'organisation {$organization->getName()}");
|
||||
$this->addFlash('success', 'Organization created successfully');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
}
|
||||
return $this->render('organization/new.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/{id}', name: 'show', requirements: ['id' => '\d+'], methods: ['GET'])]
|
||||
public function show(int $id, ActionService $actionService): Response
|
||||
{
|
||||
if ($this->isGranted('ROLE_ADMIN')) {
|
||||
$user = $this->getUser();
|
||||
if (!$user) {
|
||||
return $this->redirectToRoute('app_login');
|
||||
}
|
||||
|
||||
//Don't care about the null pointer because if no UO found, it won't pass the previous check
|
||||
$organization = $this->entityManager->getRepository(Organizations::class)->find($id);
|
||||
$newUsers = $this->entityManager->getRepository(UsersOrganizations::class)->getLastNewActiveUsersByOrganization($organization);
|
||||
$adminUsers = $this->entityManager->getRepository(UsersOrganizations::class)->getAdminUsersByOrganization($organization);
|
||||
// reusing the method to avoid code duplication even though it returns an array of UsersOrganizations
|
||||
$org = $this->usersOrganizationService->findActiveUsersByOrganizations([$organization]);
|
||||
|
||||
// get all applications
|
||||
$applications = $this->organizationsService->getApplicationsWithAccessStatus($organization);
|
||||
|
||||
$actions = $organization->getActions()->toArray();
|
||||
usort($actions, static function ($a, $b) {
|
||||
return $b->getDate() <=> $a->getDate();
|
||||
});
|
||||
//get the last 10 activities
|
||||
$actions = array_slice($actions, 0, 10);
|
||||
$activities = array_map(static function ($activity) use ($actionService) {
|
||||
return [
|
||||
'date' => $activity->getDate(), // or however you access the date
|
||||
'actionType' => $activity->getActionType(),
|
||||
'users' => $activity->getUsers(),
|
||||
'color' => $actionService->getActivityColor($activity->getDate())
|
||||
];
|
||||
}, $actions);
|
||||
} else {
|
||||
throw $this->createNotFoundException(self::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
return $this->render('organization/show.html.twig', [
|
||||
'organization' => $organization,
|
||||
'adminUsers' => $adminUsers,
|
||||
'newUsers' => $newUsers,
|
||||
'org' => !empty($org) ? $org[0] : null,
|
||||
'applications' => $applications,
|
||||
'activities' => $activities
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/edit/{id}', name: 'edit', requirements: ['id' => '\d+'], methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request): Response
|
||||
{
|
||||
$id = $request->attributes->get('id');
|
||||
if (!$this->isGranted('ROLE_ADMIN')) {
|
||||
throw $this->createNotFoundException(self::ACCESS_DENIED);
|
||||
}
|
||||
$organization = $this->entityManager->getRepository(Organizations::class)->find($id);
|
||||
if (!$organization) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
$form = $this->createForm(OrganizationForm::class, $organization);
|
||||
$form->handleRequest($request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$logoFile = $form->get('logoUrl')->getData();
|
||||
|
||||
if ($logoFile) {
|
||||
$currentDate = (new \DateTime())->format('Y-m-d');
|
||||
$organizationName = preg_replace('/[^a-zA-Z0-9]/', '_', $organization->getName());
|
||||
$extension = $logoFile->guessExtension();
|
||||
$newFilename = $currentDate . '_' . $organizationName . '.' . $extension;
|
||||
// Move the file to the directory where logos are stored
|
||||
$logoFile->move(
|
||||
$this->getParameter('logos_directory'),
|
||||
$newFilename
|
||||
);
|
||||
|
||||
// Update the 'logoUrl' property to store the file name
|
||||
$organization->setLogoUrl($newFilename);
|
||||
}
|
||||
$user = $this->getUser() ?? throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
$user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $user->getUserIdentifier()]);
|
||||
$this->actionService->createAction("Modification d'une organisation",$user, $organization, "{$user->getUserIdentifier()} a modifié l'organisation {$organization->getName()}");
|
||||
$this->entityManager->persist($organization);
|
||||
$this->entityManager->flush();
|
||||
$this->addFlash('success', 'Organization updated successfully');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
}
|
||||
return $this->render('organization/edit.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'organization' => $organization,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/deactivate/{id}', name: 'deactivate', requirements: ['id' => '\d+'], methods: ['GET', 'POST'])]
|
||||
public function deactivate(Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
|
||||
$id = $request->attributes->get('id');
|
||||
$organization = $this->entityManager->getRepository(Organizations::class)->find($id);
|
||||
if (!$organization) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
if ($organization->isActive() === false) {
|
||||
$this->addFlash('error', 'Organization is already deactivated');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
}
|
||||
|
||||
$organization->setIsActive(false);
|
||||
$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, $organization, "{$user->getUserIdentifier()} a désactivé l'organisation {$organization->getName()}");
|
||||
$this->entityManager->persist($organization);
|
||||
$this->entityManager->flush();
|
||||
$this->addFlash('success', 'Organization deactivated successfully');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
}
|
||||
|
||||
#[Route('/activate/{id}', name: 'activate', requirements: ['id' => '\d+'], methods: ['GET', 'POST'])]
|
||||
public function activate(Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
|
||||
$id = $request->attributes->get('id');
|
||||
$organization = $this->entityManager->getRepository(Organizations::class)->find($id);
|
||||
if (!$organization) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
if ($organization->isActive() === true) {
|
||||
$this->addFlash('error', 'Organization is already active');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
}
|
||||
|
||||
$organization->setIsActive(true);
|
||||
$this->entityManager->persist($organization);
|
||||
$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, $organization, "{$user->getUserIdentifier()} a activé l'organisation {$organization->getName()}");
|
||||
$this->entityManager->flush();
|
||||
$this->addFlash('success', 'Organization activated successfully');
|
||||
return $this->redirectToRoute('organization_index');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,385 +32,4 @@ class UserController extends AbstractController
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /user - List all users (index/collection)
|
||||
*/
|
||||
#[Route('/', name: 'index', methods: ['GET'])]
|
||||
public function index(EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||
$usersByOrganization = $this->userOrganizationService->getActiveUsersGroupedByOrganization();
|
||||
} else {
|
||||
$user = $this->getUser();
|
||||
if (!$user) {
|
||||
return $this->redirectToRoute('app_login');
|
||||
}
|
||||
$userIdentifier = $user->getUserIdentifier();
|
||||
$organizations = $this->entityManager->getRepository(UsersOrganizations::class)->findOrganizationsByUserEmailAndRoleName($userIdentifier, 'ADMIN');
|
||||
if (!$organizations) {
|
||||
// if user is not admin in any organization, throw access denied
|
||||
throw $this->createNotFoundException(self::ACCESS_DENIED);
|
||||
}
|
||||
$usersByOrganization = $this->userOrganizationService->findActiveUsersByOrganizations($organizations);
|
||||
}
|
||||
return $this->render('user/index.html.twig', [
|
||||
'usersByOrganization' => $usersByOrganization,
|
||||
'controller_name' => 'IndexController',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /user/{id} - Show specific user (show/member)
|
||||
*/
|
||||
#[Route('/{id}', name: 'show', requirements: ['id' => '\d+'], methods: ['GET'])]
|
||||
public function show(int $id, EntityManagerInterface $entityManager, Request $request): Response
|
||||
{
|
||||
|
||||
$user = $entityManager->getRepository(User::class)->find($id);
|
||||
if (!$user) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
if ($request->query->has('organizationId')) {
|
||||
$userOrganizations = $this->userOrganizationService->getUserOrganizations($user, $request->query->get('organizationId'));
|
||||
} else {
|
||||
$userOrganizations = $this->userOrganizationService->getUserOrganizations($user);
|
||||
}
|
||||
|
||||
$actingUser = $this->getUser() ?? throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
$actingUser = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $actingUser->getUserIdentifier()]);
|
||||
|
||||
$isSameUser = $user->getUserIdentifier() === $actingUser->getUserIdentifier();
|
||||
$isAdminOrg = false;
|
||||
foreach ($userOrganizations as $userOrganization) {
|
||||
$organization = $userOrganization['organization'];
|
||||
if ($this->userService->isUserAdminInOrganization($actingUser->getId(), $organization->getId())) {
|
||||
$isAdminOrg = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$this->isGranted('ROLE_SUPER_ADMIN') &&
|
||||
!$isSameUser &&
|
||||
!$isAdminOrg) {
|
||||
throw $this->createAccessDeniedException(self::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
return $this->render('user/show.html.twig', [
|
||||
'user' => $user,
|
||||
'userOrganizations' => $userOrganizations,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /user/new - Show form to create new user and handle submission
|
||||
*/
|
||||
#[Route('/new', name: 'new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted("ROLE_ADMIN");
|
||||
$form = $this->createForm(UserForm::class);
|
||||
$organizationId = $request->query->get('organizationId');
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
//Data is a User object. App\Form\NewUserForm is a form type that maps to User entity
|
||||
$data = $form->getData();
|
||||
// Handle user creation logic here
|
||||
|
||||
|
||||
//FOR DEV PURPOSES ONLY
|
||||
$data->setPictureUrl("");
|
||||
$data->setPassword($this->userService->generateRandomPassword());
|
||||
//FOR DEV PURPOSES ONLY
|
||||
$orgId = $request->get('organization_id');
|
||||
if ($orgId) {
|
||||
$organization = $this->entityManager->getRepository(Organizations::class)->find($orgId);
|
||||
$roleUser = $this->entityManager->getRepository(Roles::class)->findOneBy(['name' => 'USER']);
|
||||
if (!$organization || !$roleUser) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
$uo = new UsersOrganizations();
|
||||
$uo->setOrganization($organization);
|
||||
$uo->setRole($roleUser);
|
||||
$uo->setUsers($data);
|
||||
|
||||
//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'un utilisateur", $user, $organization, "{$user->getIdentifier()} à ajouter l'utilisateur {$data->getUserIdentifier()} à l'organisation {$organization->getName()}");
|
||||
$this->entityManager->persist($uo);
|
||||
} else {
|
||||
$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'un utilisateur", $user, null, "{$user->getIdentifier()} à ajouter l'utilisateur {$data->getUserIdentifier()} sans organisation");
|
||||
}
|
||||
$this->entityManager->persist($data);
|
||||
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
// Redirect to user index
|
||||
return $this->redirectToRoute('user_index');
|
||||
}
|
||||
|
||||
return $this->render('user/new.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'organizationId' => $organizationId,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /user/{id}/edit - Show form to edit user
|
||||
*/
|
||||
#[Route('/edit/{id}', name: 'edit', requirements: ['id' => '\d+'], methods: ['GET', 'PUT', 'POST'])]
|
||||
public function edit(int $id, EntityManagerInterface $entityManager, Request $request): Response
|
||||
{
|
||||
// Fetch user by ID and handle not found case
|
||||
$user = $entityManager->getRepository(User::class)->find($id);
|
||||
if (!$user) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
|
||||
// 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
|
||||
$form->handleRequest($request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
// Persist changes to the user entity
|
||||
$entityManager->persist($user);
|
||||
|
||||
// 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
|
||||
return $this->redirectToRoute('user_show', ['id' => $user->getId()]);
|
||||
}
|
||||
|
||||
return $this->render('user/edit.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'user' => $user,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DELETE /user/{id} - Delete user
|
||||
*/
|
||||
#[Route('/{id}', name: 'setDelete', requirements: ['id' => '\d+'], methods: ['POST'])]
|
||||
public function setDelete(int $id, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
//This method is used to set a user as deleted without actually removing them from the database.
|
||||
|
||||
//Handle access control
|
||||
if (!$this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||
throw $this->createAccessDeniedException(self::ACCESS_DENIED);
|
||||
}
|
||||
//Fetch user by ID and handle not found case
|
||||
$user = $entityManager->getRepository(User::class)->find($id);
|
||||
if (!$user) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
|
||||
// Handle user deletion logic
|
||||
$user->setIsDeleted(true);
|
||||
$entityManager->persist($user);
|
||||
// Log the action
|
||||
$actingUser = $this->getUser() ?? throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
$actingUser = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $actingUser->getUserIdentifier()]);
|
||||
$this->actionService->createAction("Supression d'un utilisateur", $actingUser, null, "{$actingUser->getIdentifier()} a supprimé l'utilisateur {$user->getUserIdentifier()}");
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('user_index');
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE /user/{id} - Delete user
|
||||
*/
|
||||
#[Route('/{id}', name: 'delete', requirements: ['id' => '\d+'], methods: ['DELETE'])]
|
||||
public function delete(int $id, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
if (!$this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||
throw $this->createAccessDeniedException(self::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
$user = $entityManager->getRepository(User::class)->find($id);
|
||||
if (!$user) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
|
||||
// Handle user deletion logic
|
||||
$entityManager->remove($user);
|
||||
// Log the action
|
||||
|
||||
$actingUser = $this->getUser() ?? throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
$actingUser = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $actingUser->getUserIdentifier()]);
|
||||
$this->actionService->createAction("Suppression définitive d'un utilisateur", $actingUser, null, "{$actingUser->getIdentifier()} a supprimé l'utilisateur {$user->getUserIdentifier()}");
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('user_index');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* GET /user/deactivate/{id} - Deactivate user
|
||||
* This method is used to deactivate a user without deleting them.
|
||||
* The user will still exist in the database but will not be active.
|
||||
*/
|
||||
#[Route('/deactivate/{id}', name: 'deactivate', methods: ['GET'])]
|
||||
public function deactivate(Request $request, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
|
||||
$userId = $request->attributes->get('id');
|
||||
$user = $entityManager->getRepository(User::class)->find($userId);
|
||||
if (!$user) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
$user->setIsActive(false);
|
||||
$entityManager->persist($user);
|
||||
// Log the action
|
||||
$actingUser = $this->getUser() ?? throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
$actingUser = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $actingUser->getUserIdentifier()]);
|
||||
$this->actionService->createAction("Désactivation d'un utilisateur", $actingUser, null, "{$actingUser->getIdentifier()} a désactivé l'utilisateur {$user->getUserIdentifier()}");
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute('user_index');
|
||||
}
|
||||
return new Response('Unauthorized', Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update organization user /userOrganizationEdit/{id} - Update organization user
|
||||
* The id parameter is the ID of the UsersOrganizations entity.
|
||||
*/
|
||||
#[Route('/userOrganizationEdit/{id}', name: 'organization_edit', requirements: ['id' => '\d+'], methods: ['GET', 'POST'])]
|
||||
public function userOrganizationEdit(int $id, Request $request, EntityManagerInterface $entityManager, Packages $packages): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
// get the UsersOrganizations entity by ID and handle not found case same for user
|
||||
$userOrganization = $entityManager->getRepository(UsersOrganizations::class)->find($id);
|
||||
if (!$userOrganization) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
$user = $userOrganization->getUsers() ?? throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
$organization = $userOrganization->getOrganization() ?? throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
|
||||
//Handle the POST
|
||||
if ($request->isMethod('POST')) {
|
||||
// Get the selected roles and apps from the request
|
||||
$selectedRoles = $request->request->all('roles');
|
||||
$selectedApps = $request->request->all('applications');
|
||||
|
||||
// order in important here. apps MUST be before roles
|
||||
$this->userOrganizationService->setUserOrganizationsApps($user, $organization, $selectedApps);
|
||||
$this->userOrganizationService->setUserOrganizations($user, $organization, $selectedRoles);
|
||||
|
||||
|
||||
// Redirect to the user profile after successful update
|
||||
return $this->redirectToRoute('user_show', ['id' => $user->getId()]);
|
||||
}
|
||||
|
||||
//Overwrite the userOrganization with the userOrganizationsService for data consistency
|
||||
// NULL pointer won't occur here because a valid UsersOrganizations entity was fetched above
|
||||
$userOrganization = $this->userOrganizationService->getUserOrganizations($userOrganization->getUsers(), $userOrganization->getOrganization()->getId());
|
||||
|
||||
// Fetch all roles and apps
|
||||
$roles = $entityManager->getRepository(Roles::class)->findAll();
|
||||
$apps = $organization->getApps() ?? throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
if (!$roles) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
if (!$apps) {
|
||||
throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
}
|
||||
|
||||
// Map roles and apps to arrays for rendering
|
||||
$rolesArray = array_map(static function ($role) {
|
||||
return [
|
||||
'id' => $role->getId(),
|
||||
'name' => $role->getName()
|
||||
];
|
||||
}, $roles);
|
||||
$appsArray = [];
|
||||
foreach ($apps as $app) {
|
||||
$appsArray[] = [
|
||||
'id' => $app->getId(),
|
||||
'name' => $app->getName(),
|
||||
'icon' => $packages->getUrl($app->getLogoUrl()),
|
||||
];
|
||||
}
|
||||
|
||||
// Map selected roles and apps to their IDs for the form
|
||||
$selectedRoles = array_map(static function ($role) {
|
||||
return $role->getId();
|
||||
}, $userOrganization[0]["roles"]);
|
||||
$selectedApps = array_map(static function ($app) {
|
||||
return $app->getId();
|
||||
}, $userOrganization[0]["apps"]);
|
||||
|
||||
return $this->render('user/organization/edit.html.twig', [
|
||||
'userOrganization' => $userOrganization,
|
||||
'user' => $user,
|
||||
'rolesArray' => $rolesArray,
|
||||
'selectedRoleIds' => $selectedRoles,
|
||||
'appsArray' => $appsArray,
|
||||
'selectedAppIds' => $selectedApps,]);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /user/deactivateOrganization/{id} - Deactivate user
|
||||
* This method is used to deactivate a user without deleting them in an organization.
|
||||
* The user will still exist in the database but will not be active.
|
||||
*/
|
||||
#[Route('/organizationDeactivate/{id}', name: 'organization_deactivate', requirements: ['id' => '\d+'], methods: ['GET'])]
|
||||
public function deactivateUserOrganization(int $id, Request $request, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
$userOrganization = $entityManager->getRepository(UsersOrganizations::class)->find($id) ?? throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
$user = $userOrganization->getUsers() ?? throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
$organization = $userOrganization->getOrganization() ?? throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
|
||||
$this->userOrganizationService->deactivateAllUserRoles($user, $organization);
|
||||
$actingUser = $this->getUser() ?? throw $this->createNotFoundException(self::NOT_FOUND);
|
||||
$actingUser = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $actingUser->getUserIdentifier()]);
|
||||
$this->actionService->createAction("Désactivation d'un utilisateur dans une organisation", $actingUser, $organization, "{$actingUser->getIdentifier()} a désactivé l'utilisateur {$user->getUserIdentifier()} dans l'organisation {$organization->getName()}");
|
||||
|
||||
return $this->redirectToRoute('user_show', ['id' => $user->getId()]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
|
||||
class UserOrganization extends AbstractType
|
||||
{
|
||||
|
||||
public function buildForm($builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('admin' , CheckboxType::class, [
|
||||
'label' => 'Admin',
|
||||
'required' => false])
|
||||
->add('application' , ChoiceType::class, [
|
||||
'label' => 'Application',
|
||||
'choices' => [
|
||||
'Application 1' => 'app1',
|
||||
'Application 2' => 'app2',
|
||||
'Application 3' => 'app3',
|
||||
]]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -20,115 +20,4 @@ class UsersOrganizationsRepository extends ServiceEntityRepository
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find organizations where a user has a specific role (e.g., ADMIN)
|
||||
*
|
||||
* @param string $userEmail
|
||||
* @param string $roleName
|
||||
* @return array Array of UsersOrganizations entities (with organizations preloaded)
|
||||
*/
|
||||
public function findUserOrganizationsByRole(string $userEmail, string $roleName): array
|
||||
{
|
||||
return $this->createQueryBuilder('uo')
|
||||
->select('uo, o')
|
||||
->innerJoin('uo.users', 'u')
|
||||
->innerJoin('uo.organization', 'o')
|
||||
->innerJoin('uo.userOrganizatonApps', 'uoa')
|
||||
->innerJoin('uoa.role', 'r')
|
||||
->where('u.email = :email')
|
||||
->andWhere('r.name = :roleName')
|
||||
->andWhere('uo.isActive = :isActive')
|
||||
->andWhere('u.isActive = :userIsActive')
|
||||
->andWhere('o.isActive = :orgIsActive')
|
||||
->andWhere('uoa.isActive = :uoaIsActive')
|
||||
->setParameter('email', $userEmail)
|
||||
->setParameter('roleName', $roleName)
|
||||
->setParameter('isActive', true)
|
||||
->setParameter('userIsActive', true)
|
||||
->setParameter('orgIsActive', true)
|
||||
->setParameter('uoaIsActive', true)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all active user-organization relationships.
|
||||
* Optionally filter by specific organizations.
|
||||
*
|
||||
* @param array|null $organizations Array of Organization entities to filter by
|
||||
* @return array Array of UsersOrganizations entities
|
||||
*/
|
||||
public function getAllActiveUserOrganizationLinks(array $organizations = null): array
|
||||
{
|
||||
$queryBuilder = $this->createQueryBuilder('uo')
|
||||
->innerJoin('uo.users', 'u')
|
||||
->innerJoin('uo.organization', 'o')
|
||||
->where('uo.isActive = :isActive')
|
||||
->andWhere('u.isActive = :userIsActive')
|
||||
->andWhere('u.isDeleted = :userIsDeleted')
|
||||
->andWhere('o.isActive = :orgIsActive')
|
||||
->andWhere('o.isDeleted = :orgIsDeleted')
|
||||
->setParameter('isActive', true)
|
||||
->setParameter('userIsActive', true)
|
||||
->setParameter('userIsDeleted', false)
|
||||
->setParameter('orgIsActive', true)
|
||||
->setParameter('orgIsDeleted', false)
|
||||
->orderBy('o.name', 'ASC')
|
||||
->addOrderBy('u.surname', 'ASC');
|
||||
|
||||
// Filter by specific organizations if provided
|
||||
if ($organizations !== null && !empty($organizations)) {
|
||||
$queryBuilder->andWhere('uo.organization IN (:organizations)')
|
||||
->setParameter('organizations', $organizations);
|
||||
}
|
||||
|
||||
return $queryBuilder->getQuery()->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all active users who are not in any organization.
|
||||
*
|
||||
* @return array Array of User entities
|
||||
*/
|
||||
public function getUsersWithoutOrganizations(): array
|
||||
{
|
||||
return $this->getEntityManager()->getRepository(User::class)
|
||||
->createQueryBuilder('u')
|
||||
->leftJoin('App\Entity\UsersOrganizations', 'uo', 'WITH', 'uo.users = u AND uo.isActive = true')
|
||||
->where('u.isActive = :userIsActive')
|
||||
->andWhere('u.isDeleted = :userIsDeleted')
|
||||
->andWhere('uo.id IS NULL')
|
||||
->setParameter('userIsActive', true)
|
||||
->setParameter('userIsDeleted', false)
|
||||
->orderBy('u.surname', 'ASC')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the last 10 new active users for a specific organization.
|
||||
// * Users are ordered by creation date (most recent first).
|
||||
// *
|
||||
// * @param Organizations $organization
|
||||
// * @return array
|
||||
// */
|
||||
// public function getLastNewActiveUsersByOrganization(Organizations $organization): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('uo')
|
||||
// ->select('u.id', 'u.surname', 'u.name', 'u.email', 'u.pictureUrl', 'u.isActive', 'uo.createdAt')
|
||||
// ->innerJoin('uo.users', 'u')
|
||||
// ->innerJoin('uo.organization', 'o')
|
||||
// ->where('uo.isActive = :isActive')
|
||||
// ->andWhere('u.isActive = :userIsActive')
|
||||
// ->andWhere('o.isActive = :orgIsActive')
|
||||
// ->andWhere('uo.organization = :organization')
|
||||
// ->setParameter('isActive', true)
|
||||
// ->setParameter('userIsActive', true)
|
||||
// ->setParameter('orgIsActive', true)
|
||||
// ->setParameter('organization', $organization)
|
||||
// ->orderBy('uo.createdAt', 'DESC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class CguUserService
|
|||
//Function can only be called if the user has already accepted the CGU
|
||||
public function declineCgu(UserInterface $user, Cgu $cgu): void
|
||||
{
|
||||
$cguUser = $this->entityManager->getRepository(CguUser::class)->findOneBy(['users' => $user, 'cgu' => $cgu]);
|
||||
$cguUser = $this->entityManager->getRepository(CguUser::class)->findOneBy(['users' => $user, 'cgu' => $cgu])?? throw new \InvalidArgumentException('CGU not found for this user');
|
||||
|
||||
$cguUser->setIsAccepted(false);
|
||||
$this->entityManager->flush();
|
||||
|
|
|
|||
|
|
@ -14,48 +14,4 @@ class OrganizationsService
|
|||
{
|
||||
}
|
||||
|
||||
public function getAdminUsers(Organizations $organization): array{
|
||||
$roleAdmin = $this->entityManager->getRepository(Roles::class)->findBy(['name' => 'ADMIN']);
|
||||
return $this->entityManager->getRepository(UsersOrganizations::class)->findBy(['organization'=>$organization,
|
||||
'role' => $roleAdmin,
|
||||
'isActive' => true]);
|
||||
}
|
||||
|
||||
public function getNewUsers(Organizations $organization): array{
|
||||
return $this->entityManager->getRepository(UsersOrganizations::class)->findBy(['organization'=>$organization,
|
||||
'isActive' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all applications with organization access status
|
||||
*
|
||||
* @param Organizations $organization
|
||||
* @return array
|
||||
*/
|
||||
public function getApplicationsWithAccessStatus(Organizations $organization): array
|
||||
{
|
||||
// Get all applications
|
||||
$allApplications = $this->entityManager->getRepository(Apps::class)->findAll();
|
||||
|
||||
// Get applications the organization has access to
|
||||
$organizationApps = $organization->getApps();
|
||||
|
||||
// Create a lookup array for faster checking
|
||||
$orgAppIds = [];
|
||||
foreach ($organizationApps as $app) {
|
||||
$orgAppIds[$app->getId()] = true;
|
||||
}
|
||||
|
||||
// Build result array
|
||||
$result = [];
|
||||
foreach ($allApplications as $app) {
|
||||
$result[] = [
|
||||
'application' => $app,
|
||||
'has_access' => isset($orgAppIds[$app->getId()])
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,474 +19,6 @@ use Symfony\Bundle\SecurityBundle\Security;
|
|||
*/
|
||||
readonly class UserOrganizationService
|
||||
{
|
||||
/**
|
||||
* Constructeur du service UserOrganizationService.
|
||||
*
|
||||
* @param EntityManagerInterface $entityManager Le gestionnaire d'entités Doctrine
|
||||
*/
|
||||
public function __construct(private readonly EntityManagerInterface $entityManager,
|
||||
private readonly UserService $userService,
|
||||
private ActionService $actionService,
|
||||
private readonly Security $security)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère toutes les organisations auxquelles appartient l'utilisateur donné,
|
||||
* incluant les rôles et applications uniques de l'utilisateur dans chaque organisation.
|
||||
*
|
||||
* @param User $user L'utilisateur concerné
|
||||
* @param int|null $organizationsId ID optionnel pour filtrer par organisation
|
||||
* @return array<array{organization:object, roles:Roles[], apps:object[], uoId:int}>
|
||||
*/
|
||||
public function getUserOrganizations(User $user, int $organizationsId = null): array
|
||||
{
|
||||
$userOrganizations = $this->entityManager
|
||||
->getRepository(UsersOrganizations::class)
|
||||
->findAllDistinctOrganizationsByUserId($user->getId());
|
||||
$organizations = [];
|
||||
|
||||
foreach ($userOrganizations as $uo) {
|
||||
$orgId = $uo->getOrganization()->getId();
|
||||
|
||||
// Si $organizationsId est fourni, ignorer les autres organisations
|
||||
if ($organizationsId !== null && $orgId !== $organizationsId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Initialiser l'entrée de l'organisation si elle n'existe pas
|
||||
$organizations[$orgId] = $organizations[$orgId] ?? $this->createEmptyOrganizationBucket($uo);
|
||||
$organizations[$orgId]['uoId'] = $uo->getId();
|
||||
|
||||
// Agréger les rôles et applications
|
||||
$this->addRole($organizations[$orgId]['roles'], $uo->getRole());
|
||||
$this->addApps($organizations[$orgId]['apps'], $uo->getApps());
|
||||
}
|
||||
|
||||
// Ordonner les rôles : Super Admin, Admin, puis les autres
|
||||
foreach ($organizations as &$org) {
|
||||
$org['roles'] = $this->sortRoles($org['roles']);
|
||||
}
|
||||
unset($org);
|
||||
|
||||
$this->normalizeAppsIndexes($organizations);
|
||||
|
||||
return array_values($organizations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trie les rôles pour que Super Admin et Admin soient en premier, puis les autres.
|
||||
*
|
||||
* @param Roles[] $roles
|
||||
* @return Roles[]
|
||||
*/
|
||||
private function sortRoles(array $roles): array
|
||||
{
|
||||
usort($roles, function ($a, $b) {
|
||||
$priority = [
|
||||
'SUPER_ADMIN' => 0,
|
||||
'ADMIN' => 1
|
||||
];
|
||||
$aName = strtoupper($a->getName());
|
||||
$bName = strtoupper($b->getName());
|
||||
$aPriority = $priority[$aName] ?? 2;
|
||||
$bPriority = $priority[$bName] ?? 2;
|
||||
if ($aPriority === $bPriority) {
|
||||
return strcmp($aName, $bName);
|
||||
}
|
||||
return $aPriority <=> $bPriority;
|
||||
});
|
||||
return $roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise la structure de données pour une organisation.
|
||||
*
|
||||
* @param UsersOrganizations $link Lien utilisateur-organisation
|
||||
* @return array{organization:object, roles:Roles[], apps:array<int,object>}
|
||||
*/
|
||||
private function createEmptyOrganizationBucket(UsersOrganizations $link): array
|
||||
{
|
||||
return [
|
||||
'organization' => $link->getOrganization(),
|
||||
'roles' => [],
|
||||
'apps' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute un rôle à la liste s'il n'est pas déjà présent (par ID).
|
||||
*
|
||||
* @param Roles[] &$roles Liste des rôles
|
||||
* @param Roles|null $role Rôle à ajouter
|
||||
* @return void
|
||||
*/
|
||||
private function addRole(array &$roles, ?Roles $role): void
|
||||
{
|
||||
if ($role === null) {
|
||||
return;
|
||||
}
|
||||
foreach ($roles as $existingRole) {
|
||||
if ($existingRole->getId() === $role->getId()) {
|
||||
return; // Already present
|
||||
}
|
||||
}
|
||||
$roles[] = $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fusionne une ou plusieurs applications dans le tableau associatif, une entrée par ID.
|
||||
*
|
||||
* @param array<int,object> &$apps Tableau des applications
|
||||
* @param iterable $appsToAdd Applications à ajouter
|
||||
* @return void
|
||||
*/
|
||||
private function addApps(array &$apps, iterable $appsToAdd): void
|
||||
{
|
||||
foreach ($appsToAdd as $app) {
|
||||
$apps[$app->getId()] = $apps[$app->getId()] ?? $app;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise le tableau des applications pour le rendre indexé (JSON-friendly).
|
||||
*
|
||||
* @param array &$organizations Tableau des organisations
|
||||
* @return void
|
||||
*/
|
||||
private function normalizeAppsIndexes(array &$organizations): void
|
||||
{
|
||||
foreach ($organizations as &$org) {
|
||||
$org['apps'] = array_values($org['apps']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Définit les rôles d'un utilisateur dans une organisation, en s'assurant que le rôle USER est toujours présent.
|
||||
* Désactive tous les rôles si USER n'est pas sélectionné.
|
||||
*
|
||||
* @param User $user L'utilisateur
|
||||
* @param Organizations $organization L'organisation
|
||||
* @param array $selectedRoles Tableau des IDs de rôles sélectionnés
|
||||
* @return void
|
||||
* @throws \RuntimeException Si le rôle USER n'est pas trouvé
|
||||
*/
|
||||
public function setUserOrganizations(User $user, Organizations $organization, array $selectedRoles): void
|
||||
{
|
||||
$repo = $this->entityManager->getRepository(UsersOrganizations::class);
|
||||
$roleRepo = $this->entityManager->getRepository(Roles::class);
|
||||
$userRole = $roleRepo->findOneBy(['name' => 'USER']);
|
||||
if (!$userRole) {
|
||||
throw new \RuntimeException('USER role not found');
|
||||
}
|
||||
if (!in_array($userRole->getId(), $selectedRoles)) {
|
||||
$this->deactivateAllUserRoles($user, $organization);
|
||||
return;
|
||||
}
|
||||
$currentUserOrgs = $repo->findBy([
|
||||
'users' => $user,
|
||||
'organization' => $organization
|
||||
]);
|
||||
$currentRolesMap = $this->mapUserOrgRoles($currentUserOrgs);
|
||||
$selectedRoles = $this->ensureUserRolePresent($selectedRoles, $userRole->getId());
|
||||
$this->addOrUpdateRoles($selectedRoles, $currentRolesMap, $roleRepo, $user, $organization);
|
||||
$this->deactivateUnselectedRoles($currentRolesMap);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour les applications associées à l'utilisateur dans une organisation.
|
||||
*
|
||||
* @param User $user L'utilisateur
|
||||
* @param Organizations $organization L'organisation
|
||||
* @param array $selectedApps Tableau des IDs d'applications sélectionnées
|
||||
* @return void
|
||||
*/
|
||||
public function setUserOrganizationsApps(User $user, Organizations $organization, array $selectedApps): void
|
||||
{
|
||||
$roleUser = $this->entityManager->getRepository(Roles::class)->findOneBy(['name' => 'USER']);
|
||||
$uoEntity = $this->entityManager
|
||||
->getRepository(UsersOrganizations::class)
|
||||
->findOneBy(['users' => $user, 'organization' => $organization, 'role' => $roleUser]);
|
||||
if (!$uoEntity) {
|
||||
return;
|
||||
}
|
||||
$this->removeUnselectedApps($uoEntity, $selectedApps);
|
||||
$this->addSelectedApps($uoEntity, $selectedApps);
|
||||
$this->entityManager->persist($uoEntity);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée une map des rôles actuels de l'utilisateur dans l'organisation.
|
||||
* @param array $currentUserOrgs
|
||||
* @return array
|
||||
*/
|
||||
private function mapUserOrgRoles(array $currentUserOrgs): array
|
||||
{
|
||||
$map = [];
|
||||
foreach ($currentUserOrgs as $uo) {
|
||||
$map[$uo->getRole()->getId()] = $uo;
|
||||
}
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* S'assure que le rôle USER est présent dans la sélection si nécessaire.
|
||||
* @param array $selectedRoles
|
||||
* @param int $userRoleId
|
||||
* @return array
|
||||
*/
|
||||
private function ensureUserRolePresent(array $selectedRoles, int $userRoleId): array
|
||||
{
|
||||
$hasNonUserRole = false;
|
||||
foreach ($selectedRoles as $roleId) {
|
||||
if ($roleId !== $userRoleId) {
|
||||
$hasNonUserRole = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($hasNonUserRole && !in_array($userRoleId, $selectedRoles)) {
|
||||
$selectedRoles[] = $userRoleId;
|
||||
}
|
||||
return $selectedRoles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute ou réactive les rôles sélectionnés pour l'utilisateur dans l'organisation.
|
||||
* @param array $selectedRoles
|
||||
* @param array $currentRolesMap
|
||||
* @param $roleRepo
|
||||
* @param User $user
|
||||
* @param Organizations $organization
|
||||
*/
|
||||
private function addOrUpdateRoles(array $selectedRoles, array &$currentRolesMap, $roleRepo, User $user, Organizations $organization): void
|
||||
{
|
||||
foreach ($selectedRoles as $roleId) {
|
||||
if (!isset($currentRolesMap[$roleId])) {
|
||||
$roleEntity = $roleRepo->find($roleId);
|
||||
if ($roleEntity) {
|
||||
$newUserOrganization = new UsersOrganizations();
|
||||
$newUserOrganization->setUsers($user);
|
||||
$newUserOrganization->setRole($roleEntity);
|
||||
$newUserOrganization->setOrganization($organization);
|
||||
$newUserOrganization->setIsActive(true);
|
||||
$this->entityManager->persist($newUserOrganization);
|
||||
}
|
||||
} else {
|
||||
$currentRolesMap[$roleId]->setIsActive(true);
|
||||
$this->entityManager->persist($currentRolesMap[$roleId]);
|
||||
}
|
||||
unset($currentRolesMap[$roleId]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Désactive les rôles non sélectionnés pour l'utilisateur dans l'organisation.
|
||||
* @param array $currentRolesMap
|
||||
*/
|
||||
private function deactivateUnselectedRoles(array $currentRolesMap): void
|
||||
{
|
||||
foreach ($currentRolesMap as $uo) {
|
||||
$uo->setIsActive(false);
|
||||
$this->entityManager->persist($uo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retire les applications non sélectionnées de l'utilisateur dans l'organisation.
|
||||
* @param UsersOrganizations $uoEntity
|
||||
* @param array $selectedApps
|
||||
*/
|
||||
private function removeUnselectedApps(UsersOrganizations $uoEntity, array $selectedApps): void
|
||||
{
|
||||
foreach ($uoEntity->getApps()->toArray() as $existingApp) {
|
||||
if (!in_array($existingApp->getId(), $selectedApps)) {
|
||||
$uoEntity->removeApp($existingApp);
|
||||
//Log action
|
||||
$actingUser = $this->security->getUser()->getUserIdentifier();
|
||||
$actingUser = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $actingUser]);
|
||||
$this->actionService->createAction("Mise à jour des applications",
|
||||
$actingUser,
|
||||
$uoEntity->getOrganization(),
|
||||
"{$actingUser->getIdentifier()} a retiré les droits d'accès à {$existingApp->getName()} à
|
||||
{$uoEntity->getUsers()->getUserIdentifier()} pour l'organisation {$uoEntity->getOrganization()->getName()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute les applications sélectionnées à l'utilisateur dans l'organisation.
|
||||
* @param UsersOrganizations $uoEntity
|
||||
* @param array $selectedApps
|
||||
*/
|
||||
private function addSelectedApps(UsersOrganizations $uoEntity, array $selectedApps): void
|
||||
{
|
||||
foreach ($selectedApps as $appId) {
|
||||
$appEntity = $this->entityManager->getRepository(Apps::class)->find($appId);
|
||||
if ($appEntity && !$uoEntity->getApps()->contains($appEntity)) {
|
||||
$uoEntity->addApp($appEntity);
|
||||
$actingUser = $this->security->getUser()->getUserIdentifier();
|
||||
$actingUser = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $actingUser]);
|
||||
$this->actionService->createAction("Mise à jour des applications",
|
||||
$actingUser,
|
||||
$uoEntity->getOrganization(),
|
||||
"{$actingUser->getIdentifier()} a donné les droits d'accès à {$appEntity->getName()} à
|
||||
{$uoEntity->getUsers()->getUserIdentifier()} pour l'organisation {$uoEntity->getOrganization()->getName()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Désactive tous les rôles d'un utilisateur dans une organisation.
|
||||
*
|
||||
* @param User $user L'utilisateur
|
||||
* @param Organizations $organization L'organisation
|
||||
* @return void
|
||||
*/
|
||||
public function deactivateAllUserRoles(User $user, Organizations $organization): void
|
||||
{
|
||||
$repo = $this->entityManager->getRepository(UsersOrganizations::class);
|
||||
$userOrganizations = $repo->findBy([
|
||||
'users' => $user,
|
||||
'organization' => $organization
|
||||
]);
|
||||
foreach ($userOrganizations as $uo) {
|
||||
$uo->setIsActive(false);
|
||||
//Log action
|
||||
$actingUser = $this->security->getUser()->getUserIdentifier();
|
||||
$actingUser = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $actingUser]);
|
||||
$this->actionService->createAction("Mise à jour des Roles",
|
||||
$actingUser,
|
||||
$uo->getOrganization(),
|
||||
"{$actingUser->getIdentifier()} a désactivé le rôle {$uo->getRole()->getName()} de
|
||||
{$uo->getUsers()->getUserIdentifier()} pour l'organisation {$uo->getOrganization()->getName()}");
|
||||
$this->entityManager->persist($uo);
|
||||
}
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all active users grouped by organization.
|
||||
* Users with no organization are grouped under 'autre'.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getActiveUsersGroupedByOrganization(): array
|
||||
{
|
||||
$users = $this->entityManager->getRepository(User::class)->getAllActiveUsers();
|
||||
$userOrgs = $this->entityManager->getRepository(UsersOrganizations::class)->getAllActiveUserOrganizationLinks();
|
||||
|
||||
$userToOrgs = $this->mapUserToOrganizations($userOrgs);
|
||||
|
||||
$orgs = [];
|
||||
foreach ($users as $user) {
|
||||
$userId = $user['id'];
|
||||
if (isset($userToOrgs[$userId])) {
|
||||
foreach ($userToOrgs[$userId] as $orgInfo) {
|
||||
$orgId = $orgInfo['organization_id'];
|
||||
if (!isset($orgs[$orgId])) {
|
||||
$orgs[$orgId] = [
|
||||
'organization_id' => $orgId,
|
||||
'organization_name' => $orgInfo['organization_name'],
|
||||
'users' => [],
|
||||
];
|
||||
}
|
||||
// $orgs[$orgId]['users'][$userId] = $user;
|
||||
$orgs[$orgId]['users'][$userId] = [
|
||||
'users' => $user,
|
||||
'is_connected' => $this->userService->isUserConnected($user['email'])
|
||||
];
|
||||
}
|
||||
} else {
|
||||
if (!isset($orgs['autre'])) {
|
||||
$orgs['autre'] = [
|
||||
'organization_id' => null,
|
||||
'organization_name' => 'autre',
|
||||
'users' => [],
|
||||
];
|
||||
}
|
||||
$orgs['autre']['users'][$userId] = [
|
||||
'users' => $user,
|
||||
'is_connected' => $this->userService->isUserConnected($user['email'])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Convert users arrays to indexed arrays
|
||||
foreach ($orgs as &$org) {
|
||||
$org['users'] = array_values($org['users']);
|
||||
}
|
||||
|
||||
return array_values($orgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all active users for each organization in the given array.
|
||||
*
|
||||
* @param Organizations[] $organizations
|
||||
* @return array
|
||||
*/
|
||||
public function findActiveUsersByOrganizations(array $organizations): array
|
||||
{
|
||||
|
||||
if (empty($organizations)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$userOrgs = $this->entityManager->getRepository(UsersOrganizations::class)->getAllActiveUserOrganizationLinks($organizations);
|
||||
$usersByOrg = [];
|
||||
foreach ($userOrgs as $uo) {
|
||||
$org = $uo->getOrganization();
|
||||
$orgId = $org->getId();
|
||||
if (!isset($usersByOrg[$orgId])) {
|
||||
$usersByOrg[$orgId] = [
|
||||
'organization_id' => $orgId,
|
||||
'organization_name' => $org->getName(),
|
||||
'users' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$user = $uo->getUsers();
|
||||
$userId = $user->getId();
|
||||
|
||||
// Add connection status to user data
|
||||
$usersByOrg[$orgId]['users'][$userId] = [
|
||||
'users' => $user,
|
||||
'is_connected' => $this->userService->isUserConnected($user->getUserIdentifier())
|
||||
];
|
||||
}
|
||||
|
||||
// Convert users arrays to indexed arrays
|
||||
foreach ($usersByOrg as &$org) {
|
||||
$org['users'] = array_values($org['users']);
|
||||
}
|
||||
|
||||
return array_values($usersByOrg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: Map userId to their organizations (id and name), avoiding duplicates.
|
||||
*
|
||||
* @param UsersOrganizations[] $userOrgs
|
||||
* @return array
|
||||
*/
|
||||
private function mapUserToOrganizations(array $userOrgs): array
|
||||
{
|
||||
$userToOrgs = [];
|
||||
foreach ($userOrgs as $uo) {
|
||||
$userId = $uo->getUsers()->getId();
|
||||
$org = $uo->getOrganization();
|
||||
$orgId = $org->getId();
|
||||
$orgName = $org->getName();
|
||||
$userToOrgs[$userId][$orgId] = [
|
||||
'organization_id' => $orgId,
|
||||
'organization_name' => $orgName,
|
||||
];
|
||||
}
|
||||
return $userToOrgs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use App\Entity\User;
|
|||
use App\Entity\UsersOrganizations;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use League\Bundle\OAuth2ServerBundle\Model\AccessToken;
|
||||
use Random\RandomException;
|
||||
|
||||
class UserService
|
||||
{
|
||||
|
|
@ -20,6 +21,7 @@ class UserService
|
|||
|
||||
/**
|
||||
* Generate a random password for a new user until they set their own.
|
||||
* @throws RandomException
|
||||
*/
|
||||
public function generateRandomPassword(): string{
|
||||
$length = 50; // Length of the password
|
||||
|
|
@ -28,38 +30,12 @@ class UserService
|
|||
$randomPassword = '';
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$randomPassword .= $characters[rand(0, $charactersLength - 1)];
|
||||
$randomPassword .= $characters[random_int(0, $charactersLength - 1)];
|
||||
}
|
||||
|
||||
return $randomPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user is an admin in the given organization.
|
||||
*
|
||||
* @param int $userId
|
||||
* @param int $organizationId
|
||||
* @return bool
|
||||
*/
|
||||
public function isUserAdminInOrganization(int $userId, int $organizationId): bool
|
||||
{
|
||||
$user = $this->entityManager->getRepository(User::class)->find($userId);
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
$organization = $this->entityManager->getRepository(Organizations::class)->find($organizationId);
|
||||
if (!$organization) {
|
||||
return false;
|
||||
}
|
||||
$roleAdmin = $this->entityManager->getRepository(Roles::class)->findOneBy(['name'=> 'ADMIN']);
|
||||
|
||||
// Check if the user is an admin in the organization
|
||||
return !empty($this->entityManager->getRepository(UsersOrganizations::class)->findBy([
|
||||
'users' => $user,
|
||||
'organization' => $organization,
|
||||
'role' => $roleAdmin]));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user is currently connected.
|
||||
|
|
|
|||
Loading…
Reference in New Issue