]> source.dussan.org Git - nextcloud-server.git/commitdiff
Fix LDAP LoginListener by adding new group relationships to caches before firing...
authorCôme Chilliet <come.chilliet@nextcloud.com>
Tue, 12 Sep 2023 10:15:30 +0000 (12:15 +0200)
committerCôme Chilliet <come.chilliet@nextcloud.com>
Thu, 12 Oct 2023 08:13:43 +0000 (10:13 +0200)
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
apps/user_ldap/lib/Group_LDAP.php
apps/user_ldap/lib/Group_Proxy.php
apps/user_ldap/lib/LoginListener.php

index b3ff63d3b5c0f46dbab888bb861ddd2faf509481..544c7f151ac63eb31c796620290a7960cde46fb0 100644 (file)
@@ -56,9 +56,9 @@ use Psr\Log\LoggerInterface;
 class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDisplayNameBackend, IDeleteGroupBackend {
        protected bool $enabled = false;
 
-       /** @var CappedMemoryCache<string[]> $cachedGroupMembers array of users with gid as key */
+       /** @var CappedMemoryCache<string[]> $cachedGroupMembers array of user DN with gid as key */
        protected CappedMemoryCache $cachedGroupMembers;
-       /** @var CappedMemoryCache<array[]> $cachedGroupsByMember array of groups with uid as key */
+       /** @var CappedMemoryCache<array[]> $cachedGroupsByMember array of groups with user DN as key */
        protected CappedMemoryCache $cachedGroupsByMember;
        /** @var CappedMemoryCache<string[]> $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;
+       }
 }
index 114902ff9bad730b6b5784acfdf03ce8034c623f..bb3941565723bdf6fcb96c3ff0cdf2c19a8bff08 100644 (file)
@@ -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]);
+       }
 }
index b9c3c3c17428c05ebcb4860de1de90f11e4a7063..ac5b32635c8f5d9b27094f4c41763d8a84eec0f3 100644 (file)
@@ -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}',