diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index 4f2424d953..820d2c4636 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -276,6 +276,83 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { return $groupUsers; } + /** + * @brief returns the number of users in a group, who match the search term + * @param string the internal group name + * @param string optional, a search string + * @returns int | bool + */ + public function countUsersInGroup($gid, $search = '') { + $cachekey = 'countUsersInGroup-'.$gid.'-'.$search; + if(!$this->enabled || !$this->groupExists($gid)) { + return false; + } + $groupUsers = $this->access->connection->getFromCache($cachekey); + if(!is_null($groupUsers)) { + return $groupUsers; + } + + $groupDN = $this->access->groupname2dn($gid); + if(!$groupDN) { + // group couldn't be found, return empty resultset + $this->access->connection->writeToCache($cachekey, false); + return false; + } + + $members = array_keys($this->_groupMembers($groupDN)); + if(!$members) { + //in case users could not be retrieved, return empty resultset + $this->access->connection->writeToCache($cachekey, false); + return false; + } + + if(empty($search)) { + $groupUsers = count($members); + $this->access->connection->writeToCache($cachekey, $groupUsers); + return $groupUsers; + } + $isMemberUid = + (strtolower($this->access->connection->ldapGroupMemberAssocAttr) + === 'memberuid'); + + //we need to apply the search filter + //alternatives that need to be checked: + //a) get all users by search filter and array_intersect them + //b) a, but only when less than 1k 10k ?k users like it is + //c) put all DNs|uids in a LDAP filter, combine with the search string + // and let it count. + //For now this is not important, because the only use of this method + //does not supply a search string + foreach($members as $member) { + if($isMemberUid) { + //we got uids, need to get their DNs to 'tranlsate' them to usernames + $filter = $this->access->combineFilterWithAnd(array( + \OCP\Util::mb_str_replace('%uid', $member, + $this->access->connection->ldapLoginFilter, 'UTF-8'), + $this->access->getFilterPartForUserSearch($search) + )); + $ldap_users = $this->access->fetchListOfUsers($filter, 'dn'); + if(count($ldap_users) < 1) { + continue; + } + $groupUsers[] = $this->access->dn2username($ldap_users[0]); + } else { + //we need to apply the search filter now + if(!$this->access->readAttribute($member, + $this->access->connection->ldapUserDisplayName, + $this->access->getFilterPartForUserSearch($search))) { + continue; + } + // dn2username will also check if the users belong to the allowed base + if($ocname = $this->access->dn2username($member)) { + $groupUsers[] = $ocname; + } + } + } + + return $groupUsers; + } + /** * @brief get a list of all display names in a group * @returns array with display names (value) and user ids(key) @@ -418,6 +495,9 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { * compared with OC_USER_BACKEND_CREATE_USER etc. */ public function implementsActions($actions) { - return (bool)(OC_GROUP_BACKEND_GET_DISPLAYNAME & $actions); + return (bool)(( + OC_GROUP_BACKEND_GET_DISPLAYNAME + | OC_GROUP_BACKEND_COUNT_USERS + ) & $actions); } } diff --git a/apps/user_ldap/group_proxy.php b/apps/user_ldap/group_proxy.php index 4404bd7fe3..c000973623 100644 --- a/apps/user_ldap/group_proxy.php +++ b/apps/user_ldap/group_proxy.php @@ -144,6 +144,17 @@ class Group_Proxy extends lib\Proxy implements \OCP\GroupInterface { return $users; } + /** + * @brief returns the number of users in a group, who match the search term + * @param string the internal group name + * @param string optional, a search string + * @returns int | bool + */ + public function countUsersInGroup($gid, $search = '') { + return $this->handleRequest( + $gid, 'countUsersInGroup', array($gid, $search)); + } + /** * @brief get a list of all display names in a group * @returns array with display names (value) and user ids(key)