From 4c13918bd8b12ac4bd341c846a50accc1bf9704d Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Mon, 8 Dec 2014 22:38:54 +0100 Subject: [PATCH 1/2] Expose backend type via REST API This change will expose the user backend via the REST API which is a pre-requisite for https://github.com/owncloud/core/issues/12620. For example: ````json [{"name":"9707A09E-CA9A-4ABE-A66A-3F632F16C409","displayname":"Document Conversion User Account","groups":[],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/9707A09E-CA9A-4ABE-A66A-3F632F16C409","lastLogin":0,"backend":"OCA\\user_ldap\\USER_LDAP"},{"name":"ED86733E-745C-4E4D-90CB-278A9737DB3C","displayname":"Hacker","groups":[],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/ED86733E-745C-4E4D-90CB-278A9737DB3C","lastLogin":0,"backend":"OCA\\user_ldap\\USER_LDAP"},{"name":"71CDF45B-E125-450D-983C-D9192F36EC88","displayname":"admin","groups":[],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/71CDF45B-E125-450D-983C-D9192F36EC88","lastLogin":0,"backend":"OCA\\user_ldap\\USER_LDAP"},{"name":"admin","displayname":"admin","groups":["admin"],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/admin","lastLogin":"1418057287","backend":"OC_User_Database"},{"name":"test","displayname":"test","groups":[],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/test","lastLogin":0,"backend":"OC_User_Database"}] ``` --- lib/private/user/user.php | 9 ++ lib/public/iuser.php | 7 ++ settings/controller/userscontroller.php | 50 ++++---- settings/js/users/users.js | 53 ++++---- tests/lib/user/user.php | 7 ++ .../controller/userscontrollertest.php | 115 ++++++++++++------ 6 files changed, 152 insertions(+), 89 deletions(-) diff --git a/lib/private/user/user.php b/lib/private/user/user.php index ad85337f62..05374c52b9 100644 --- a/lib/private/user/user.php +++ b/lib/private/user/user.php @@ -217,6 +217,15 @@ class User implements IUser { return $this->home; } + /** + * Get the name of the backend class the user is connected with + * + * @return string + */ + public function getBackendClassName() { + return get_class($this->backend); + } + /** * check if the backend allows the user to change his avatar on Personal page * diff --git a/lib/public/iuser.php b/lib/public/iuser.php index c15edcd14d..b288c61df5 100644 --- a/lib/public/iuser.php +++ b/lib/public/iuser.php @@ -68,6 +68,13 @@ interface IUser { */ public function getHome(); + /** + * Get the name of the backend class the user is connected with + * + * @return string + */ + public function getBackendClassName(); + /** * check if the backend allows the user to change his avatar on Personal page * diff --git a/settings/controller/userscontroller.php b/settings/controller/userscontroller.php index 5bd4b55510..589b0a888c 100644 --- a/settings/controller/userscontroller.php +++ b/settings/controller/userscontroller.php @@ -18,6 +18,7 @@ use OCP\IConfig; use OCP\IGroupManager; use OCP\IL10N; use OCP\IRequest; +use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; @@ -65,9 +66,27 @@ class UsersController extends Controller { $this->l10n = $l10n; } + /** + * @param IUser $user + * @param array $userGroups + * @return array + */ + private function formatUserForIndex(IUser $user, array $userGroups = null) { + return array( + 'name' => $user->getUID(), + 'displayname' => $user->getDisplayName(), + 'groups' => (empty($userGroups)) ? $this->groupManager->getUserGroupIds($user) : $userGroups, + 'subadmin' => \OC_SubAdmin::getSubAdminsGroups($user->getUID()), + 'quota' => $this->config->getUserValue($user->getUID(), 'files', 'quota', 'default'), + 'storageLocation' => $user->getHome(), + 'lastLogin' => $user->getLastLogin(), + 'backend' => $user->getBackendClassName() + ); + } + /** * @NoAdminRequired - * @NoCSRFRequired + * * @param int $offset * @param int $limit * @param string $gid @@ -91,16 +110,7 @@ class UsersController extends Controller { } foreach ($batch as $uid => $displayname) { - $user = $this->userManager->get($uid); - $users[] = array( - 'name' => $uid, - 'displayname' => $displayname, - 'groups' => $this->groupManager->getUserGroupIds($user), - 'subadmin' => \OC_SubAdmin::getSubAdminsGroups($uid), - 'quota' => $this->config->getUserValue($uid, 'files', 'quota', 'default'), - 'storageLocation' => $user->getHome(), - 'lastLogin' => $user->getLastLogin(), - ); + $users[] = $this->formatUserForIndex($this->userManager->get($uid)); } } else { $groups = \OC_SubAdmin::getSubAdminsGroups($this->userSession->getUser()->getUID()); @@ -115,20 +125,13 @@ class UsersController extends Controller { $user = $this->userManager->get($uid); // Only add the groups, this user is a subadmin of - $userGroups = array_intersect($this->groupManager->getUserGroupIds($user), \OC_SubAdmin::getSubAdminsGroups($this->userSession->getUser()->getUID())); - $users[] = array( - 'name' => $uid, - 'displayname' => $user->getDisplayName(), - 'groups' => $userGroups, - 'quota' => $this->config->getUserValue($uid, 'files', 'quota', 'default'), - 'storageLocation' => $user->getHome(), - 'lastLogin' => $user->getLastLogin(), - ); + $userGroups = array_intersect($this->groupManager->getUserGroupIds($user), + \OC_SubAdmin::getSubAdminsGroups($this->userSession->getUser()->getUID())); + $users[] = $this->formatUserForIndex($user, $userGroups); } } - // FIXME: That assignment on "data" is uneeded here - JS should be adjusted - return new DataResponse(array('data' => $users, 'status' => 'success')); + return new DataResponse($users); } /** @@ -142,7 +145,7 @@ class UsersController extends Controller { * TODO: Tidy up and write unit tests - code is mainly static method calls */ public function create($username, $password, array $groups) { - + if (!$this->isAdmin) { if (!empty($groups)) { foreach ($groups as $key => $group) { @@ -247,7 +250,6 @@ class UsersController extends Controller { ), Http::STATUS_FORBIDDEN ); - } } diff --git a/settings/js/users/users.js b/settings/js/users/users.js index 1bca6d06b3..9c48da32c5 100644 --- a/settings/js/users/users.js +++ b/settings/js/users/users.js @@ -331,35 +331,34 @@ var UserList = { function (result) { var loadedUsers = 0; var trs = []; - if (result.status === 'success') { - //The offset does not mirror the amount of users available, - //because it is backend-dependent. For correct retrieval, - //always the limit(requested amount of users) needs to be added. - $.each(result.data, function (index, user) { - if(UserList.has(user.name)) { - return true; - } - var $tr = UserList.add(user.name, user.displayname, user.groups, user.subadmin, user.quota, user.storageLocation, user.lastLogin, false); - $tr.addClass('appear transparent'); - trs.push($tr); - loadedUsers++; - }); - if (result.data.length > 0) { - UserList.doSort(); - $userList.siblings('.loading').css('visibility', 'hidden'); + //The offset does not mirror the amount of users available, + //because it is backend-dependent. For correct retrieval, + //always the limit(requested amount of users) needs to be added. + $.each(result, function (index, user) { + if(UserList.has(user.name)) { + return true; } - else { - UserList.noMoreEntries = true; - $userList.siblings('.loading').remove(); - } - UserList.offset += loadedUsers; - // animate - setTimeout(function() { - for (var i = 0; i < trs.length; i++) { - trs[i].removeClass('transparent'); - } - }, 0); + var $tr = UserList.add(user.name, user.displayname, user.groups, user.subadmin, user.quota, user.storageLocation, user.lastLogin, false); + $tr.addClass('appear transparent'); + trs.push($tr); + loadedUsers++; + }); + if (result.length > 0) { + UserList.doSort(); + $userList.siblings('.loading').css('visibility', 'hidden'); } + else { + UserList.noMoreEntries = true; + $userList.siblings('.loading').remove(); + } + UserList.offset += loadedUsers; + // animate + setTimeout(function() { + for (var i = 0; i < trs.length; i++) { + trs[i].removeClass('transparent'); + } + }, 0); + }).always(function() { UserList.updating = false; }); }, diff --git a/tests/lib/user/user.php b/tests/lib/user/user.php index 6aa7243a75..b54677f10a 100644 --- a/tests/lib/user/user.php +++ b/tests/lib/user/user.php @@ -216,6 +216,13 @@ class User extends \Test\TestCase { $this->assertEquals('/home/foo', $user->getHome()); } + public function testGetBackendClassName() { + $user = new \OC\User\User('foo', new \OC_User_Dummy()); + $this->assertEquals('OC_User_Dummy', $user->getBackendClassName()); + $user = new \OC\User\User('foo', new \OC_User_Database()); + $this->assertEquals('OC_User_Database', $user->getBackendClassName()); + } + public function testGetHomeNotSupported() { /** * @var \OC_User_Backend | \PHPUnit_Framework_MockObject_MockObject $backend diff --git a/tests/settings/controller/userscontrollertest.php b/tests/settings/controller/userscontrollertest.php index 4b0683b6da..eb48babadc 100644 --- a/tests/settings/controller/userscontrollertest.php +++ b/tests/settings/controller/userscontrollertest.php @@ -54,30 +54,68 @@ class UsersControllerTest extends \Test\TestCase { * to test for subadmins. Thus the test always assumes you have admin permissions... */ public function testIndex() { - $admin = $this->getMockBuilder('\OC\User\User') - ->disableOriginalConstructor()->getMock(); - $admin - ->method('getLastLogin') - ->will($this->returnValue(12)); - $admin - ->method('getHome') - ->will($this->returnValue('/home/admin')); $foo = $this->getMockBuilder('\OC\User\User') ->disableOriginalConstructor()->getMock(); + $foo + ->expects($this->exactly(3)) + ->method('getUID') + ->will($this->returnValue('foo')); + $foo + ->expects($this->once()) + ->method('getDisplayName') + ->will($this->returnValue('M. Foo')); $foo ->method('getLastLogin') ->will($this->returnValue(500)); $foo ->method('getHome') ->will($this->returnValue('/home/foo')); + $foo + ->expects($this->once()) + ->method('getBackendClassName') + ->will($this->returnValue('OC_User_Database')); + $admin = $this->getMockBuilder('\OC\User\User') + ->disableOriginalConstructor()->getMock(); + $admin + ->expects($this->exactly(3)) + ->method('getUID') + ->will($this->returnValue('admin')); + $admin + ->expects($this->once()) + ->method('getDisplayName') + ->will($this->returnValue('S. Admin')); + $admin + ->expects($this->once()) + ->method('getLastLogin') + ->will($this->returnValue(12)); + $admin + ->expects($this->once()) + ->method('getHome') + ->will($this->returnValue('/home/admin')); + $admin + ->expects($this->once()) + ->method('getBackendClassName') + ->will($this->returnValue('OC_User_Dummy')); $bar = $this->getMockBuilder('\OC\User\User') ->disableOriginalConstructor()->getMock(); + $bar + ->expects($this->exactly(3)) + ->method('getUID') + ->will($this->returnValue('bar')); + $bar + ->expects($this->once()) + ->method('getDisplayName') + ->will($this->returnValue('B. Ar')); $bar ->method('getLastLogin') ->will($this->returnValue(3999)); $bar ->method('getHome') ->will($this->returnValue('/home/bar')); + $bar + ->expects($this->once()) + ->method('getBackendClassName') + ->will($this->returnValue('OC_User_Dummy')); $this->container['GroupManager'] ->expects($this->once()) @@ -98,36 +136,36 @@ class UsersControllerTest extends \Test\TestCase { $expectedResponse = new DataResponse( array( - 'status' => 'success', - 'data' => array( - 0 => array( - 'name' => 'foo', - 'displayname' => 'M. Foo', - 'groups' => array('Users', 'Support'), - 'subadmin' => array(), - 'quota' => 1024, - 'storageLocation' => '/home/foo', - 'lastLogin' => 500 - ), - 1 => array( - 'name' => 'admin', - 'displayname' => 'S. Admin', - 'groups' => array('admins', 'Support'), - 'subadmin' => array(), - 'quota' => 404, - 'storageLocation' => '/home/admin', - 'lastLogin' => 12 - ), - 2 => array( - 'name' => 'bar', - 'displayname' => 'B. Ar', - 'groups' => array('External Users'), - 'subadmin' => array(), - 'quota' => 2323, - 'storageLocation' => '/home/bar', - 'lastLogin' => 3999 - ), - ) + 0 => array( + 'name' => 'foo', + 'displayname' => 'M. Foo', + 'groups' => array('Users', 'Support'), + 'subadmin' => array(), + 'quota' => 1024, + 'storageLocation' => '/home/foo', + 'lastLogin' => 500, + 'backend' => 'OC_User_Database' + ), + 1 => array( + 'name' => 'admin', + 'displayname' => 'S. Admin', + 'groups' => array('admins', 'Support'), + 'subadmin' => array(), + 'quota' => 404, + 'storageLocation' => '/home/admin', + 'lastLogin' => 12, + 'backend' => 'OC_User_Dummy' + ), + 2 => array( + 'name' => 'bar', + 'displayname' => 'B. Ar', + 'groups' => array('External Users'), + 'subadmin' => array(), + 'quota' => 2323, + 'storageLocation' => '/home/bar', + 'lastLogin' => 3999, + 'backend' => 'OC_User_Dummy' + ), ) ); $response = $this->usersController->index(0, 10, 'pattern'); @@ -341,4 +379,5 @@ class UsersControllerTest extends \Test\TestCase { $response = $this->usersController->destroy('UserToDelete'); $this->assertEquals($expectedResponse, $response); } + } From 7a290a3d6b779a624700ee3d264d3a87cb38b08b Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 9 Dec 2014 12:25:22 +0100 Subject: [PATCH 2/2] Make class compatible --- tests/lib/contacts/localadressbook.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/lib/contacts/localadressbook.php b/tests/lib/contacts/localadressbook.php index 5fa260ffc3..a34d45bf3d 100644 --- a/tests/lib/contacts/localadressbook.php +++ b/tests/lib/contacts/localadressbook.php @@ -78,6 +78,9 @@ class SimpleUserForTesting implements \OCP\IUser { public function getHome() { } + public function getBackendClassName() { + } + public function canChangeAvatar() { }