From 1e1ced777275c70307d26556843938e68ca25fde Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 7 Jan 2014 23:05:37 +0100 Subject: [PATCH 1/8] Introduce user count action to user management --- lib/private/user/backend.php | 16 +++++++++------- lib/private/user/database.php | 15 +++++++++++++++ lib/private/user/manager.php | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/lib/private/user/backend.php b/lib/private/user/backend.php index 02c93d13bd..6969ce4ba3 100644 --- a/lib/private/user/backend.php +++ b/lib/private/user/backend.php @@ -31,13 +31,14 @@ define('OC_USER_BACKEND_NOT_IMPLEMENTED', -501); /** * actions that user backends can define */ -define('OC_USER_BACKEND_CREATE_USER', 0x0000001); -define('OC_USER_BACKEND_SET_PASSWORD', 0x0000010); -define('OC_USER_BACKEND_CHECK_PASSWORD', 0x0000100); -define('OC_USER_BACKEND_GET_HOME', 0x0001000); -define('OC_USER_BACKEND_GET_DISPLAYNAME', 0x0010000); -define('OC_USER_BACKEND_SET_DISPLAYNAME', 0x0100000); -define('OC_USER_BACKEND_PROVIDE_AVATAR', 0x1000000); +define('OC_USER_BACKEND_CREATE_USER', 0x00000001); +define('OC_USER_BACKEND_SET_PASSWORD', 0x00000010); +define('OC_USER_BACKEND_CHECK_PASSWORD', 0x00000100); +define('OC_USER_BACKEND_GET_HOME', 0x00001000); +define('OC_USER_BACKEND_GET_DISPLAYNAME', 0x00010000); +define('OC_USER_BACKEND_SET_DISPLAYNAME', 0x00100000); +define('OC_USER_BACKEND_PROVIDE_AVATAR', 0x01000000); +define('OC_USER_BACKEND_COUNT_USERS', 0x10000000); /** * Abstract base class for user management. Provides methods for querying backend @@ -55,6 +56,7 @@ abstract class OC_User_Backend implements OC_User_Interface { OC_USER_BACKEND_GET_DISPLAYNAME => 'getDisplayName', OC_USER_BACKEND_SET_DISPLAYNAME => 'setDisplayName', OC_USER_BACKEND_PROVIDE_AVATAR => 'canChangeAvatar', + OC_USER_BACKEND_COUNT_USERS => 'countUsers', ); /** diff --git a/lib/private/user/database.php b/lib/private/user/database.php index c99db3b27c..1a63755b98 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -253,4 +253,19 @@ class OC_User_Database extends OC_User_Backend { return true; } + /** + * counts the users in the database + * + * @return int | bool + */ + public function countUsers() { + $query = OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users`'); + $result = $query->execute(); + if (OC_DB::isError($result)) { + OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR); + return false; + } + return $result->fetchOne(); + } + } diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php index cf83a75ba2..101b388f1e 100644 --- a/lib/private/user/manager.php +++ b/lib/private/user/manager.php @@ -270,4 +270,22 @@ class Manager extends PublicEmitter { } return false; } + + /** + * returns how many users per backend exist (if supported by backend) + * + * @return array with backend class as key and count number as value + */ + public function countUsers() { + $userCountStatistics = array(); + foreach ($this->backends as $backend) { + if ($backend->implementsActions(\OC_USER_BACKEND_COUNT_USERS)) { + $backendusers = $backend->countUsers(); + if($backendusers !== false) { + $userCountStatistics[get_class($backend)] = $backendusers; + } + } + } + return $userCountStatistics; + } } From bc1235d325c5b8ff659afc6700e82e35e2912fbb Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 7 Jan 2014 23:06:37 +0100 Subject: [PATCH 2/8] Add command line tool to show numbers of users and user directories --- core/command/user/report.php | 61 ++++++++++++++++++++++++++++++++++++ core/register_command.php | 1 + 2 files changed, 62 insertions(+) create mode 100644 core/command/user/report.php diff --git a/core/command/user/report.php b/core/command/user/report.php new file mode 100644 index 0000000000..f95ba251bc --- /dev/null +++ b/core/command/user/report.php @@ -0,0 +1,61 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Core\Command\User; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Helper\TableHelper; + +class Report extends Command { + protected function configure() { + $this + ->setName('user:report') + ->setDescription('shows how many users have access'); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $table = $this->getHelperSet()->get('table'); + $table->setHeaders(array('User Report', '')); + $userCountArray = $this->countUsers(); + if(!empty($userCountArray)) { + $total = 0; + $rows = array(); + foreach($userCountArray as $classname => $users) { + $total += $users; + $rows[] = array($classname, $users); + } + + $rows[] = array(' '); + $rows[] = array('total users', $total); + } else { + $rows[] = array('No backend enabled that supports user counting', ''); + } + + $userDirectoryCount = $this->countUserDirectories(); + $rows[] = array(' '); + $rows[] = array('user directories', $userDirectoryCount); + + $table->setRows($rows); + $table->render($output); + } + + private function countUsers() { + \OC_App::loadApps(array('authentication')); + $userManager = \OC::$server->getUserManager(); + return $userManager->countUsers(); + } + + private function countUserDirectories() { + $dataview = new \OC\Files\View('/'); + $userDirectories = $dataview->getDirectoryContent('/', 'httpd/unix-directory'); + return count($userDirectories); + } +} \ No newline at end of file diff --git a/core/register_command.php b/core/register_command.php index e4f3b12436..2efa838e9e 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -15,3 +15,4 @@ $application->add(new OC\Core\Command\App\Disable()); $application->add(new OC\Core\Command\App\Enable()); $application->add(new OC\Core\Command\App\ListApps()); $application->add(new OC\Core\Command\Maintenance\Repair(new \OC\Repair())); +$application->add(new OC\Core\Command\User\Report()); From b669e1a3c13dc6fabc8929a4abc4fd13fb8a4450 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 8 Jan 2014 12:07:57 +0100 Subject: [PATCH 3/8] LDAP: implement userCount action. This required to (finally) clean up and refactor the search method, which will have a positive performance impact on paged search. --- apps/user_ldap/lib/access.php | 145 +++++++++++++++++++++++++++------- apps/user_ldap/user_ldap.php | 16 +++- apps/user_ldap/user_proxy.php | 15 ++++ 3 files changed, 148 insertions(+), 28 deletions(-) diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index ecc74b6cf5..72f9c74092 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -634,6 +634,10 @@ class Access extends LDAPUtility { return $this->search($filter, $this->connection->ldapBaseUsers, $attr, $limit, $offset); } + public function countUsers($filter, $attr = array('dn'), $limit = null, $offset = null) { + return $this->count($filter, $this->connection->ldapBaseGroups, $attr, $limit, $offset); + } + /** * @brief executes an LDAP search, optimized for Groups * @param $filter the LDAP filter for the search @@ -647,61 +651,68 @@ class Access extends LDAPUtility { } /** - * @brief executes an LDAP search + * @brief prepares and executes an LDAP search operation * @param $filter the LDAP filter for the search * @param $base an array containing the LDAP subtree(s) that shall be searched * @param $attr optional, array, one or more attributes that shall be * retrieved. Results will according to the order in the array. - * @returns array with the search result - * - * Executes an LDAP search + * @param $limit optional, maximum results to be counted + * @param $offset optional, a starting point + * @returns array with the search result as first value and pagedSearchOK as + * second | false if not successful */ - private function search($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) { + private function executeSearch($filter, $base, &$attr = null, $limit = null, $offset = null) { if(!is_null($attr) && !is_array($attr)) { $attr = array(mb_strtolower($attr, 'UTF-8')); } // See if we have a resource, in case not cancel with message - $link_resource = $this->connection->getConnectionResource(); - if(!$this->ldap->isResource($link_resource)) { + $cr = $this->connection->getConnectionResource(); + if(!$this->ldap->isResource($cr)) { // Seems like we didn't find any resource. // Return an empty array just like before. \OCP\Util::writeLog('user_ldap', 'Could not search, because resource is missing.', \OCP\Util::DEBUG); - return array(); + return false; } //check wether paged search should be attempted $pagedSearchOK = $this->initPagedSearch($filter, $base, $attr, $limit, $offset); - $linkResources = array_pad(array(), count($base), $link_resource); + $linkResources = array_pad(array(), count($base), $cr); $sr = $this->ldap->search($linkResources, $base, $filter, $attr); - $error = $this->ldap->errno($link_resource); + $error = $this->ldap->errno($cr); if(!is_array($sr) || $error !== 0) { \OCP\Util::writeLog('user_ldap', - 'Error when searching: '.$this->ldap->error($link_resource). - ' code '.$this->ldap->errno($link_resource), + 'Error when searching: '.$this->ldap->error($cr). + ' code '.$this->ldap->errno($cr), \OCP\Util::ERROR); \OCP\Util::writeLog('user_ldap', 'Attempt for Paging? '.print_r($pagedSearchOK, true), \OCP\Util::ERROR); - return array(); + return false; } - // Do the server-side sorting - foreach(array_reverse($attr) as $sortAttr){ - foreach($sr as $searchResource) { - $this->ldap->sort($link_resource, $searchResource, $sortAttr); - } - } + return array($sr, $pagedSearchOK); + } - $findings = array(); - foreach($sr as $key => $res) { - $findings = array_merge($findings, $this->ldap->getEntries($link_resource, $res )); - } + /** + * @brief processes an LDAP paged search operation + * @param $sr the array containing the LDAP search resources + * @param $filter the LDAP filter for the search + * @param $base an array containing the LDAP subtree(s) that shall be searched + * @param $iFoundItems number of results in the search operation + * @param $limit maximum results to be counted + * @param $offset a starting point + * @param $pagedSearchOK whether a paged search has been executed + * @param $skipHandling required for paged search when cookies to + * prior results need to be gained + * @returns array with the search result as first value and pagedSearchOK as + * second | false if not successful + */ + private function processPagedSearchStatus($sr, $filter, $base, $iFoundItems, $limit, $offset, $pagedSearchOK, $skipHandling) { if($pagedSearchOK) { - \OCP\Util::writeLog('user_ldap', 'Paged search successful', \OCP\Util::INFO); + $cr = $this->connection->getConnectionResource(); foreach($sr as $key => $res) { $cookie = null; - if($this->ldap->controlPagedResultResponse($link_resource, $res, $cookie)) { - \OCP\Util::writeLog('user_ldap', 'Set paged search cookie', \OCP\Util::INFO); + if($this->ldap->controlPagedResultResponse($cr, $res, $cookie)) { $this->setPagedResultCookie($base[$key], $filter, $limit, $offset, $cookie); } } @@ -713,7 +724,7 @@ class Access extends LDAPUtility { // if count is bigger, then the server does not support // paged search. Instead, he did a normal search. We set a // flag here, so the callee knows how to deal with it. - if($findings['count'] <= $limit) { + if($iFoundItems <= $limit) { $this->pagedSearchedSuccessful = true; } } else { @@ -721,6 +732,86 @@ class Access extends LDAPUtility { \OCP\Util::writeLog('user_ldap', 'Paged search failed :(', \OCP\Util::INFO); } } + } + + /** + * @brief executes an LDAP search, but counts the results only + * @param $filter the LDAP filter for the search + * @param $base an array containing the LDAP subtree(s) that shall be searched + * @param $attr optional, array, one or more attributes that shall be + * retrieved. Results will according to the order in the array. + * @param $limit optional, maximum results to be counted + * @param $offset optional, a starting point + * @param $skipHandling indicates whether the pages search operation is + * completed + * @returns int | false if the search could not be initialized + * + */ + private function count($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) { + \OCP\Util::writeLog('user_ldap', 'Count filter: '.print_r($filter, true), \OCP\Util::DEBUG); + $search = $this->executeSearch($filter, $base, $attr, $limit, $offset); + if($search === false) { + return false; + } + list($sr, $pagedSearchOK) = $search; + $cr = $this->connection->getConnectionResource(); + $counter = 0; + foreach($sr as $key => $res) { + $count = $this->ldap->countEntries($cr, $res); + if($count !== false) { + $counter += $count; + } + } + + $this->processPagedSearchStatus($sr, $filter, $base, $counter, $limit, + $offset, $pagedSearchOK, $skipHandling); + + return $counter; + } + + /** + * @brief executes an LDAP search + * @param $filter the LDAP filter for the search + * @param $base an array containing the LDAP subtree(s) that shall be searched + * @param $attr optional, array, one or more attributes that shall be + * retrieved. Results will according to the order in the array. + * @returns array with the search result + * + * Executes an LDAP search + */ + private function search($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) { + $search = $this->executeSearch($filter, $base, $attr, $limit, $offset); + if($search === false) { + return array(); + } + list($sr, $pagedSearchOK) = $search; + $cr = $this->connection->getConnectionResource(); + + if($skipHandling) { + //i.e. result do not need to be fetched, we just need the cookie + //thus pass 1 or any other value as $iFoundItems because it is not + //used + $this->processPagedSearchStatus($sr, $filter, $base, 1, $limit, + $offset, $pagedSearchOK, + $skipHandling); + return; + } + + // Do the server-side sorting + foreach(array_reverse($attr) as $sortAttr){ + foreach($sr as $searchResource) { + $this->ldap->sort($cr, $searchResource, $sortAttr); + } + } + + $findings = array(); + foreach($sr as $key => $res) { + $findings = array_merge($findings, $this->ldap->getEntries($cr , $res )); + } + + $this->processPagedSearchStatus($sr, $filter, $base, $findings['count'], + $limit, $offset, $pagedSearchOK, + $skipHandling); // if we're here, probably no connection resource is returned. // to make ownCloud behave nicely, we simply give back an empty array. diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 527a5c10b8..542d6b00c5 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -363,7 +363,8 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { return (bool)((OC_USER_BACKEND_CHECK_PASSWORD | OC_USER_BACKEND_GET_HOME | OC_USER_BACKEND_GET_DISPLAYNAME - | OC_USER_BACKEND_PROVIDE_AVATAR) + | OC_USER_BACKEND_PROVIDE_AVATAR + | OC_USER_BACKEND_COUNT_USERS) & $actions); } @@ -373,4 +374,17 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { public function hasUserListings() { return true; } + + /** + * counts the users in LDAP + * + * @return int | bool + */ + public function countUsers() { + $o = $this->access->connection->ldapLoginFilter; + $filter = \OCP\Util::mb_str_replace( + '%uid', '*', $this->access->connection->ldapLoginFilter, 'UTF-8'); + $entries = $this->access->countUsers($filter); + return $entries; + } } diff --git a/apps/user_ldap/user_proxy.php b/apps/user_ldap/user_proxy.php index b073b143e7..5ad127197f 100644 --- a/apps/user_ldap/user_proxy.php +++ b/apps/user_ldap/user_proxy.php @@ -210,4 +210,19 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface { return $this->refBackend->hasUserListings(); } + /** + * @brief Count the number of users + * @returns int | bool + */ + public function countUsers() { + $users = false; + foreach($this->backends as $backend) { + $backendUsers = $backend->countUsers(); + if ($backendUsers !== false) { + $users += $backendUsers; + } + } + return $users; + } + } From 53498bc8761d564ee44f1d59e8b85873b5d654da Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 8 Jan 2014 12:20:56 +0100 Subject: [PATCH 4/8] remove unnecessary line --- apps/user_ldap/user_ldap.php | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 542d6b00c5..a19af86086 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -381,7 +381,6 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { * @return int | bool */ public function countUsers() { - $o = $this->access->connection->ldapLoginFilter; $filter = \OCP\Util::mb_str_replace( '%uid', '*', $this->access->connection->ldapLoginFilter, 'UTF-8'); $entries = $this->access->countUsers($filter); From 677d83d45fed6e799b9d90927f365d47ba08f93b Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 8 Jan 2014 12:24:29 +0100 Subject: [PATCH 5/8] LDAP: add tests for countUsers --- apps/user_ldap/tests/user_ldap.php | 54 ++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/apps/user_ldap/tests/user_ldap.php b/apps/user_ldap/tests/user_ldap.php index 6b9b8b3e18..9193a005ae 100644 --- a/apps/user_ldap/tests/user_ldap.php +++ b/apps/user_ldap/tests/user_ldap.php @@ -408,4 +408,58 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase { //no test for getDisplayNames, because it just invokes getUsers and //getDisplayName + + public function testCountUsers() { + $access = $this->getAccessMock(); + + $access->connection->expects($this->once()) + ->method('__get') + ->will($this->returnCallback(function($name) { + if($name === 'ldapLoginFilter') { + return 'uid=%uid'; + } + return null; + })); + + $access->expects($this->once()) + ->method('countUsers') + ->will($this->returnCallback(function($filter, $a, $b, $c) { + if($filter !== 'uid=*') { + return false; + } + return 5; + })); + + $backend = new UserLDAP($access); + + $result = $backend->countUsers(); + $this->assertEquals(5, $result); + } + + public function testCountUsersFailing() { + $access = $this->getAccessMock(); + + $access->connection->expects($this->once()) + ->method('__get') + ->will($this->returnCallback(function($name) { + if($name === 'ldapLoginFilter') { + return 'invalidFilter'; + } + return null; + })); + + $access->expects($this->once()) + ->method('countUsers') + ->will($this->returnCallback(function($filter, $a, $b, $c) { + if($filter !== 'uid=*') { + return false; + } + return 5; + })); + + $backend = new UserLDAP($access); + + $result = $backend->countUsers(); + $this->assertFalse($result); + } } \ No newline at end of file From cb6a3e2617c6549d4a305f3612bef8aa5840306e Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 8 Jan 2014 13:24:28 +0100 Subject: [PATCH 6/8] if backends have the same class name, sum their users up instead of overwriting --- lib/private/user/manager.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php index 101b388f1e..90970ef996 100644 --- a/lib/private/user/manager.php +++ b/lib/private/user/manager.php @@ -282,7 +282,11 @@ class Manager extends PublicEmitter { if ($backend->implementsActions(\OC_USER_BACKEND_COUNT_USERS)) { $backendusers = $backend->countUsers(); if($backendusers !== false) { - $userCountStatistics[get_class($backend)] = $backendusers; + if(isset($userCountStatistics[get_class($backend)])) { + $userCountStatistics[get_class($backend)] += $backendusers; + } else { + $userCountStatistics[get_class($backend)] = $backendusers; + } } } } From d7cb5ab080e2b3abe804ffe974ebb65398914943 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 8 Jan 2014 13:26:48 +0100 Subject: [PATCH 7/8] add tests for user counting --- lib/private/user/dummy.php | 9 +++++ tests/lib/user/manager.php | 72 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/lib/private/user/dummy.php b/lib/private/user/dummy.php index 52be7edfa7..fc15a630cf 100644 --- a/lib/private/user/dummy.php +++ b/lib/private/user/dummy.php @@ -123,4 +123,13 @@ class OC_User_Dummy extends OC_User_Backend { public function hasUserListings() { return true; } + + /** + * counts the users in the database + * + * @return int | bool + */ + public function countUsers() { + return 0; + } } diff --git a/tests/lib/user/manager.php b/tests/lib/user/manager.php index 00901dd411..ad1ac9e12f 100644 --- a/tests/lib/user/manager.php +++ b/tests/lib/user/manager.php @@ -346,4 +346,76 @@ class Manager extends \PHPUnit_Framework_TestCase { $manager->createUser('foo', 'bar'); } + + public function testCountUsersNoBackend() { + $manager = new \OC\User\Manager(); + + $result = $manager->countUsers(); + $this->assertTrue(is_array($result)); + $this->assertTrue(empty($result)); + } + + public function testCountUsersOneBackend() { + /** + * @var \OC_User_Dummy | \PHPUnit_Framework_MockObject_MockObject $backend + */ + $backend = $this->getMock('\OC_User_Dummy'); + $backend->expects($this->once()) + ->method('countUsers') + ->will($this->returnValue(7)); + + $backend->expects($this->once()) + ->method('implementsActions') + ->with(\OC_USER_BACKEND_COUNT_USERS) + ->will($this->returnValue(true)); + + $manager = new \OC\User\Manager(); + $manager->registerBackend($backend); + + $result = $manager->countUsers(); + $keys = array_keys($result); + $this->assertTrue(strpos($keys[0], 'Mock_OC_User_Dummy') !== false); + + $users = array_shift($result); + $this->assertEquals(7, $users); + } + + public function testCountUsersTwoBackends() { + /** + * @var \OC_User_Dummy | \PHPUnit_Framework_MockObject_MockObject $backend + */ + $backend1 = $this->getMock('\OC_User_Dummy'); + $backend1->expects($this->once()) + ->method('countUsers') + ->will($this->returnValue(7)); + + $backend1->expects($this->once()) + ->method('implementsActions') + ->with(\OC_USER_BACKEND_COUNT_USERS) + ->will($this->returnValue(true)); + + $backend2 = $this->getMock('\OC_User_Dummy'); + $backend2->expects($this->once()) + ->method('countUsers') + ->will($this->returnValue(16)); + + $backend2->expects($this->once()) + ->method('implementsActions') + ->with(\OC_USER_BACKEND_COUNT_USERS) + ->will($this->returnValue(true)); + + $manager = new \OC\User\Manager(); + $manager->registerBackend($backend1); + $manager->registerBackend($backend2); + + $result = $manager->countUsers(); + //because the backends have the same class name, only one value expected + $this->assertEquals(1, count($result)); + $keys = array_keys($result); + $this->assertTrue(strpos($keys[0], 'Mock_OC_User_Dummy') !== false); + + $users = array_shift($result); + //users from backends shall be summed up + $this->assertEquals(7+16, $users); + } } From 4585b4ea3f1fd21aabc167102e74a382dfa0cbd8 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 8 Jan 2014 19:41:10 +0100 Subject: [PATCH 8/8] Infowarning about 32bit --- lib/private/user/backend.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/private/user/backend.php b/lib/private/user/backend.php index 6969ce4ba3..f4e5618e04 100644 --- a/lib/private/user/backend.php +++ b/lib/private/user/backend.php @@ -39,6 +39,7 @@ define('OC_USER_BACKEND_GET_DISPLAYNAME', 0x00010000); define('OC_USER_BACKEND_SET_DISPLAYNAME', 0x00100000); define('OC_USER_BACKEND_PROVIDE_AVATAR', 0x01000000); define('OC_USER_BACKEND_COUNT_USERS', 0x10000000); +//more actions cannot be defined without breaking 32bit platforms! /** * Abstract base class for user management. Provides methods for querying backend