summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Schiwon <blizzz@owncloud.com>2014-11-28 13:31:57 +0100
committerArthur Schiwon <blizzz@owncloud.com>2014-11-28 13:31:57 +0100
commit7484c2f0d84e0fef54c813f8ff0f542a7ace0a87 (patch)
tree954c3227e9639eb0a86a466d61306569f0ec44e9
parent2944f952dca4b859f17357b13a917055e352b824 (diff)
downloadnextcloud-server-7484c2f0d84e0fef54c813f8ff0f542a7ace0a87.tar.gz
nextcloud-server-7484c2f0d84e0fef54c813f8ff0f542a7ace0a87.zip
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.
-rw-r--r--apps/user_ldap/lib/access.php41
1 files changed, 40 insertions, 1 deletions
diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index d3d25e96f2d..8a0191e4244 100644
--- a/apps/user_ldap/lib/access.php
+++ b/apps/user_ldap/lib/access.php
@@ -1152,6 +1152,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
@@ -1161,7 +1188,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 '';