From 05efbf11d95109c7905a554b92ee7924cc6115e6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?C=C3=B4me=20Chilliet?= Date: Tue, 12 Sep 2023 12:15:30 +0200 Subject: [PATCH] Fix LDAP LoginListener by adding new group relationships to caches before firing the event MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- apps/user_ldap/lib/Group_LDAP.php | 35 ++++++++++++++++++++++++++-- apps/user_ldap/lib/Group_Proxy.php | 4 ++++ apps/user_ldap/lib/LoginListener.php | 2 +- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/apps/user_ldap/lib/Group_LDAP.php b/apps/user_ldap/lib/Group_LDAP.php index b3ff63d3b5c..544c7f151ac 100644 --- a/apps/user_ldap/lib/Group_LDAP.php +++ b/apps/user_ldap/lib/Group_LDAP.php @@ -56,9 +56,9 @@ use Psr\Log\LoggerInterface; 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 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis 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 114902ff9ba..bb394156572 100644 --- a/apps/user_ldap/lib/Group_Proxy.php +++ b/apps/user_ldap/lib/Group_Proxy.php @@ -384,4 +384,8 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGet 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 b9c3c3c1742..ac5b32635c8 100644 --- a/apps/user_ldap/lib/LoginListener.php +++ b/apps/user_ldap/lib/LoginListener.php @@ -93,7 +93,7 @@ class LoginListener implements IEventListener { 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}', -- 2.39.5