]> source.dussan.org Git - nextcloud-server.git/commitdiff
fix(LDAP): ensure stored groups are formatted as simple list 42405/head
authorArthur Schiwon <blizzz@arthur-schiwon.de>
Wed, 20 Dec 2023 15:56:16 +0000 (16:56 +0100)
committerArthur Schiwon <blizzz@arthur-schiwon.de>
Wed, 20 Dec 2023 16:05:58 +0000 (17:05 +0100)
With array_unique it is possible that the keys are not in sequential order
but have gaps. json_encode then would store them as associative array,
which later on json_decode would result in a stdClass by default. This is
unexpected and would also contradict the return type hint.

Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
apps/user_ldap/lib/Group_LDAP.php
apps/user_ldap/tests/Group_LDAPTest.php

index 376af8520d04005f1039479ea6f6844eaf4622ac..699205cf501b511f1119a687619b89fa242f401c 100644 (file)
@@ -685,7 +685,7 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
 
        protected function getCachedGroupsForUserId(string $uid): array {
                $groupStr = $this->config->getUserValue($uid, 'user_ldap', 'cached-group-memberships-' . $this->access->connection->getConfigPrefix(), '[]');
-               return json_decode($groupStr) ?? [];
+               return json_decode($groupStr, true) ?? [];
        }
 
        /**
@@ -838,7 +838,7 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
                        return $groups;
                }
 
-               $groups = array_unique($groups, SORT_LOCALE_STRING);
+               $groups = array_values(array_unique($groups, SORT_LOCALE_STRING));
                $this->access->connection->writeToCache($cacheKey, $groups);
 
                $groupStr = \json_encode($groups);
index cc1090bf9650527d4d90a82bd1de8ffb53e7946a..5c994b8e3a521bd2eae17d8b7e8cdac88622cc91 100644 (file)
@@ -901,6 +901,33 @@ class Group_LDAPTest extends TestCase {
                $this->assertTrue(in_array('groupF', $returnedGroups));
        }
 
+       /**
+        * regression tests against a case where a json object was stored instead of expected list
+        * @see https://github.com/nextcloud/server/issues/42374
+        */
+       public function testGetUserGroupsOfflineUserUnexpectedJson() {
+               $this->enableGroups();
+
+               $offlineUser = $this->createMock(OfflineUser::class);
+
+               $this->config->expects($this->any())
+                       ->method('getUserValue')
+                       ->with('userX', 'user_ldap', 'cached-group-memberships-', $this->anything())
+                       // results in a json object: {"0":"groupB","2":"groupF"}
+                       ->willReturn(\json_encode([0 => 'groupB', 2 => 'groupF']));
+
+               $this->access->userManager->expects($this->any())
+                       ->method('get')
+                       ->with('userX')
+                       ->willReturn($offlineUser);
+
+               $this->initBackend();
+               $returnedGroups = $this->groupBackend->getUserGroups('userX');
+               $this->assertCount(2, $returnedGroups);
+               $this->assertTrue(in_array('groupB', $returnedGroups));
+               $this->assertTrue(in_array('groupF', $returnedGroups));
+       }
+
        public function testGetUserGroupsUnrecognizedOfflineUser() {
                $this->enableGroups();
                $dn = 'cn=userX,dc=foobar';