diff options
Diffstat (limited to 'tests/lib/Collaboration/Collaborators/UserPluginTest.php')
-rw-r--r-- | tests/lib/Collaboration/Collaborators/UserPluginTest.php | 293 |
1 files changed, 222 insertions, 71 deletions
diff --git a/tests/lib/Collaboration/Collaborators/UserPluginTest.php b/tests/lib/Collaboration/Collaborators/UserPluginTest.php index 2806540d00e..cb4949fb86d 100644 --- a/tests/lib/Collaboration/Collaborators/UserPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/UserPluginTest.php @@ -1,30 +1,15 @@ <?php + /** - * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Collaboration\Collaborators; use OC\Collaboration\Collaborators\SearchResult; use OC\Collaboration\Collaborators\UserPlugin; +use OC\KnownUser\KnownUserService; use OCP\Collaboration\Collaborators\ISearchResult; use OCP\IConfig; use OCP\IGroup; @@ -34,37 +19,39 @@ use OCP\IUserManager; use OCP\IUserSession; use OCP\Share\IShare; use OCP\UserStatus\IManager as IUserStatusManager; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class UserPluginTest extends TestCase { - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IConfig|MockObject */ protected $config; - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUserManager|MockObject */ protected $userManager; - /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IGroupManager|MockObject */ protected $groupManager; - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUserSession|MockObject */ protected $session; - /** @var IUserStatusManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var KnownUserService|MockObject */ + protected $knownUserService; + + /** @var IUserStatusManager|MockObject */ protected $userStatusManager; - /** @var UserPlugin */ + /** @var UserPlugin */ protected $plugin; - /** @var ISearchResult */ + /** @var ISearchResult */ protected $searchResult; - /** @var int */ - protected $limit = 2; + protected int $limit = 2; - /** @var int */ - protected $offset = 0; + protected int $offset = 0; - /** @var IUser|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUser|MockObject */ protected $user; protected function setUp(): void { @@ -78,6 +65,8 @@ class UserPluginTest extends TestCase { $this->session = $this->createMock(IUserSession::class); + $this->knownUserService = $this->createMock(KnownUserService::class); + $this->userStatusManager = $this->createMock(IUserStatusManager::class); $this->searchResult = new SearchResult(); @@ -93,23 +82,17 @@ class UserPluginTest extends TestCase { $this->userManager, $this->groupManager, $this->session, + $this->knownUserService, $this->userStatusManager ); } - public function mockConfig($shareWithGroupOnly, $shareeEnumeration, $shareeEnumerationLimitToGroup) { + public function mockConfig($mockedSettings) { $this->config->expects($this->any()) ->method('getAppValue') ->willReturnCallback( - function ($appName, $key, $default) use ($shareWithGroupOnly, $shareeEnumeration, $shareeEnumerationLimitToGroup) { - if ($appName === 'core' && $key === 'shareapi_only_share_with_group_members') { - return $shareWithGroupOnly ? 'yes' : 'no'; - } elseif ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') { - return $shareeEnumeration ? 'yes' : 'no'; - } elseif ($appName === 'core' && $key === 'shareapi_restrict_user_enumeration_to_group') { - return $shareeEnumerationLimitToGroup ? 'yes' : 'no'; - } - return $default; + function ($appName, $key, $default) use ($mockedSettings) { + return $mockedSettings[$appName][$key] ?? $default; } ); } @@ -142,7 +125,7 @@ class UserPluginTest extends TestCase { return $group; } - public function dataGetUsers() { + public function dataGetUsers(): array { return [ ['test', false, true, [], [], [], [], true, false], ['test', false, false, [], [], [], [], true, false], @@ -262,6 +245,28 @@ class UserPluginTest extends TestCase { [ 'test', false, + true, + [], + [ + $this->getUserMock('test0', 'Test'), + $this->getUserMock('test1', 'Test One'), + $this->getUserMock('test2', 'Test Two'), + ], + [ + ['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test0'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test0'], + ], + [ + ['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'], + ['label' => 'Test Two', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test2'], + ], + false, + false, + [], + true, + ], + [ + 'test', + false, false, [], [ @@ -413,7 +418,6 @@ class UserPluginTest extends TestCase { } /** - * @dataProvider dataGetUsers * * @param string $searchTerm * @param bool $shareWithGroupOnly @@ -426,6 +430,7 @@ class UserPluginTest extends TestCase { * @param bool|IUser $singleUser * @param array $users */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetUsers')] public function testSearch( $searchTerm, $shareWithGroupOnly, @@ -436,9 +441,16 @@ class UserPluginTest extends TestCase { array $expected, $reachedEnd, $singleUser, - array $users = [] - ) { - $this->mockConfig($shareWithGroupOnly, $shareeEnumeration, false); + array $users = [], + $shareeEnumerationPhone = false, + ): void { + $this->mockConfig(['core' => [ + 'shareapi_only_share_with_group_members' => $shareWithGroupOnly ? 'yes' : 'no', + 'shareapi_allow_share_dialog_user_enumeration' => $shareeEnumeration? 'yes' : 'no', + 'shareapi_restrict_user_enumeration_to_group' => false ? 'yes' : 'no', + 'shareapi_restrict_user_enumeration_to_phone' => $shareeEnumerationPhone ? 'yes' : 'no', + ]]); + $this->instantiatePlugin(); $this->session->expects($this->any()) @@ -446,10 +458,24 @@ class UserPluginTest extends TestCase { ->willReturn($this->user); if (!$shareWithGroupOnly) { - $this->userManager->expects($this->once()) - ->method('searchDisplayName') - ->with($searchTerm, $this->limit, $this->offset) - ->willReturn($userResponse); + if ($shareeEnumerationPhone) { + $this->userManager->expects($this->once()) + ->method('searchKnownUsersByDisplayName') + ->with($this->user->getUID(), $searchTerm, $this->limit, $this->offset) + ->willReturn($userResponse); + + $this->knownUserService->method('isKnownToUser') + ->willReturnMap([ + [$this->user->getUID(), 'test0', true], + [$this->user->getUID(), 'test1', true], + [$this->user->getUID(), 'test2', true], + ]); + } else { + $this->userManager->expects($this->once()) + ->method('searchDisplayName') + ->with($searchTerm, $this->limit, $this->offset) + ->willReturn($userResponse); + } } else { $this->groupManager->method('getUserGroupIds') ->with($this->user) @@ -483,7 +509,7 @@ class UserPluginTest extends TestCase { $this->assertSame($reachedEnd, $moreResults); } - public function takeOutCurrentUserProvider() { + public static function takeOutCurrentUserProvider(): array { $inputUsers = [ 'alice' => 'Alice', 'bob' => 'Bob', @@ -509,12 +535,12 @@ class UserPluginTest extends TestCase { } /** - * @dataProvider takeOutCurrentUserProvider * @param array $users * @param array $expectedUIDs * @param $currentUserId */ - public function testTakeOutCurrentUser(array $users, array $expectedUIDs, $currentUserId) { + #[\PHPUnit\Framework\Attributes\DataProvider('takeOutCurrentUserProvider')] + public function testTakeOutCurrentUser(array $users, array $expectedUIDs, $currentUserId): void { $this->instantiatePlugin(); $this->session->expects($this->once()) @@ -530,7 +556,7 @@ class UserPluginTest extends TestCase { $this->assertSame($expectedUIDs, array_keys($users)); } - public function dataSearchEnumeration() { + public static function dataSearchEnumeration(): array { return [ [ 'test', @@ -540,6 +566,83 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => ['groupB']], ], ['exact' => [], 'wide' => ['test1']], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], + ], + [ + 'test', + ['groupA'], + [ + ['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']], + ['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']], + ], + ['exact' => [], 'wide' => []], + ['core' => ['shareapi_allow_share_dialog_user_enumeration' => 'no']], + ], + [ + 'test1', + ['groupA'], + [ + ['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']], + ['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']], + ], + ['exact' => ['test1'], 'wide' => []], + ['core' => ['shareapi_allow_share_dialog_user_enumeration' => 'no']], + ], + [ + 'test1', + ['groupA'], + [ + ['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']], + ['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']], + ], + ['exact' => [], 'wide' => []], + [ + 'core' => [ + 'shareapi_allow_share_dialog_user_enumeration' => 'no', + 'shareapi_restrict_user_enumeration_full_match_userid' => 'no', + ], + ] + ], + [ + 'Test user 1', + ['groupA'], + [ + ['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']], + ['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']], + ], + ['exact' => ['test1'], 'wide' => []], + [ + 'core' => [ + 'shareapi_allow_share_dialog_user_enumeration' => 'no', + 'shareapi_restrict_user_enumeration_full_match_userid' => 'no', + ], + ] + ], + [ + 'Test user 1', + ['groupA'], + [ + ['uid' => 'test1', 'displayName' => 'Test user 1 (Second displayName for user 1)', 'groups' => ['groupA']], + ['uid' => 'test2', 'displayName' => 'Test user 2 (Second displayName for user 2)', 'groups' => ['groupA']], + ], + ['exact' => [], 'wide' => []], + ['core' => ['shareapi_allow_share_dialog_user_enumeration' => 'no'], + ] + ], + [ + 'Test user 1', + ['groupA'], + [ + ['uid' => 'test1', 'displayName' => 'Test user 1 (Second displayName for user 1)', 'groups' => ['groupA']], + ['uid' => 'test2', 'displayName' => 'Test user 2 (Second displayName for user 2)', 'groups' => ['groupA']], + ], + ['exact' => ['test1'], 'wide' => []], + [ + 'core' => [ + 'shareapi_allow_share_dialog_user_enumeration' => 'no', + 'shareapi_restrict_user_enumeration_full_match_ignore_second_dn' => 'yes', + ], + ] ], [ 'test1', @@ -549,6 +652,7 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => ['groupB']], ], ['exact' => ['test1'], 'wide' => []], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], [ 'test', @@ -558,6 +662,7 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => ['groupB', 'groupA']], ], ['exact' => [], 'wide' => ['test1', 'test2']], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], [ 'test', @@ -567,6 +672,7 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => ['groupB', 'groupA']], ], ['exact' => [], 'wide' => ['test1', 'test2']], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], [ 'test', @@ -576,6 +682,7 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => ['groupB', 'groupA']], ], ['exact' => [], 'wide' => ['test1', 'test2']], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], [ 'test', @@ -585,6 +692,7 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => ['groupB', 'groupA']], ], ['exact' => [], 'wide' => []], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], [ 'test', @@ -594,6 +702,7 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => []], ], ['exact' => [], 'wide' => []], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], [ 'test', @@ -603,40 +712,82 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => []], ], ['exact' => [], 'wide' => []], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], ]; } - /** - * @dataProvider dataSearchEnumeration - */ - public function testSearchEnumerationLimit($search, $userGroups, $matchingUsers, $result) { - $this->mockConfig(false, true, true); + #[\PHPUnit\Framework\Attributes\DataProvider('dataSearchEnumeration')] + public function testSearchEnumerationLimit($search, $userGroups, $matchingUsers, $result, $mockedSettings): void { + $this->mockConfig($mockedSettings); - $userResults = array_map(function ($user) { - return $this->getUserMock($user['uid'], $user['uid']); - }, $matchingUsers); + $userResults = []; + foreach ($matchingUsers as $user) { + $userResults[$user['uid']] = $user['uid']; + } - $mappedResultExact = array_map(function ($user) { - return ['label' => $user, 'value' => ['shareType' => 0, 'shareWith' => $user], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => $user]; + $usersById = []; + foreach ($matchingUsers as $user) { + $usersById[$user['uid']] = $user; + } + + $mappedResultExact = array_map(function ($user) use ($usersById, $search) { + return [ + 'label' => $search === $user ? $user : $usersById[$user]['displayName'], + 'value' => ['shareType' => 0, 'shareWith' => $user], + 'icon' => 'icon-user', + 'subline' => null, + 'status' => [], + 'shareWithDisplayNameUnique' => $user, + ]; }, $result['exact']); $mappedResultWide = array_map(function ($user) { - return ['label' => $user, 'value' => ['shareType' => 0, 'shareWith' => $user], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => $user]; + return [ + 'label' => $user, + 'value' => ['shareType' => 0, 'shareWith' => $user], + 'icon' => 'icon-user', + 'subline' => null, + 'status' => [], + 'shareWithDisplayNameUnique' => $user, + ]; }, $result['wide']); - $this->userManager->expects($this->once()) + $this->userManager + ->method('get') + ->willReturnCallback(function ($userId) use ($userResults) { + if (isset($userResults[$userId])) { + return $this->getUserMock($userId, $userId); + } + return null; + }); + $this->userManager ->method('searchDisplayName') + ->willReturnCallback(function ($search) use ($matchingUsers) { + $users = array_filter( + $matchingUsers, + fn ($user) => str_contains(strtolower($user['displayName']), strtolower($search)) + ); + return array_map( + fn ($user) => $this->getUserMock($user['uid'], $user['displayName']), + $users); + }); + + $this->groupManager->method('displayNamesInGroup') ->willReturn($userResults); + + $this->session->expects($this->any()) ->method('getUser') ->willReturn($this->getUserMock('test', 'foo')); - // current user - $this->groupManager->expects($this->at(0)) - ->method('getUserGroupIds') - ->willReturn($userGroups); $this->groupManager->expects($this->any()) ->method('getUserGroupIds') - ->willReturnCallback(function ($user) use ($matchingUsers) { + ->willReturnCallback(function ($user) use ($matchingUsers, $userGroups) { + static $firstCall = true; + if ($firstCall) { + $firstCall = false; + // current user + return $userGroups; + } $neededObject = array_filter( $matchingUsers, function ($e) use ($user) { |