add Admin when Super Admin is added
This commit is contained in:
parent
41c6e82a13
commit
a01df6345a
|
|
@ -93,24 +93,45 @@ class UserOrganizationAppService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronizes user roles for a specific application within an organization.
|
||||||
|
*
|
||||||
|
* This method handles the complete lifecycle of user-application role assignments:
|
||||||
|
* - Activates/deactivates existing role links based on selection
|
||||||
|
* - Creates new role assignments for newly selected roles
|
||||||
|
* - Updates the user's global Symfony security roles when ADMIN/SUPER_ADMIN roles are assigned
|
||||||
|
*
|
||||||
|
* @param UsersOrganizations $uo The user-organization relationship
|
||||||
|
* @param Apps $application The target application
|
||||||
|
* @param array $selectedRoleIds Array of role IDs that should be active for this user-app combination
|
||||||
|
* @param User $actingUser The user performing this action (for audit logging)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws \Exception If role entities cannot be found or persisted
|
||||||
|
*/
|
||||||
public function syncRolesForUserOrganizationApp(
|
public function syncRolesForUserOrganizationApp(
|
||||||
UsersOrganizations $uo,
|
UsersOrganizations $uo,
|
||||||
Apps $application,
|
Apps $application,
|
||||||
array $selectedRoleIds,
|
array $selectedRoleIds,
|
||||||
User $actingUser
|
User $actingUser
|
||||||
): void {
|
): void {
|
||||||
$repo = $this->entityManager->getRepository(UserOrganizatonApp::class);
|
|
||||||
$currentLinks = $repo->findBy([
|
// Fetch existing UserOrganizationApp links for this user and application
|
||||||
|
$uoas = $this->entityManager->getRepository(UserOrganizatonApp::class)->findBy([
|
||||||
'userOrganization' => $uo,
|
'userOrganization' => $uo,
|
||||||
'application' => $application,
|
'application' => $application,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$currentRoleIds = [];
|
$currentRoleIds = [];
|
||||||
foreach ($currentLinks as $uoa) {
|
// Process existing role links - activate or deactivate based on selection
|
||||||
|
foreach ($uoas as $uoa) {
|
||||||
$roleId = $uoa->getRole()->getId();
|
$roleId = $uoa->getRole()->getId();
|
||||||
$currentRoleIds[] = $roleId;
|
$currentRoleIds[] = $roleId;
|
||||||
|
$roleName = $uoa->getRole()->getName();
|
||||||
|
|
||||||
if (in_array($roleId, $selectedRoleIds)) {
|
if (in_array((string) $roleId, $selectedRoleIds, true)) {
|
||||||
|
// Role is selected - ensure it's active
|
||||||
if (!$uoa->isActive()) {
|
if (!$uoa->isActive()) {
|
||||||
$uoa->setIsActive(true);
|
$uoa->setIsActive(true);
|
||||||
$this->entityManager->persist($uoa);
|
$this->entityManager->persist($uoa);
|
||||||
|
|
@ -118,10 +139,19 @@ class UserOrganizationAppService
|
||||||
"Re-activate user role for application",
|
"Re-activate user role for application",
|
||||||
$actingUser,
|
$actingUser,
|
||||||
$uo->getOrganization(),
|
$uo->getOrganization(),
|
||||||
"App: {$application->getName()}, Role: {$uoa->getRole()->getName()} for user {$uo->getUsers()->getUserIdentifier()}"
|
"App: {$application->getName()}, Role: $roleName for user {$uo->getUsers()->getUserIdentifier()}"
|
||||||
);
|
);
|
||||||
|
// Sync Admins roles to user's global Symfony security roles
|
||||||
|
if (in_array($roleName, ['ADMIN', 'SUPER ADMIN'], true)) {
|
||||||
|
$this->userService->syncUserRoles($uo->getUsers(), $roleName, true);
|
||||||
|
}
|
||||||
|
// Ensure ADMIN role is assigned if SUPER ADMIN is activated
|
||||||
|
if ($roleName === 'SUPER ADMIN') {
|
||||||
|
$this->ensureAdminRoleForSuperAdmin($uoa);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Role is not selected - ensure it's inactive
|
||||||
if ($uoa->isActive()) {
|
if ($uoa->isActive()) {
|
||||||
$uoa->setIsActive(false);
|
$uoa->setIsActive(false);
|
||||||
$this->entityManager->persist($uoa);
|
$this->entityManager->persist($uoa);
|
||||||
|
|
@ -130,23 +160,37 @@ class UserOrganizationAppService
|
||||||
"Deactivate user role for application",
|
"Deactivate user role for application",
|
||||||
$actingUser,
|
$actingUser,
|
||||||
$uo->getOrganization(),
|
$uo->getOrganization(),
|
||||||
"App: {$application->getName()}, Role: {$uoa->getRole()->getName()} for user {$uo->getUsers()->getUserIdentifier()}"
|
"App: {$application->getName()}, Role: $roleName for user {$uo->getUsers()->getUserIdentifier()}"
|
||||||
);
|
);
|
||||||
|
// Sync Admins roles to user's global Symfony security roles
|
||||||
|
if (in_array($roleName, ['ADMIN', 'SUPER ADMIN'], true)) {
|
||||||
|
$this->userService->syncUserRoles($uo->getUsers(), $roleName, false);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add missing roles
|
// Create new role assignments for roles that don't exist yet
|
||||||
foreach ($selectedRoleIds as $roleId) {
|
foreach ($selectedRoleIds as $roleId) {
|
||||||
if (!in_array($roleId, $currentRoleIds)) {
|
if (!in_array($roleId, $currentRoleIds)) {
|
||||||
$role = $this->entityManager->getRepository(Roles::class)->find($roleId);
|
$role = $this->entityManager->getRepository(Roles::class)->find($roleId);
|
||||||
if ($role) {
|
if ($role) {
|
||||||
|
// Create new user-organization-application role link
|
||||||
$newUoa = new UserOrganizatonApp();
|
$newUoa = new UserOrganizatonApp();
|
||||||
$newUoa->setUserOrganization($uo);
|
$newUoa->setUserOrganization($uo);
|
||||||
$newUoa->setApplication($application);
|
$newUoa->setApplication($application);
|
||||||
$newUoa->setRole($role);
|
$newUoa->setRole($role);
|
||||||
$newUoa->setIsActive(true);
|
$newUoa->setIsActive(true);
|
||||||
|
|
||||||
|
// Sync Admins roles to user's global Symfony security roles
|
||||||
|
if (in_array($role->getName(), ['ADMIN', 'SUPER ADMIN'], true)) {
|
||||||
|
$this->userService->syncUserRoles($uo->getUsers(), $role->getName(), true);
|
||||||
|
}
|
||||||
|
// Ensure ADMIN role is assigned if SUPER ADMIN is activated
|
||||||
|
if ($role->getName() === 'SUPER ADMIN') {
|
||||||
|
$this->ensureAdminRoleForSuperAdmin($newUoa);
|
||||||
|
}
|
||||||
$this->entityManager->persist($newUoa);
|
$this->entityManager->persist($newUoa);
|
||||||
$this->actionService->createAction("New user role for application",
|
$this->actionService->createAction("New user role for application",
|
||||||
$actingUser,
|
$actingUser,
|
||||||
|
|
@ -155,8 +199,34 @@ class UserOrganizationAppService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute the role Admin to the user if the user has the role Super Admin
|
||||||
|
*
|
||||||
|
* @param UserOrganizatonApp $uoa
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function ensureAdminRoleForSuperAdmin(UserOrganizatonApp $uoa): void
|
||||||
|
{
|
||||||
|
$uoaAdmin = $this->entityManager->getRepository(UserOrganizatonApp::class)->findOneBy([
|
||||||
|
'userOrganization' => $uoa->getUserOrganization(),
|
||||||
|
'application' => $uoa->getApplication(),
|
||||||
|
'role' => $this->entityManager->getRepository(Roles::class)->findOneBy(['name' => 'ADMIN'])
|
||||||
|
]);
|
||||||
|
if(!$uoaAdmin) {
|
||||||
|
$uoaAdmin = new UserOrganizatonApp();
|
||||||
|
$uoaAdmin->setUserOrganization($uoa->getUserOrganization());
|
||||||
|
$uoaAdmin->setApplication($uoa->getApplication());
|
||||||
|
$uoaAdmin->setRole($this->entityManager->getRepository(Roles::class)->findOneBy(['name' => 'ADMIN']));
|
||||||
|
$uoaAdmin->setIsActive(true);
|
||||||
|
$this->entityManager->persist($uoaAdmin);
|
||||||
|
}
|
||||||
|
// If the ADMIN role link exists but is inactive, activate it
|
||||||
|
if ($uoaAdmin && !$uoaAdmin->isActive()) {
|
||||||
|
$uoaAdmin->setIsActive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -289,4 +289,71 @@ class UserService
|
||||||
|
|
||||||
return $users;
|
return $users;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle user's role synchronization
|
||||||
|
*
|
||||||
|
* @param User $user
|
||||||
|
* @param string $role
|
||||||
|
* @param boolean $add
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function syncUserRoles(User $user, string $role, bool $add): void
|
||||||
|
{
|
||||||
|
$roleFormatted = $this->formatRoleString($role);
|
||||||
|
|
||||||
|
if ($add) {
|
||||||
|
// Add the main role if not already present
|
||||||
|
if (!in_array($roleFormatted, $user->getRoles(), true)) {
|
||||||
|
$user->setRoles(array_merge($user->getRoles(), [$roleFormatted]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If SUPER ADMIN is given → ensure ADMIN is also present
|
||||||
|
if ($roleFormatted === 'ROLE_SUPER_ADMIN' && !in_array('ROLE_ADMIN', $user->getRoles(), true)) {
|
||||||
|
$user->setRoles(array_merge($user->getRoles(), ['ROLE_ADMIN']));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Remove the role if present and not used elsewhere
|
||||||
|
if (in_array($roleFormatted, $user->getRoles(), true)) {
|
||||||
|
$uos = $this->entityManager->getRepository(UsersOrganizations::class)
|
||||||
|
->findBy(['users' => $user, 'isActive' => true]);
|
||||||
|
|
||||||
|
$hasRole = false;
|
||||||
|
foreach ($uos as $uo) {
|
||||||
|
$uoa = $this->entityManager->getRepository(UserOrganizatonApp::class)
|
||||||
|
->findBy([
|
||||||
|
'userOrganization' => $uo,
|
||||||
|
'isActive' => true,
|
||||||
|
'role' => $this->entityManager->getRepository(Roles::class)
|
||||||
|
->findOneBy(['name' => $role]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($uoa) {
|
||||||
|
$hasRole = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only remove globally if no other app gives this role
|
||||||
|
if (!$hasRole) {
|
||||||
|
$roles = $user->getRoles();
|
||||||
|
$roles = array_filter($roles, fn($r) => $r !== $roleFormatted);
|
||||||
|
$user->setRoles($roles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format role string to match the ROLE_ convention
|
||||||
|
*/
|
||||||
|
public function formatRoleString(string $role): string
|
||||||
|
{
|
||||||
|
$role = str_replace(' ', '_', trim($role));
|
||||||
|
$role = strtoupper($role);
|
||||||
|
if (str_starts_with($role, 'ROLE_')) {
|
||||||
|
return $role;
|
||||||
|
}
|
||||||
|
return 'ROLE_' . $role;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue