New role logic to activate/deactive user in organization

This commit is contained in:
Charles 2026-02-11 11:50:47 +01:00
parent 7d1e2ee4e7
commit e64afa87db
4 changed files with 51 additions and 137 deletions

View File

@ -182,7 +182,7 @@ class OrganizationController extends AbstractController
#[Route(path: '/view/{id}', name: 'show', methods: ['GET'])]
public function view($id): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$this->denyAccessUnlessGranted('ROLE_USER');
$organization = $this->organizationsRepository->find($id);
$actingUser = $this->userService->getUserByIdentifier($this->getUser()->getUserIdentifier());
if (!$organization) {
@ -304,7 +304,7 @@ class OrganizationController extends AbstractController
#[Route(path: '/data', name: 'data', methods: ['GET'])]
public function data(Request $request): JsonResponse
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$this->denyAccessUnlessGranted('ROLE_USER');
$page = max(1, (int)$request->query->get('page', 1));

View File

@ -369,21 +369,22 @@ class UserController extends AbstractController
#[Route('/organization/activateStatus/{id}', name: 'activate_organization', methods: ['GET', 'POST'])]
public function activateStatusOrganization(int $id, Request $request): JsonResponse
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$this->denyAccessUnlessGranted('ROLE_USER');
$actingUser = $this->userService->getUserByIdentifier($this->getUser()->getUserIdentifier());
try {
if ($this->userService->hasAccessTo($actingUser, true)) {
$user = $this->userRepository->find($id);
if (!$user) {
$this->loggerService->logEntityNotFound('User', ['id' => $id], $actingUser->getId());
throw $this->createNotFoundException(self::NOT_FOUND);
}
if ($this->userService->isAdminOfUser($user)) {
$orgId = $request->get('organizationId');
$org = $this->organizationRepository->find($orgId);
if (!$org) {
$this->loggerService->logEntityNotFound('Organization', ['id' => $orgId], $actingUser->getId());
throw $this->createNotFoundException(self::NOT_FOUND);
}
$user = $this->userRepository->find($id);
if (!$user) {
$this->loggerService->logEntityNotFound('User', ['id' => $id], $actingUser->getId());
throw $this->createNotFoundException(self::NOT_FOUND);
}
$uo = $this->uoRepository->findOneBy(['users' => $user,
'organization' => $org]);
if (!$uo) {

View File

@ -19,121 +19,32 @@ class UsersOrganizationsRepository extends ServiceEntityRepository
}
/**
* Returns active user-organization mappings with joined User and Organization.
* Only active and non-deleted users and organizations are included.
*
* @return UsersOrganizations[]
* Checks if an acting user has administrative rights over a target user
* based on shared organizational memberships.
*/
public function findUsersWithOrganization(array $organizationIds = null): array
public function isUserAdminOfTarget(User $actingUser, User $targetUser, $adminRole): bool
{
$qb = $this->createQueryBuilder('uo')
->addSelect('u', 'o')
->leftJoin('uo.users', 'u')
->leftJoin('uo.organization', 'o')
->andWhere('u.isActive = :uActive')
->andWhere('u.isDeleted = :uDeleted')
->andWhere('o.isActive = :oActive')
->andWhere('o.isDeleted = :oDeleted')
->orderBy('o.name', 'ASC')
->addOrderBy('u.surname', 'ASC')
->setParameter('uActive', true)
->setParameter('uDeleted', false)
->setParameter('oActive', true)
->setParameter('oDeleted', false);
if (!empty($organizationIds)) {
$qb->andWhere('o.id IN (:orgIds)')
->setParameter('orgIds', $organizationIds);
}
$qb = $this->createQueryBuilder('uo_acting');
return $qb->getQuery()->getResult();
}
/**
* Same as above, filtered by a list of organization IDs.
*
* @param int[] $organizationIds
* @return UsersOrganizations[]
*/
public function findActiveWithUserAndOrganizationByOrganizationIds(array $organizationIds): array
{
if (empty($organizationIds)) {
return [];
}
$qb = $this->createQueryBuilder('uo')
->addSelect('u', 'o')
->leftJoin('uo.users', 'u')
->leftJoin('uo.organization', 'o')
->where('uo.isActive = :uoActive')
->andWhere('u.isActive = :uActive')
->andWhere('u.isDeleted = :uDeleted')
->andWhere('o.isActive = :oActive')
->andWhere('o.isDeleted = :oDeleted')
->andWhere('o.id IN (:orgIds)')
->orderBy('o.name', 'ASC')
->addOrderBy('u.surname', 'ASC')
->setParameter('uoActive', true)
->setParameter('uActive', true)
->setParameter('uDeleted', false)
->setParameter('oActive', true)
->setParameter('oDeleted', false)
->setParameter('orgIds', $organizationIds);
return $qb->getQuery()->getResult();
}
/**
* Find 10 newest Users in an Organization.
*
* @param Organizations $organization
* @return User[]
*/
public function findNewestUO(Organizations $organization): array
{
$qb = $this->createQueryBuilder('uo')
->select('uo', 'u')
->leftJoin('uo.users', 'u')
->where('uo.organization = :org')
->andWhere('uo.isActive = :uoActive')
->andWhere('u.isActive = :uActive')
->andWhere('u.isDeleted = :uDeleted')
->orderBy('u.createdAt', 'DESC')
->setMaxResults(10)
->setParameter('org', $organization)
->setParameter('uoActive', true)
->setParameter('uActive', true)
->setParameter('uDeleted', false);
return $qb->getQuery()->getResult();
}
/**
* Find all the admins of an Organization.
* limited to 10 results.
*
* @param Organizations $organization
* @return User[]
*/
public function findAdminsInOrganization(Organizations $organization): array
{
$qb = $this->createQueryBuilder('uo')
->select('uo', 'u')
->leftJoin('uo.users', 'u')
->leftJoin('uo.userOrganizatonApps', 'uoa')
->leftJoin('uoa.role', 'r')
->where('uo.organization = :org')
->andWhere('uo.isActive = :uoActive')
->andWhere('u.isActive = :uActive')
->andWhere('u.isDeleted = :uDeleted')
->andWhere('r.name = :roleAdmin')
->orderBy('u.surname', 'ASC')
->setMaxResults(10)
->setParameter('org', $organization)
->setParameter('uoActive', true)
->setParameter('uActive', true)
->setParameter('uDeleted', false)
->setParameter('roleAdmin', 'ADMIN');
return $qb->getQuery()->getResult();
return (bool) $qb
->select('COUNT(uo_acting.id)')
// We join the same table again to find the target user in the same organization
->innerJoin(
UsersOrganizations::class,
'uo_target',
'WITH',
'uo_target.organization = uo_acting.organization'
)
->where('uo_acting.users = :actingUser')
->andWhere('uo_acting.role = :role')
->andWhere('uo_acting.isActive = true')
->andWhere('uo_target.users = :targetUser')
->andWhere('uo_target.statut = :status')
->setParameter('actingUser', $actingUser)
->setParameter('targetUser', $targetUser)
->setParameter('role', $adminRole)
->setParameter('status', 'ACCEPTED')
->getQuery()
->getSingleScalarResult() > 0;
}
}

View File

@ -134,23 +134,25 @@ class UserService
*/
public function isAdminOfUser(User $user): bool
{
$actingUser = $this->getUserByIdentifier($this->security->getUser()->getUserIdentifier());
$roleAdmin = $this->rolesRepository->findOneBy(['name' => 'ADMIN']);
$adminUOs = $this->entityManager->getRepository(UsersOrganizations::class)->findBy([
'users' => $actingUser,
'isActive' => true,
'role'=> $roleAdmin]);
$userOrganizations = $this->entityManager->getRepository(UsersOrganizations::class)->findBy(['users' => $user, 'statut' => 'ACCEPTED', 'isActive' => true]);
if ($userOrganizations) {
foreach ($userOrganizations as $uo) {
if (in_array($uo, $adminUOs, true)) {
return true;
}
}
}
$actingUser = $this->security->getUser();
if (!$actingUser instanceof User) {
return false;
}
// Reuse the cached/fetched role
$adminRole = $this->rolesRepository->findOneBy(['name' => 'ADMIN']);
if (!$adminRole) {
return false;
}
// Call the optimized repository method
return $this->entityManager
->getRepository(UsersOrganizations::class)
->isUserAdminOfTarget($actingUser, $user, $adminRole);
}
/**
* Check if the acting user is an admin of the organization
* A user is considered an admin of an organization if they have an active UsersOrganizations link with the role of ADMIN for that organization.
@ -161,7 +163,7 @@ class UserService
*/
public function isAdminOfOrganization(Organizations $organizations): bool
{
$actingUser = $this->getUserByIdentifier($this->security->getUser()->getUserIdentifier());
$actingUser =$this->security->getUser();
$roleAdmin = $this->entityManager->getRepository(Roles::class)->findOneBy(['name' => 'ADMIN']);
$uoAdmin = $this->entityManager->getRepository(UsersOrganizations::class)->findOneBy(['users' => $actingUser,
'organization' => $organizations,