diff --git a/apps/user_ldap/lib/Group_LDAP.php b/apps/user_ldap/lib/Group_LDAP.php index b3ff63d3b5c0f..544c7f151ac63 100644 --- a/apps/user_ldap/lib/Group_LDAP.php +++ b/apps/user_ldap/lib/Group_LDAP.php @@ -56,9 +56,9 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDisplayNameBackend, IDeleteGroupBackend { protected bool $enabled = false; - /** @var CappedMemoryCache $cachedGroupMembers array of users with gid as key */ + /** @var CappedMemoryCache $cachedGroupMembers array of user DN with gid as key */ protected CappedMemoryCache $cachedGroupMembers; - /** @var CappedMemoryCache $cachedGroupsByMember array of groups with uid as key */ + /** @var CappedMemoryCache $cachedGroupsByMember array of groups with user DN as key */ protected CappedMemoryCache $cachedGroupsByMember; /** @var CappedMemoryCache $cachedNestedGroups array of groups with gid (DN) as key */ protected CappedMemoryCache $cachedNestedGroups; @@ -1357,4 +1357,35 @@ public function getDisplayName(string $gid): string { public function dn2GroupName(string $dn): string|false { return $this->access->dn2groupname($dn); } + + public function addRelationshipToCaches(string $uid, ?string $dnUser, string $gid): void { + $dnGroup = $this->access->groupname2dn($gid); + $dnUser ??= $this->access->username2dn($uid); + if ($dnUser === false || $dnGroup === false) { + return; + } + if (isset($this->cachedGroupMembers[$gid])) { + $this->cachedGroupMembers[$gid] = array_merge($this->cachedGroupMembers[$gid], [$dnUser]); + } + unset($this->cachedGroupsByMember[$dnUser]); + unset($this->cachedNestedGroups[$gid]); + $cacheKey = 'inGroup' . $uid . ':' . $gid; + $this->access->connection->writeToCache($cacheKey, true); + $cacheKeyMembers = 'inGroup-members:' . $gid; + if (!is_null($data = $this->access->connection->getFromCache($cacheKeyMembers))) { + $this->access->connection->writeToCache($cacheKeyMembers, array_merge($data, [$dnUser])); + } + $cacheKey = '_groupMembers' . $dnGroup; + if (!is_null($data = $this->access->connection->getFromCache($cacheKey))) { + $this->access->connection->writeToCache($cacheKey, array_merge($data, [$dnUser])); + } + $cacheKey = 'getUserGroups' . $uid; + if (!is_null($data = $this->access->connection->getFromCache($cacheKey))) { + $this->access->connection->writeToCache($cacheKey, array_merge($data, [$gid])); + } + // These cache keys cannot be easily updated: + // $cacheKey = 'usersInGroup-' . $gid . '-' . $search . '-' . $limit . '-' . $offset; + // $cacheKey = 'usersInGroup-' . $gid . '-' . $search; + // $cacheKey = 'countUsersInGroup-' . $gid . '-' . $search; + } } diff --git a/apps/user_ldap/lib/Group_Proxy.php b/apps/user_ldap/lib/Group_Proxy.php index 114902ff9bad7..bb3941565723b 100644 --- a/apps/user_ldap/lib/Group_Proxy.php +++ b/apps/user_ldap/lib/Group_Proxy.php @@ -384,4 +384,8 @@ public function getBackendName(): string { public function searchInGroup(string $gid, string $search = '', int $limit = -1, int $offset = 0): array { return $this->handleRequest($gid, 'searchInGroup', [$gid, $search, $limit, $offset]); } + + public function addRelationshipToCaches(string $uid, ?string $dnUser, string $gid): void { + $this->handleRequest($gid, 'addRelationshipToCaches', [$uid, $dnUser, $gid]); + } } diff --git a/apps/user_ldap/lib/LoginListener.php b/apps/user_ldap/lib/LoginListener.php index d2aea689efd95..53d4ccc12b9e5 100644 --- a/apps/user_ldap/lib/LoginListener.php +++ b/apps/user_ldap/lib/LoginListener.php @@ -93,7 +93,7 @@ private function updateGroups(IUser $userObject): void { continue; } $this->groupMembershipMapper->insert(GroupMembership::fromParams(['groupid' => $groupId,'userid' => $userId])); - // TODO: empty cache to avoid crash + $this->groupBackend->addRelationshipToCaches($userId, null, $groupId); $this->dispatcher->dispatchTyped(new UserAddedEvent($groupObject, $userObject)); $this->logger->info( __CLASS__ . ' – {user} added to {group}',