diff --git a/lib/GroupManager.php b/lib/GroupManager.php index 7bb031328..52da191c3 100644 --- a/lib/GroupManager.php +++ b/lib/GroupManager.php @@ -126,9 +126,16 @@ protected function unassignUserFromGroup(IUser $user, string $gid): void { return; } + // keep empty groups if general-keep_groups is set to 1 + $keepEmptyGroups = $this->config->getAppValue( + 'user_saml', + 'general-keep_groups', + '0', + ); + if ($this->hasSamlBackend($group)) { $this->ownGroupBackend->removeFromGroup($user->getUID(), $group->getGID()); - if ($this->ownGroupBackend->countUsersInGroup($gid) === 0) { + if ($keepEmptyGroups !== '1' && $this->ownGroupBackend->countUsersInGroup($gid) === 0) { $this->dispatcher->dispatchTyped(new BeforeGroupDeletedEvent($group)); $this->ownGroupBackend->deleteGroup($group->getGID()); $this->dispatcher->dispatchTyped(new GroupDeletedEvent($group)); diff --git a/tests/unit/GroupManagerTest.php b/tests/unit/GroupManagerTest.php index 0cbbb8f08..ddc870484 100644 --- a/tests/unit/GroupManagerTest.php +++ b/tests/unit/GroupManagerTest.php @@ -187,6 +187,48 @@ public function testUnassignUserFromGroups() { $this->invokePrivate($this->ownGroupManager, 'handleUserUnassignedFromGroups', [$user, ['groupA']]); } + public function testUnassignUserFromGroupsWithKeepEmpytGroups() { + $this->getGroupManager(); + // set general-keep_groups to 1 and assert it was read + $this->config + ->expects($this->exactly(1)) + ->method('getAppValue') + ->with('user_saml', 'general-keep_groups', '0') + ->willReturn('1'); + // create user and group mock + $user = $this->createMock(IUser::class); + $groupA = $this->createMock(IGroup::class); + $groupA->method('getBackendNames') + ->willReturn(['Database', 'user_saml']); + $this->groupManager + ->method('get') + ->with('groupA') + ->willReturn($groupA); + $user->expects($this->once()) + ->method('getUID') + ->willReturn('uid'); + $groupA->expects($this->exactly(1)) + ->method('getGID') + ->willReturn('gid'); + // assert membership gets removed + $this->ownGroupBackend + ->expects($this->once()) + ->method('removeFromGroup'); + // assert no remaining group memberships + $this->ownGroupBackend + ->expects($this->never()) + ->method('countUsersInGroup') + ->willReturn(0); + // assert group is not deleted + $this->ownGroupBackend + ->expects($this->never()) + ->method('deleteGroup'); + $this->eventDispatcher->expects($this->exactly(0)) + ->method('dispatchTyped'); + + $this->invokePrivate($this->ownGroupManager, 'handleUserUnassignedFromGroups', [$user, ['groupA']]); + } + public function testAssignUserToGroups() { $this->getGroupManager(['hasSamlBackend', 'createGroupInBackend']); $user = $this->createMock(IUser::class);