Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LDAP-45] Search strategy internal search fixes #31

Merged
merged 12 commits into from
Feb 29, 2024
39 changes: 26 additions & 13 deletions src/main/java/net/tirasa/connid/bundles/ldap/LdapConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ public enum SearchScope {

private String changeLogContext = "cn=changelog";

private boolean changeLogPagingSupport = false;

private boolean filterWithOrInsteadOfAnd;

private boolean removeLogEntryObjectClassFromFilter = true;
Expand Down Expand Up @@ -903,7 +905,18 @@ public void setChangeLogContext(String changeLogContext) {
this.changeLogContext = changeLogContext;
}

@ConfigurationProperty(order = 39, operations = { SyncOp.class },
@ConfigurationProperty(order = 40, operations = { SyncOp.class },
displayMessageKey = "changeLogPagingSupport.display",
helpMessageKey = "changeLogPagingSupport.help")
public boolean getChangeLogPagingSupport() {
return changeLogPagingSupport;
}

public void setChangeLogPagingSupport(boolean changeLogPagingSupport) {
this.changeLogPagingSupport = changeLogPagingSupport;
}

@ConfigurationProperty(order = 41, operations = { SyncOp.class },
displayMessageKey = "filterWithOrInsteadOfAnd.display",
helpMessageKey = "filterWithOrInsteadOfAnd.help")
public boolean isFilterWithOrInsteadOfAnd() {
Expand All @@ -914,7 +927,7 @@ public void setFilterWithOrInsteadOfAnd(boolean filterWithOrInsteadOfAnd) {
this.filterWithOrInsteadOfAnd = filterWithOrInsteadOfAnd;
}

@ConfigurationProperty(order = 40, operations = { SyncOp.class },
@ConfigurationProperty(order = 42, operations = { SyncOp.class },
displayMessageKey = "removeLogEntryObjectClassFromFilter.display",
helpMessageKey = "removeLogEntryObjectClassFromFilter.help")
public boolean isRemoveLogEntryObjectClassFromFilter() {
Expand All @@ -925,7 +938,7 @@ public void setRemoveLogEntryObjectClassFromFilter(boolean removeLogEntryObjectC
this.removeLogEntryObjectClassFromFilter = removeLogEntryObjectClassFromFilter;
}

@ConfigurationProperty(order = 41, operations = { SyncOp.class },
@ConfigurationProperty(order = 43, operations = { SyncOp.class },
displayMessageKey = "synchronizePasswords.display",
helpMessageKey = "synchronizePasswords.help")
public boolean isSynchronizePasswords() {
Expand All @@ -936,7 +949,7 @@ public void setSynchronizePasswords(boolean synchronizePasswords) {
this.synchronizePasswords = synchronizePasswords;
}

@ConfigurationProperty(order = 42, operations = { SyncOp.class },
@ConfigurationProperty(order = 44, operations = { SyncOp.class },
displayMessageKey = "passwordAttributeToSynchronize.display",
helpMessageKey = "passwordAttributeToSynchronize.help")
public String getPasswordAttributeToSynchronize() {
Expand All @@ -947,7 +960,7 @@ public void setPasswordAttributeToSynchronize(String passwordAttributeToSynchron
this.passwordAttributeToSynchronize = passwordAttributeToSynchronize;
}

@ConfigurationProperty(order = 43, operations = { SyncOp.class }, confidential = true,
@ConfigurationProperty(order = 45, operations = { SyncOp.class }, confidential = true,
displayMessageKey = "passwordDecryptionKey.display",
helpMessageKey = "passwordDecryptionKey.help")
public GuardedByteArray getPasswordDecryptionKey() {
Expand All @@ -959,7 +972,7 @@ public void setPasswordDecryptionKey(GuardedByteArray passwordDecryptionKey) {
copy() : null;
}

@ConfigurationProperty(order = 44, operations = { SyncOp.class }, confidential = true,
@ConfigurationProperty(order = 46, operations = { SyncOp.class }, confidential = true,
displayMessageKey = "passwordDecryptionInitializationVector.display",
helpMessageKey = "passwordDecryptionInitializationVector.help")
public GuardedByteArray getPasswordDecryptionInitializationVector() {
Expand All @@ -971,7 +984,7 @@ public void setPasswordDecryptionInitializationVector(GuardedByteArray passwordD
? passwordDecryptionInitializationVector.copy() : null;
}

@ConfigurationProperty(order = 45,
@ConfigurationProperty(order = 47,
displayMessageKey = "statusManagementClass.display",
helpMessageKey = "statusManagementClass.help")
public String getStatusManagementClass() {
Expand All @@ -982,7 +995,7 @@ public void setStatusManagementClass(String statusManagementClass) {
this.statusManagementClass = statusManagementClass;
}

@ConfigurationProperty(order = 46,
@ConfigurationProperty(order = 48,
displayMessageKey = "retrievePasswordsWithSearch.display",
helpMessageKey = "retrievePasswordsWithSearch.help")
public boolean getRetrievePasswordsWithSearch() {
Expand All @@ -993,7 +1006,7 @@ public void setRetrievePasswordsWithSearch(boolean retrievePasswordsWithSearch)
this.retrievePasswordsWithSearch = retrievePasswordsWithSearch;
}

@ConfigurationProperty(order = 47,
@ConfigurationProperty(order = 49,
displayMessageKey = "dnAttribute.display",
helpMessageKey = "dnAttribute.help")
public String getDnAttribute() {
Expand All @@ -1004,7 +1017,7 @@ public void setDnAttribute(String dnAttribute) {
this.dnAttribute = dnAttribute;
}

@ConfigurationProperty(order = 48,
@ConfigurationProperty(order = 50,
displayMessageKey = "groupSearchFilter.display",
helpMessageKey = "groupSearchFilter.help")
public String getGroupSearchFilter() {
Expand All @@ -1015,7 +1028,7 @@ public void setGroupSearchFilter(String groupSearchFilter) {
this.groupSearchFilter = groupSearchFilter;
}

@ConfigurationProperty(order = 49,
@ConfigurationProperty(order = 51,
displayMessageKey = "readTimeout.display",
helpMessageKey = "readTimeout.help")
public long getReadTimeout() {
Expand All @@ -1026,7 +1039,7 @@ public void setReadTimeout(long readTimeout) {
this.readTimeout = readTimeout;
}

@ConfigurationProperty(order = 50,
@ConfigurationProperty(order = 52,
displayMessageKey = "connectTimeout.display",
helpMessageKey = "connectTimeout.help")
public long getConnectTimeout() {
Expand All @@ -1037,7 +1050,7 @@ public void setConnectTimeout(long connectTimeout) {
this.connectTimeout = connectTimeout;
}

@ConfigurationProperty(order = 51,
@ConfigurationProperty(order = 53,
displayMessageKey = "syncStrategy.display",
helpMessageKey = "syncStrategy.help")
public String getSyncStrategy() {
Expand Down
24 changes: 16 additions & 8 deletions src/main/java/net/tirasa/connid/bundles/ldap/commons/LdapUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ private LdapUtil() {
}

/**
* Returns true if the names of the given LDAP attributes are equal. Deals
* with null values as a convenience.
* @return @code true} if the names of the given LDAP attributes are equal. Deals with null values as a convenience.
*/
public static boolean attrNameEquals(String name1, String name2) {
if (name1 == null) {
Expand All @@ -61,8 +60,7 @@ public static boolean attrNameEquals(String name1, String name2) {
}

/**
* Returns {@code true} if the attribute has the binary option,
* e.g., {@code userCertificate;binary}.
* @return {@code true} if the attribute has the binary option, e.g., {@code userCertificate;binary}.
*/
public static boolean hasBinaryOption(String ldapAttrName) {
return ldapAttrName.toLowerCase(Locale.US).endsWith(LDAP_BINARY_OPTION);
Expand All @@ -89,7 +87,7 @@ public static String removeBinaryOption(String ldapAttrName) {
}

/**
* Return the value of the {@code ldapAttrName} parameter cast to a String.
* @return the value of the {@code ldapAttrName} parameter cast to a String.
*/
public static String getStringAttrValue(Attributes ldapAttrs, String ldapAttrName) {
Attribute attr = ldapAttrs.get(ldapAttrName);
Expand All @@ -104,11 +102,11 @@ public static String getStringAttrValue(Attributes ldapAttrs, String ldapAttrNam
}

/**
* Return the <b>case insensitive</b> set of values of the {@code
* @return the <b>case insensitive</b> set of values of the {@code
* ldapAttrName} parameter cast to a String.
*/
public static Set<String> getStringAttrValues(Attributes ldapAttrs, String ldapAttrName) {
Set<String> result = new HashSet<String>();
Set<String> result = new HashSet<>();
addStringAttrValues(ldapAttrs, ldapAttrName, result);
return result;
}
Expand All @@ -130,7 +128,8 @@ public static void addStringAttrValues(Attributes ldapAttrs, String ldapAttrName

/**
* Escapes the given attribute value to the given {@code StringBuilder}.
* Returns {@code true} iff anything was written to the builder.
*
* @returns {@code true} iff anything was written to the builder.
*/
public static boolean escapeAttrValue(Object value, StringBuilder toBuilder) {
if (value == null) {
Expand Down Expand Up @@ -431,38 +430,47 @@ public ListItr(ListIterator iter) {
this.iter = iter;
}

@Override
public void add(E o) {
iter.add(o);
}

@Override
public boolean hasNext() {
return iter.hasNext();
}

@Override
public boolean hasPrevious() {
return iter.hasPrevious();
}

@Override
public E next() {
return cast(iter.next());
}

@Override
public int nextIndex() {
return iter.nextIndex();
}

@Override
public E previous() {
return cast(iter.previous());
}

@Override
public int previousIndex() {
return iter.previousIndex();
}

@Override
public void remove() {
iter.remove();
}

@Override
public void set(E o) {
iter.set(o);
}
Expand Down
37 changes: 26 additions & 11 deletions src/main/java/net/tirasa/connid/bundles/ldap/search/LdapSearch.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ public class LdapSearch {
// An Operation Option specific for usage with LDAP
public static final String OP_IGNORE_CUSTOM_ANY_OBJECT_CONFIG = "IGNORE_CUSTOM_ANY_OBJECT_CONFIG";

public static final String OP_IGNORE_BUILT_IN_FILTERS = "IGNORE_BUILT_IN_FILTERS";

private static final Log LOG = Log.getLog(LdapSearch.class);

protected final LdapConnection conn;
Expand Down Expand Up @@ -208,18 +210,31 @@ protected LdapInternalSearch getInternalSearch(final Set<String> attrsToGet) {
controls.setSearchScope(searchScope);

String optionsFilter = LdapConstants.getSearchFilter(options);
String searchFilter = null;
if (oclass.equals(ObjectClass.ACCOUNT)) {
searchFilter = conn.getConfiguration().getAccountSearchFilter();
} else if (oclass.equals(ObjectClass.GROUP)) {
searchFilter = conn.getConfiguration().getGroupSearchFilter();
} else if (!ignoreUserAnyObjectConfig) {
searchFilter = conn.getConfiguration().getAnyObjectSearchFilter();

boolean ignoreBuiltInFilters;
if (options.getOptions().containsKey(OP_IGNORE_BUILT_IN_FILTERS)) {
ignoreBuiltInFilters = (boolean) options.getOptions().get(OP_IGNORE_BUILT_IN_FILTERS);
} else {
ignoreBuiltInFilters = false;
}

String finalFilter;
if (ignoreBuiltInFilters) {
finalFilter = optionsFilter;
} else {
String searchFilter = null;
if (oclass.equals(ObjectClass.ACCOUNT)) {
searchFilter = conn.getConfiguration().getAccountSearchFilter();
} else if (oclass.equals(ObjectClass.GROUP)) {
searchFilter = conn.getConfiguration().getGroupSearchFilter();
} else if (!ignoreUserAnyObjectConfig) {
searchFilter = conn.getConfiguration().getAnyObjectSearchFilter();
}
String nativeFilter = filter == null ? null : filter.getNativeFilter();

finalFilter = getSearchFilter(optionsFilter, nativeFilter, searchFilter);
}
String nativeFilter = filter == null ? null : filter.getNativeFilter();
return new LdapInternalSearch(conn,
getSearchFilter(optionsFilter, nativeFilter, searchFilter),
dns, strategy, controls);
return new LdapInternalSearch(conn, finalFilter, dns, strategy, controls);
}

protected Set<String> getLdapAttributesToGet(final Set<String> attrsToGet) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/*
/*
* ====================
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
*
* Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved.
*
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License("CDDL") (the "License"). You may not use this file
* except in compliance with the License.
*
*
* You can obtain a copy of the License at
* http://opensource.org/licenses/cddl1.php
* See the License for the specific language governing permissions and limitations
* under the License.
*
*
* When distributing the Covered Code, include this CDDL Header Notice in each file
* and include the License file at http://opensource.org/licenses/cddl1.php.
* If applicable, add the following below this CDDL Header, with the fields
Expand All @@ -29,6 +29,12 @@
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.PagedResultsControl;
import com.sun.jndi.ldap.ctl.VirtualListViewControl;

import org.identityconnectors.framework.common.objects.OperationOptions;

import net.tirasa.connid.bundles.ldap.LdapConnection;

public abstract class LdapSearchStrategy {

Expand Down Expand Up @@ -66,4 +72,17 @@ protected static String searchControlsToString(final SearchControls controls) {
builder.append('}');
return builder.toString();
}

public static Class<? extends LdapSearchStrategy> getSearchStrategy(LdapConnection conn, OperationOptions options) {
Class<? extends LdapSearchStrategy> clazz = DefaultSearchStrategy.class;
if (options.getPageSize() != null) {
if (conn.getConfiguration().isUseVlvControls() && conn.supportsControl(VirtualListViewControl.OID)) {
clazz = VlvIndexSearchStrategy.class;
} else if (conn.supportsControl(PagedResultsControl.OID)) {
clazz = PagedSearchStrategy.class;
}
}

return clazz;
}
}
Loading