Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorblizzz <blizzz@owncloud.com>2014-01-08 22:41:39 +0400
committerblizzz <blizzz@owncloud.com>2014-01-08 22:41:39 +0400
commitd8b8abb429d3d66598a16d25cf55f7dc19e3f996 (patch)
tree085c9d1173d570f02fbf1bc88fb6ec27a674c42a /apps
parent0e7283ef39d7fe2e80585c190d8e1dc2cb511c96 (diff)
parent4585b4ea3f1fd21aabc167102e74a382dfa0cbd8 (diff)
Merge pull request #6681 from owncloud/userreport
add command line option to get user number statistics
Diffstat (limited to 'apps')
-rw-r--r--apps/user_ldap/lib/access.php145
-rw-r--r--apps/user_ldap/tests/user_ldap.php54
-rw-r--r--apps/user_ldap/user_ldap.php15
-rw-r--r--apps/user_ldap/user_proxy.php15
4 files changed, 201 insertions, 28 deletions
diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index ecc74b6cf54..72f9c740921 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/tests/user_ldap.php b/apps/user_ldap/tests/user_ldap.php
index 6b9b8b3e185..9193a005ae5 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
diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index 527a5c10b85..a19af86086c 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,16 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface {
public function hasUserListings() {
return true;
}
+
+ /**
+ * counts the users in LDAP
+ *
+ * @return int | bool
+ */
+ public function countUsers() {
+ $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 b073b143e74..5ad127197f3 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;
+ }
+
}