groupMembershipMapper->getKnownGroups(); $actualGroups = $this->groupBackend->getGroups(); if (empty($actualGroups) && empty($knownGroups)) { $this->logger->info( 'service "updateGroups" - groups do not seem to be configured properly, aborting.', ); return; } $this->handleKnownGroups(array_intersect($actualGroups, $knownGroups)); $this->handleCreatedGroups(array_diff($actualGroups, $knownGroups)); $this->handleRemovedGroups(array_diff($knownGroups, $actualGroups)); $this->logger->debug('service "updateGroups" - Finished.'); } /** * @param string[] $groups * @throws Exception */ public function handleKnownGroups(array $groups): void { $this->logger->debug('service "updateGroups" - Dealing with known Groups.'); foreach ($groups as $group) { $this->logger->debug('service "updateGroups" - Dealing with {group}.', ['group' => $group]); $groupMemberships = $this->groupMembershipMapper->findGroupMemberships($group); $knownUsers = array_map( static fn (GroupMembership $groupMembership): string => $groupMembership->getUserid(), $groupMemberships ); $groupMemberships = array_combine($knownUsers, $groupMemberships); $actualUsers = $this->groupBackend->usersInGroup($group); $groupObject = $this->groupManager->get($group); if ($groupObject === null) { /* We are not expecting the group to not be found since it was returned by $this->groupBackend->getGroups() */ $this->logger->error( 'service "updateGroups" - Failed to get group {group} for update', [ 'group' => $group ] ); continue; } foreach (array_diff($knownUsers, $actualUsers) as $removedUser) { try { $this->groupMembershipMapper->delete($groupMemberships[$removedUser]); } catch (Exception $e) { if ($e->getReason() !== Exception::REASON_DATABASE_OBJECT_NOT_FOUND) { /* If reason is not found something else removed the membership, that’s fine */ $this->logger->error( self::class . ' - group {group} membership failed to be removed (user {user})', [ 'app' => 'user_ldap', 'user' => $removedUser, 'group' => $group, 'exception' => $e, ] ); } /* We failed to delete the groupmembership so we do not want to advertise it */ continue; } $userObject = $this->userManager->get($removedUser); if ($userObject instanceof IUser) { $this->dispatcher->dispatchTyped(new UserRemovedEvent($groupObject, $userObject)); } $this->logger->info( 'service "updateGroups" - {user} removed from {group}', [ 'user' => $removedUser, 'group' => $group ] ); } foreach (array_diff($actualUsers, $knownUsers) as $addedUser) { try { $this->groupMembershipMapper->insert(GroupMembership::fromParams(['groupid' => $group,'userid' => $addedUser])); } catch (Exception $e) { if ($e->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) { /* If reason is unique constraint something else added the membership, that’s fine */ $this->logger->error( self::class . ' - group {group} membership failed to be added (user {user})', [ 'app' => 'user_ldap', 'user' => $addedUser, 'group' => $group, 'exception' => $e, ] ); } /* We failed to insert the groupmembership so we do not want to advertise it */ continue; } $userObject = $this->userManager->get($addedUser); if ($userObject instanceof IUser) { $this->dispatcher->dispatchTyped(new UserAddedEvent($groupObject, $userObject)); } $this->logger->info( 'service "updateGroups" - {user} added to {group}', [ 'user' => $addedUser, 'group' => $group ] ); } } $this->logger->debug('service "updateGroups" - FINISHED dealing with known Groups.'); } /** * @param string[] $createdGroups * @throws Exception */ public function handleCreatedGroups(array $createdGroups): void { $this->logger->debug('service "updateGroups" - dealing with created Groups.'); foreach ($createdGroups as $createdGroup) { $this->logger->info('service "updateGroups" - new group "' . $createdGroup . '" found.'); $users = $this->groupBackend->usersInGroup($createdGroup); $groupObject = $this->groupManager->get($createdGroup); foreach ($users as $user) { try { $this->groupMembershipMapper->insert(GroupMembership::fromParams(['groupid' => $createdGroup,'userid' => $user])); } catch (Exception $e) { if ($e->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) { $this->logger->error( self::class . ' - group {group} membership failed to be added (user {user})', [ 'app' => 'user_ldap', 'user' => $user, 'group' => $createdGroup, 'exception' => $e, ] ); } /* We failed to insert the groupmembership so we do not want to advertise it */ continue; } if ($groupObject instanceof IGroup) { $userObject = $this->userManager->get($user); if ($userObject instanceof IUser) { $this->dispatcher->dispatchTyped(new UserAddedEvent($groupObject, $userObject)); } } } } $this->logger->debug('service "updateGroups" - FINISHED dealing with created Groups.'); } /** * @param string[] $removedGroups * @throws Exception */ public function handleRemovedGroups(array $removedGroups): void { $this->logger->debug('service "updateGroups" - dealing with removed groups.'); $this->groupMembershipMapper->deleteGroups($removedGroups); foreach ($removedGroups as $group) { $groupObject = $this->groupManager->get($group); if ($groupObject instanceof IGroup) { $groupMemberships = $this->groupMembershipMapper->findGroupMemberships($group); foreach ($groupMemberships as $groupMembership) { $userObject = $this->userManager->get($groupMembership->getUserid()); if ($userObject instanceof IUser) { $this->dispatcher->dispatchTyped(new UserRemovedEvent($groupObject, $userObject)); } } } } $this->logger->info( 'service "updateGroups" - groups {removedGroups} were removed.', [ 'removedGroups' => $removedGroups ] ); } }