From 5dc6406b7075a6f1db3ada7a9d0f5ddc93f58b18 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 9 Dec 2014 18:36:40 +0100 Subject: Add filter for 'backend' to user REST route This adds a "backend" type filter to the index REST route which is a pre-requisite for https://github.com/owncloud/core/issues/12620 For example when calling `index.php/settings/users/users?offset=0&limit=10&gid=&pattern=&backend=OC_User_Database` only users within the backend `OC_User_Database` would be shown. (requires sending a CSRF token as well) Depends upon https://github.com/owncloud/core/pull/12711 --- lib/private/user.php | 1 + lib/private/user/manager.php | 8 ++++ lib/public/iusermanager.php | 6 +++ settings/controller/userscontroller.php | 56 ++++++++++++++++------- tests/lib/user/manager.php | 11 +++++ tests/settings/controller/userscontrollertest.php | 56 +++++++++++++++++++++++ 6 files changed, 121 insertions(+), 17 deletions(-) diff --git a/lib/private/user.php b/lib/private/user.php index f93b76a3a64..ff45e9e26a6 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -546,6 +546,7 @@ class OC_User { * @return array associative array with all display names (value) and corresponding uids (key) * * Get a list of all display names and user ids. + * @deprecated Use \OC::$server->getUserManager->searchDisplayName($search, $limit, $offset) instead. */ public static function getDisplayNames($search = '', $limit = null, $offset = null) { $displayNames = array(); diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php index 4fa3711e3b8..b283269916a 100644 --- a/lib/private/user/manager.php +++ b/lib/private/user/manager.php @@ -62,6 +62,14 @@ class Manager extends PublicEmitter implements IUserManager { }); } + /** + * Get the active backends + * @return \OC_User_Interface[] + */ + public function getBackends() { + return $this->backends; + } + /** * register a user backend * diff --git a/lib/public/iusermanager.php b/lib/public/iusermanager.php index fc0729b860b..86e495772da 100644 --- a/lib/public/iusermanager.php +++ b/lib/public/iusermanager.php @@ -31,6 +31,12 @@ interface IUserManager { */ public function registerBackend($backend); + /** + * Get the active backends + * @return \OC_User_Interface[] + */ + public function getBackends(); + /** * remove a user backend * diff --git a/settings/controller/userscontroller.php b/settings/controller/userscontroller.php index 589b0a888cb..25fa5ca2ed6 100644 --- a/settings/controller/userscontroller.php +++ b/settings/controller/userscontroller.php @@ -11,6 +11,7 @@ namespace OC\Settings\Controller; use OC\AppFramework\Http; +use OC\User\Manager; use OC\User\User; use \OCP\AppFramework\Controller; use OCP\AppFramework\Http\DataResponse; @@ -84,46 +85,67 @@ class UsersController extends Controller { ); } + /** + * @param array $userIDs + * @return IUser[] + */ + private function getUsersForUID(array $userIDs) { + $users = []; + foreach ($userIDs as $uid) { + $users[] = $this->userManager->get($uid); + } + return $users; + } + /** * @NoAdminRequired * * @param int $offset * @param int $limit - * @param string $gid - * @param string $pattern + * @param string $gid GID to filter for + * @param string $pattern Pattern to search for in the username + * @param string $backend Backend to filter for (class-name) * @return DataResponse * * TODO: Tidy up and write unit tests - code is mainly static method calls */ - public function index($offset = 0, $limit = 10, $gid = '', $pattern = '') { + public function index($offset = 0, $limit = 10, $gid = '', $pattern = '', $backend = '') { // FIXME: The JS sends the group '_everyone' instead of no GID for the "all users" group. if($gid === '_everyone') { $gid = ''; } + + // Remove backends + if(!empty($backend)) { + $activeBackends = $this->userManager->getBackends(); + $this->userManager->clearBackends(); + foreach($activeBackends as $singleActiveBackend) { + if($backend === get_class($singleActiveBackend)) { + $this->userManager->registerBackend($singleActiveBackend); + } + } + } + $users = array(); if ($this->isAdmin) { + if($gid !== '') { - $batch = $this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset); + $batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset)); } else { - // FIXME: Remove static method call - $batch = \OC_User::getDisplayNames($pattern, $limit, $offset); + $batch = $this->userManager->search(''); } - foreach ($batch as $uid => $displayname) { - $users[] = $this->formatUserForIndex($this->userManager->get($uid)); + foreach ($batch as $user) { + $users[] = $this->formatUserForIndex($user); } + } else { - $groups = \OC_SubAdmin::getSubAdminsGroups($this->userSession->getUser()->getUID()); - if($gid !== '' && in_array($gid, $groups)) { - $groups = array($gid); - } elseif($gid !== '') { - //don't you try to investigate loops you must not know about - $groups = array(); + if($gid !== '' && !in_array($gid, \OC_SubAdmin::getSubAdminsGroups($this->userSession->getUser()->getUID()))) { + $gid = ''; } - $batch = \OC_Group::usersInGroups($groups, $pattern, $limit, $offset); - foreach ($batch as $uid) { - $user = $this->userManager->get($uid); + $batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset)); + foreach ($batch as $user) { // Only add the groups, this user is a subadmin of $userGroups = array_intersect($this->groupManager->getUserGroupIds($user), \OC_SubAdmin::getSubAdminsGroups($this->userSession->getUser()->getUID())); diff --git a/tests/lib/user/manager.php b/tests/lib/user/manager.php index c825ec05775..9cb9374d89f 100644 --- a/tests/lib/user/manager.php +++ b/tests/lib/user/manager.php @@ -10,6 +10,17 @@ namespace Test\User; class Manager extends \Test\TestCase { + public function testGetBackends() { + $userDummyBackend = $this->getMock('\OC_User_Dummy'); + $manager = new \OC\User\Manager(); + $manager->registerBackend($userDummyBackend); + $this->assertEquals([$userDummyBackend], $manager->getBackends()); + $dummyDatabaseBackend = $this->getMock('\OC_User_Database'); + $manager->registerBackend($dummyDatabaseBackend); + $this->assertEquals([$userDummyBackend, $dummyDatabaseBackend], $manager->getBackends()); + } + + public function testUserExistsSingleBackendExists() { /** * @var \OC_User_Dummy | \PHPUnit_Framework_MockObject_MockObject $backend diff --git a/tests/settings/controller/userscontrollertest.php b/tests/settings/controller/userscontrollertest.php index eb48babadc8..42d91c7731a 100644 --- a/tests/settings/controller/userscontrollertest.php +++ b/tests/settings/controller/userscontrollertest.php @@ -172,6 +172,62 @@ class UsersControllerTest extends \Test\TestCase { $this->assertEquals($expectedResponse, $response); } + public function testIndexWithBackend() { + $user = $this->getMockBuilder('\OC\User\User') + ->disableOriginalConstructor()->getMock(); + $user + ->expects($this->exactly(3)) + ->method('getUID') + ->will($this->returnValue('foo')); + $user + ->expects($this->once()) + ->method('getDisplayName') + ->will($this->returnValue('M. Foo')); + $user + ->method('getLastLogin') + ->will($this->returnValue(500)); + $user + ->method('getHome') + ->will($this->returnValue('/home/foo')); + $user + ->expects($this->once()) + ->method('getBackendClassName') + ->will($this->returnValue('OC_User_Database')); + $this->container['UserManager'] + ->expects($this->once()) + ->method('getBackends') + ->will($this->returnValue([new \OC_User_Dummy(), new \OC_User_Database()])); + $this->container['UserManager'] + ->expects($this->once()) + ->method('clearBackends'); + $this->container['UserManager'] + ->expects($this->once()) + ->method('registerBackend') + ->with(new \OC_User_Dummy()); + $this->container['UserManager'] + ->expects($this->once()) + ->method('search') + ->with('') + ->will($this->returnValue([$user])); + + $expectedResponse = new DataResponse( + array( + 0 => array( + 'name' => 'foo', + 'displayname' => 'M. Foo', + 'groups' => null, + 'subadmin' => array(), + 'quota' => null, + 'storageLocation' => '/home/foo', + 'lastLogin' => 500, + 'backend' => 'OC_User_Database' + ) + ) + ); + $response = $this->usersController->index(0, 10, '','', 'OC_User_Dummy'); + $this->assertEquals($expectedResponse, $response); + } + /** * TODO: Since the function uses the static OC_Subadmin class it can't be mocked * to test for subadmins. Thus the test always assumes you have admin permissions... -- cgit v1.2.3 From 661dc789cec2504978b5c64b5a64410137054690 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 11 Dec 2014 12:29:53 +0100 Subject: Break loop --- settings/controller/userscontroller.php | 1 + 1 file changed, 1 insertion(+) diff --git a/settings/controller/userscontroller.php b/settings/controller/userscontroller.php index 25fa5ca2ed6..dbd8118375a 100644 --- a/settings/controller/userscontroller.php +++ b/settings/controller/userscontroller.php @@ -122,6 +122,7 @@ class UsersController extends Controller { foreach($activeBackends as $singleActiveBackend) { if($backend === get_class($singleActiveBackend)) { $this->userManager->registerBackend($singleActiveBackend); + break; } } } -- cgit v1.2.3 From d0716d2c7df9d150a2705a517efcde8855a51f51 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 11 Dec 2014 12:29:58 +0100 Subject: Use public interface --- lib/private/user/manager.php | 10 +++++----- lib/public/iusermanager.php | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php index b283269916a..1bc3b51c2ef 100644 --- a/lib/private/user/manager.php +++ b/lib/private/user/manager.php @@ -28,7 +28,7 @@ use OCP\IConfig; */ class Manager extends PublicEmitter implements IUserManager { /** - * @var \OC_User_Interface[] $backends + * @var \OCP\UserInterface [] $backends */ private $backends = array(); @@ -64,7 +64,7 @@ class Manager extends PublicEmitter implements IUserManager { /** * Get the active backends - * @return \OC_User_Interface[] + * @return \OCP\UserInterface[] */ public function getBackends() { return $this->backends; @@ -73,7 +73,7 @@ class Manager extends PublicEmitter implements IUserManager { /** * register a user backend * - * @param \OC_User_Interface $backend + * @param \OCP\UserInterface $backend */ public function registerBackend($backend) { $this->backends[] = $backend; @@ -82,7 +82,7 @@ class Manager extends PublicEmitter implements IUserManager { /** * remove a user backend * - * @param \OC_User_Interface $backend + * @param \OCP\UserInterface $backend */ public function removeBackend($backend) { $this->cachedUsers = array(); @@ -121,7 +121,7 @@ class Manager extends PublicEmitter implements IUserManager { * get or construct the user object * * @param string $uid - * @param \OC_User_Interface $backend + * @param \OCP\UserInterface $backend * @return \OC\User\User */ protected function getUserObject($uid, $backend) { diff --git a/lib/public/iusermanager.php b/lib/public/iusermanager.php index 86e495772da..1691aee8e7d 100644 --- a/lib/public/iusermanager.php +++ b/lib/public/iusermanager.php @@ -33,7 +33,7 @@ interface IUserManager { /** * Get the active backends - * @return \OC_User_Interface[] + * @return \OCP\UserInterface[] */ public function getBackends(); -- cgit v1.2.3 From 26b0a89874dc1a3279471b9fbf35420d63fd45dd Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 12 Dec 2014 12:39:31 +0100 Subject: Add test for user without backend --- tests/settings/controller/userscontrollertest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/settings/controller/userscontrollertest.php b/tests/settings/controller/userscontrollertest.php index 42d91c7731a..78b855fd3f1 100644 --- a/tests/settings/controller/userscontrollertest.php +++ b/tests/settings/controller/userscontrollertest.php @@ -228,6 +228,22 @@ class UsersControllerTest extends \Test\TestCase { $this->assertEquals($expectedResponse, $response); } + public function testIndexWithBackendNoUser() { + $this->container['UserManager'] + ->expects($this->once()) + ->method('getBackends') + ->will($this->returnValue([new \OC_User_Dummy(), new \OC_User_Database()])); + $this->container['UserManager'] + ->expects($this->once()) + ->method('search') + ->with('') + ->will($this->returnValue([])); + + $expectedResponse = new DataResponse([]); + $response = $this->usersController->index(0, 10, '','', 'OC_User_Dummy'); + $this->assertEquals($expectedResponse, $response); + } + /** * TODO: Since the function uses the static OC_Subadmin class it can't be mocked * to test for subadmins. Thus the test always assumes you have admin permissions... -- cgit v1.2.3 From d5b26e682cc94c62b8ad1360d4be1e74a55f22a9 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 12 Dec 2014 16:42:25 +0100 Subject: Use array key instead of value --- settings/controller/userscontroller.php | 2 +- tests/settings/controller/userscontrollertest.php | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/settings/controller/userscontroller.php b/settings/controller/userscontroller.php index dbd8118375a..579d38f7091 100644 --- a/settings/controller/userscontroller.php +++ b/settings/controller/userscontroller.php @@ -91,7 +91,7 @@ class UsersController extends Controller { */ private function getUsersForUID(array $userIDs) { $users = []; - foreach ($userIDs as $uid) { + foreach ($userIDs as $uid => $displayName) { $users[] = $this->userManager->get($uid); } return $users; diff --git a/tests/settings/controller/userscontrollertest.php b/tests/settings/controller/userscontrollertest.php index 78b855fd3f1..89ef8bcf8a6 100644 --- a/tests/settings/controller/userscontrollertest.php +++ b/tests/settings/controller/userscontrollertest.php @@ -126,9 +126,20 @@ class UsersControllerTest extends \Test\TestCase { ->method('getUserGroupIds') ->will($this->onConsecutiveCalls(array('Users', 'Support'), array('admins', 'Support'), array('External Users'))); $this->container['UserManager'] - ->expects($this->exactly(3)) + ->expects($this->at(0)) + ->method('get') + ->with('foo') + ->will($this->returnValue($foo)); + $this->container['UserManager'] + ->expects($this->at(1)) + ->method('get') + ->with('admin') + ->will($this->returnValue($admin)); + $this->container['UserManager'] + ->expects($this->at(2)) ->method('get') - ->will($this->onConsecutiveCalls($foo, $admin, $bar)); + ->with('bar') + ->will($this->returnValue($bar)); $this->container['Config'] ->expects($this->exactly(3)) ->method('getUserValue') @@ -168,7 +179,7 @@ class UsersControllerTest extends \Test\TestCase { ), ) ); - $response = $this->usersController->index(0, 10, 'pattern'); + $response = $this->usersController->index(0, 10, 'gid', 'pattern'); $this->assertEquals($expectedResponse, $response); } -- cgit v1.2.3 From 202f1215aa4752a7b5ce10d5ac6e9092a3e1531d Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 12 Dec 2014 16:43:24 +0100 Subject: Use limit and offset --- settings/controller/userscontroller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings/controller/userscontroller.php b/settings/controller/userscontroller.php index 579d38f7091..bd0c859b18c 100644 --- a/settings/controller/userscontroller.php +++ b/settings/controller/userscontroller.php @@ -133,7 +133,7 @@ class UsersController extends Controller { if($gid !== '') { $batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset)); } else { - $batch = $this->userManager->search(''); + $batch = $this->userManager->search('', $limit, $offset); } foreach ($batch as $user) { -- cgit v1.2.3 From dced436a3a435bf892d2d610caaac5895b6e16ba Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 12 Dec 2014 16:45:11 +0100 Subject: Comment code path --- settings/controller/userscontroller.php | 1 + 1 file changed, 1 insertion(+) diff --git a/settings/controller/userscontroller.php b/settings/controller/userscontroller.php index bd0c859b18c..7f2449f2af6 100644 --- a/settings/controller/userscontroller.php +++ b/settings/controller/userscontroller.php @@ -141,6 +141,7 @@ class UsersController extends Controller { } } else { + // Set the $gid parameter to an empty value if the subadmin has no rights to access a specific group if($gid !== '' && !in_array($gid, \OC_SubAdmin::getSubAdminsGroups($this->userSession->getUser()->getUID()))) { $gid = ''; } -- cgit v1.2.3 From 76a633bf52647ab9ae44c5f53bc86fa02cb7d3a8 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 12 Dec 2014 16:50:14 +0100 Subject: Make comment clear --- settings/controller/userscontroller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings/controller/userscontroller.php b/settings/controller/userscontroller.php index 7f2449f2af6..5e496fe725c 100644 --- a/settings/controller/userscontroller.php +++ b/settings/controller/userscontroller.php @@ -86,7 +86,7 @@ class UsersController extends Controller { } /** - * @param array $userIDs + * @param array $userIDs Array with schema [$uid => $displayName] * @return IUser[] */ private function getUsersForUID(array $userIDs) { -- cgit v1.2.3