summaryrefslogtreecommitdiffstats
path: root/apps/user_ldap/lib
diff options
context:
space:
mode:
authorArthur Schiwon <blizzz@owncloud.com>2014-11-28 12:08:33 +0100
committerArthur Schiwon <blizzz@owncloud.com>2014-12-04 19:02:09 +0100
commitee168a121d8ba54e607d739f9e01070ded8bb3b8 (patch)
treec5d231c25394d8076884afd82e39b5f29a38243e /apps/user_ldap/lib
parentb6975143ff03c12e8f996b6f9f3144c5c0f47b25 (diff)
downloadnextcloud-server-ee168a121d8ba54e607d739f9e01070ded8bb3b8.tar.gz
nextcloud-server-ee168a121d8ba54e607d739f9e01070ded8bb3b8.zip
Forward port of #12493
add ldap-search command to occ Conflicts: apps/user_ldap/appinfo/register_command.php LDAP search filter creation changes: 1. do not prepend * wildcard to search terms. Will result in faster search, but you don't find "foobar" when looking for "bar" 2. advanced behaviour when search string contains a space and multiple search attributes are present. The search string is split into single words. The resulting filter requires that each word at least appears once in any search attribute. This is supposed to return better results in big LDAPs. trim search string before passing it on
Diffstat (limited to 'apps/user_ldap/lib')
-rw-r--r--apps/user_ldap/lib/access.php52
1 files changed, 51 insertions, 1 deletions
diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index 6f28a87d30c..5a4d324fba2 100644
--- a/apps/user_ldap/lib/access.php
+++ b/apps/user_ldap/lib/access.php
@@ -403,6 +403,8 @@ class Access extends LDAPUtility implements user\IUserTools {
//a new user/group! Add it only if it doesn't conflict with other backend's users or existing groups
//disabling Cache is required to avoid that the new user is cached as not-existing in fooExists check
+ //NOTE: mind, disabling cache affects only this instance! Using it
+ // outside of core user management will still cache the user as non-existing.
$originalTTL = $this->connection->ldapCacheTTL;
$this->connection->setConfiguration(array('ldapCacheTTL' => 0));
if(($isUser && !\OCP\User::userExists($intName))
@@ -507,6 +509,7 @@ class Access extends LDAPUtility implements user\IUserTools {
if($isUsers) {
//cache the user names so it does not need to be retrieved
//again later (e.g. sharing dialogue).
+ $this->cacheUserExists($ocName);
$this->cacheUserDisplayName($ocName, $nameByLDAP);
}
}
@@ -516,6 +519,14 @@ class Access extends LDAPUtility implements user\IUserTools {
}
/**
+ * caches a user as existing
+ * @param string $ocName the internal ownCloud username
+ */
+ public function cacheUserExists($ocName) {
+ $this->connection->writeToCache('userExists'.$ocName, true);
+ }
+
+ /**
* caches the user display name
* @param string $ocName the internal ownCloud username
* @param string $displayName the display name
@@ -1142,6 +1153,33 @@ class Access extends LDAPUtility implements user\IUserTools {
}
/**
+ * creates a filter part for searches by splitting up the given search
+ * string into single words
+ * @param string $search the search term
+ * @param string[] $searchAttributes needs to have at least two attributes,
+ * otherwise it does not make sense :)
+ * @return string the final filter part to use in LDAP searches
+ * @throws \Exception
+ */
+ private function getAdvancedFilterPartForSearch($search, $searchAttributes) {
+ if(!is_array($searchAttributes) || count($searchAttributes) < 2) {
+ throw new \Exception('searchAttributes must be an array with at least two string');
+ }
+ $searchWords = explode(' ', trim($search));
+ $wordFilters = array();
+ foreach($searchWords as $word) {
+ $word .= '*';
+ //every word needs to appear at least once
+ $wordMatchOneAttrFilters = array();
+ foreach($searchAttributes as $attr) {
+ $wordMatchOneAttrFilters[] = $attr . '=' . $word;
+ }
+ $wordFilters[] = $this->combineFilterWithOr($wordMatchOneAttrFilters);
+ }
+ return $this->combineFilterWithAnd($wordFilters);
+ }
+
+ /**
* creates a filter part for searches
* @param string $search the search term
* @param string[]|null $searchAttributes
@@ -1151,7 +1189,19 @@ class Access extends LDAPUtility implements user\IUserTools {
*/
private function getFilterPartForSearch($search, $searchAttributes, $fallbackAttribute) {
$filter = array();
- $search = empty($search) ? '*' : '*'.$search.'*';
+ $haveMultiSearchAttributes = (is_array($searchAttributes) && count($searchAttributes) > 0);
+ if($haveMultiSearchAttributes && strpos(trim($search), ' ') !== false) {
+ try {
+ return $this->getAdvancedFilterPartForSearch($search, $searchAttributes);
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog(
+ 'user_ldap',
+ 'Creating advanced filter for search failed, falling back to simple method.',
+ \OCP\Util::INFO
+ );
+ }
+ }
+ $search = empty($search) ? '*' : $search.'*';
if(!is_array($searchAttributes) || count($searchAttributes) === 0) {
if(empty($fallbackAttribute)) {
return '';