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-39] Correct usage of ALL special class to ANY #19

Merged
merged 3 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import net.tirasa.connid.bundles.ldap.commons.LdapConstants;
import net.tirasa.connid.bundles.ldap.commons.LdapUtil;
import net.tirasa.connid.bundles.ldap.commons.ObjectClassMappingConfig;
import net.tirasa.connid.bundles.ldap.schema.LdapSchemaMapping;
import net.tirasa.connid.bundles.ldap.search.DefaultSearchStrategy;
import org.identityconnectors.common.CollectionUtil;
import org.identityconnectors.common.EqualsHashCodeBuilder;
Expand Down Expand Up @@ -244,6 +245,11 @@ public enum SearchScope {
CollectionUtil.newList("top", "groupOfUniqueNames"),
false, CollectionUtil.newList("cn"));

private final ObjectClassMappingConfig anyObjectConfig = new ObjectClassMappingConfig(
LdapSchemaMapping.ANY_OBJECT_CLASS,
CollectionUtil.newList("top"),
false, CollectionUtil.newList(DEFAULT_ID_ATTRIBUTE));

private final ObjectClassMappingConfig allConfig = new ObjectClassMappingConfig(
ObjectClass.ALL,
CollectionUtil.newList("top"),
Expand Down Expand Up @@ -295,11 +301,11 @@ public void validate() {
checkNotEmpty(groupConfig.getShortNameLdapAttributes(), "groupNameAttributes.notEmpty");
checkNoBlankValues(groupConfig.getShortNameLdapAttributes(), "groupNameAttributes.noBlankValues");

checkNotEmpty(allConfig.getLdapClasses(), "anyObjectClasses.notEmpty");
checkNoBlankValues(allConfig.getLdapClasses(), "anyObjectClasses.noBlankValues");
checkNotEmpty(anyObjectConfig.getLdapClasses(), "anyObjectClasses.notEmpty");
checkNoBlankValues(anyObjectConfig.getLdapClasses(), "anyObjectClasses.noBlankValues");

checkNotEmpty(allConfig.getShortNameLdapAttributes(), "anyObjectNameAttributes.notEmpty");
checkNoBlankValues(allConfig.getShortNameLdapAttributes(), "anyObjectNameAttributes.noBlankValues");
checkNotEmpty(anyObjectConfig.getShortNameLdapAttributes(), "anyObjectNameAttributes.notEmpty");
checkNoBlankValues(anyObjectConfig.getShortNameLdapAttributes(), "anyObjectNameAttributes.noBlankValues");

checkNotBlank(getUserSearchScope(), "userSearchScope.notBlank");
checkValidScope(getUserSearchScope(), "userSearchScope.invalidScope");
Expand Down Expand Up @@ -641,24 +647,24 @@ public void setAddPrincipalToNewGroups(boolean addPrincipalToNewGroups) {
displayMessageKey = "anyObjectClasses.display",
helpMessageKey = "anyObjectClasses.help")
public String[] getAnyObjectClasses() {
List<String> ldapClasses = allConfig.getLdapClasses();
List<String> ldapClasses = anyObjectConfig.getLdapClasses();
return ldapClasses.toArray(new String[ldapClasses.size()]);
}

public void setAnyObjectClasses(String... anyObjectClasses) {
allConfig.setLdapClasses(Arrays.asList(anyObjectClasses));
anyObjectConfig.setLdapClasses(Arrays.asList(anyObjectClasses));
}

@ConfigurationProperty(order = 21,
displayMessageKey = "anyObjectNameAttributes.display",
helpMessageKey = "anyObjectNameAttributes.help")
public String[] getAnyObjectNameAttributes() {
List<String> shortNameLdapAttributes = allConfig.getShortNameLdapAttributes();
List<String> shortNameLdapAttributes = anyObjectConfig.getShortNameLdapAttributes();
return shortNameLdapAttributes.toArray(new String[shortNameLdapAttributes.size()]);
}

public void setAnyObjectNameAttributes(String... anyObjectNameAttributes) {
allConfig.setShortNameLdapAttributes(Arrays.asList(anyObjectNameAttributes));
anyObjectConfig.setShortNameLdapAttributes(Arrays.asList(anyObjectNameAttributes));
}

@ConfigurationProperty(order = 22,
Expand Down Expand Up @@ -1025,6 +1031,7 @@ public Map<ObjectClass, ObjectClassMappingConfig> getObjectClassMappingConfigs()
Map<ObjectClass, ObjectClassMappingConfig> result = new HashMap<ObjectClass, ObjectClassMappingConfig>();
result.put(accountConfig.getObjectClass(), accountConfig);
result.put(groupConfig.getObjectClass(), groupConfig);
result.put(anyObjectConfig.getObjectClass(), anyObjectConfig);
result.put(allConfig.getObjectClass(), allConfig);
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,6 @@ private Set<String> getEffectiveLdapClasses(String ldapClass) {
* Returns the LDAP object classes to which the given framework object class is mapped.
*/
public List<String> getLdapClasses(ObjectClass oclass) {
if (oclass.equals(ANY_OBJECT_CLASS)) {
return Collections.<String>emptyList();
}
ObjectClassMappingConfig oclassConfig = conn.getConfiguration().
getObjectClassMappingConfigs().get(oclass);
if (oclassConfig != null) {
Expand Down Expand Up @@ -220,7 +217,7 @@ public String getLdapUidAttribute(final ObjectClass oclass) {
clazz = oclass;
idAttribute = conn.getConfiguration().getUidAttribute();
} else {
clazz = ObjectClass.ALL;
clazz = oclass.equals(ANY_OBJECT_CLASS) ? oclass : ObjectClass.ALL;
idAttribute = null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import net.tirasa.connid.bundles.ldap.commons.LdapEntry;
import net.tirasa.connid.bundles.ldap.commons.LdapUtil;
import net.tirasa.connid.bundles.ldap.commons.StatusManagement;
import net.tirasa.connid.bundles.ldap.schema.LdapSchemaMapping;
import org.identityconnectors.common.CollectionUtil;
import org.identityconnectors.common.StringUtil;
import org.identityconnectors.common.logging.Log;
Expand Down Expand Up @@ -87,9 +86,6 @@ public class LdapSearch {
private final ResultsHandler handler;

public static Set<String> getAttributesReturnedByDefault(final LdapConnection conn, final ObjectClass oclass) {
if (oclass.equals(LdapSchemaMapping.ANY_OBJECT_CLASS)) {
return CollectionUtil.newSet(Name.NAME);
}
Set<String> result = CollectionUtil.newCaseInsensitiveSet();
ObjectClassInfo oci = conn.getSchemaMapping().schema().findObjectClassInfo(oclass.getObjectClassValue());
if (oci != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import net.tirasa.connid.bundles.ldap.LdapConfiguration;
import net.tirasa.connid.bundles.ldap.LdapConnectorTestBase;
import net.tirasa.connid.bundles.ldap.MyStatusManagement;
import net.tirasa.connid.bundles.ldap.schema.LdapSchemaMapping;

import org.identityconnectors.framework.common.objects.OperationOptions;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -158,6 +160,7 @@ private void doCreateGroup(ConnectorFacade facade) {
public void createArbitrary() {
LdapConfiguration config = newConfiguration();
config.setBaseContexts(SMALL_COMPANY_DN);
config.setAnyObjectClasses("top", "organization");
ConnectorFacade facade = newFacade(config);

doCreateArbitrary(facade);
Expand All @@ -167,6 +170,7 @@ public void createArbitrary() {
public void createArbitraryWhenReadingSchema() {
LdapConfiguration config = newConfiguration(true);
config.setBaseContexts(SMALL_COMPANY_DN);
config.setAnyObjectClasses("top", "organization");
ConnectorFacade facade = newFacade(config);

doCreateArbitrary(facade);
Expand All @@ -178,7 +182,9 @@ public void createArbitraryWhenUidNotDefault() {
assertFalse(config.getUidAttribute().equalsIgnoreCase("entryDN"));
config.setUidAttribute("entryDN");
config.setGidAttribute("entryDN");
config.setAnyObjectNameAttributes("o");
config.setBaseContexts(SMALL_COMPANY_DN);
config.setAnyObjectClasses("top", "organization");
ConnectorFacade facade = newFacade(config);

doCreateArbitrary(facade);
Expand All @@ -190,29 +196,29 @@ private void doCreateArbitrary(ConnectorFacade facade) {
Name name = new Name("o=Smallest," + SMALL_COMPANY_DN);
attributes.add(name);
attributes.add(AttributeBuilder.build("o", "Smallest"));
ObjectClass oclass = new ObjectClass("organization");
Uid uid = facade.create(oclass, attributes, null);
Uid uid = facade.create(LdapSchemaMapping.ANY_OBJECT_CLASS, attributes, null);

ConnectorObject newObject = facade.getObject(oclass, uid, null);
ConnectorObject newObject = facade.getObject(LdapSchemaMapping.ANY_OBJECT_CLASS, uid, null);
assertEquals(name, newObject.getName());
}

@Test
public void createArbitraryWhenNameAttributesNotDefault() {
public void createDeviceWhenNameAttributesNotDefault() {
LdapConfiguration config = newConfiguration();
assertFalse(config.getUidAttribute().equalsIgnoreCase("entryDN"));
config.setAnyObjectNameAttributes("cn");
config.setBaseContexts(SMALL_COMPANY_DN);
config.setAnyObjectClasses("top", "device");
ConnectorFacade facade = newFacade(config);

doCreateDevice(facade);
}

@Test
public void createArbitraryWhenObjectClassesNotDefault() {
public void createDeviceWhenObjectClassesNotDefault() {
LdapConfiguration config = newConfiguration();
assertFalse(config.getUidAttribute().equalsIgnoreCase("entryDN"));
config.setAnyObjectClasses("top", "organization");
config.setAnyObjectClasses("top", "device");
config.setBaseContexts(SMALL_COMPANY_DN);
ConnectorFacade facade = newFacade(config);

Expand All @@ -226,15 +232,13 @@ private void doCreateDevice(ConnectorFacade facade) {
attributes.add(AttributeBuilder.build("cn", DEVICE_0_CN));
attributes.add(AttributeBuilder.build("serialNumber", DEVICE_0_SERIALNUMBER));

ObjectClass oclass = new ObjectClass("device");
Uid uid = facade.create(oclass, attributes, null);
Uid uid = facade.create(LdapSchemaMapping.ANY_OBJECT_CLASS, attributes, null);

ConnectorObject newObject = facade.getObject(oclass, uid, null);
ConnectorObject newObject = facade.getObject(LdapSchemaMapping.ANY_OBJECT_CLASS, uid, null);
assertEquals(name, newObject.getName());

}


@Test
public void createBinaryAttributes() throws IOException {
ConnectorFacade facade = newFacade();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
import net.tirasa.connid.bundles.ldap.LdapConfiguration;
import net.tirasa.connid.bundles.ldap.LdapConnection;
import net.tirasa.connid.bundles.ldap.LdapConnectorTestBase;
import net.tirasa.connid.bundles.ldap.schema.LdapSchemaMapping;

import org.identityconnectors.common.CollectionUtil;
import org.identityconnectors.framework.common.objects.SearchResult;
import org.identityconnectors.framework.spi.SearchResultsHandler;
Expand Down Expand Up @@ -415,6 +417,7 @@ public void configurableGroupScope() {
public void configurableAnyObjectScope() {
LdapConfiguration configuration = newConfiguration();
configuration.setAnyObjectSearchScope("object");
configuration.setAnyObjectClasses("top", "organization");
ConnectorFacade facade = newFacade(configuration);

// Find an organization to pass in OP_CONTAINER.
Expand All @@ -428,10 +431,12 @@ public void configurableAnyObjectScope() {
OperationOptions options = optionsBuilder.build();

// Set up for 'device' search
ObjectClass deviceObjectClass = new ObjectClass("device");
configuration.setAnyObjectClasses("top", "device");
facade = newFacade(configuration);

// We can get the 'carrot laptop' device with an 'object' search by DN
ConnectorObject carrotLaptop = searchByAttribute(facade, deviceObjectClass, new Name(CARROT_LAPTOP_DN));
ConnectorObject carrotLaptop = searchByAttribute(
facade, LdapSchemaMapping.ANY_OBJECT_CLASS, new Name(CARROT_LAPTOP_DN));
assertNotNull(carrotLaptop);

// Reconfigure for 'onelevel' search
Expand All @@ -441,15 +446,15 @@ public void configurableAnyObjectScope() {

// 'carrot laptop'' doesn't exist directly under the organisation..
List<ConnectorObject> objects = TestHelpers.searchToList(
facade, deviceObjectClass, null, options);
facade, LdapSchemaMapping.ANY_OBJECT_CLASS, null, options);
assertTrue(objects.isEmpty());

// Reconfigure for 'subtree' search
configuration.setAnyObjectSearchScope("subtree");
facade = newFacade(configuration);

// ... but does in the organisation subtree
objects = TestHelpers.searchToList(facade, deviceObjectClass, null, options);
objects = TestHelpers.searchToList(facade, LdapSchemaMapping.ANY_OBJECT_CLASS, null, options);
assertFalse(objects.isEmpty());
}

Expand Down Expand Up @@ -544,26 +549,31 @@ public void missingParenthesesAddedToGroupSearchFilter() {

@Test
public void anyObjectSearchFilter() {
ConnectorFacade facade = newFacade();
LdapConfiguration configuration = newConfiguration();
configuration.setAnyObjectClasses("top", "organization");
ConnectorFacade facade = newFacade(configuration);
// Find an organization to pass in OP_CONTAINER.
ObjectClass oclass = new ObjectClass("organization");
ConnectorObject organization = searchByAttribute(facade, oclass, new Name(ACME_DN));

// First just check that there really are some anyObjects (devices in this case).
ObjectClass deviceObjectClass = new ObjectClass("device");

OperationOptionsBuilder optionsBuilder = new OperationOptionsBuilder();
optionsBuilder.setScope(OperationOptions.SCOPE_SUBTREE);
optionsBuilder.setContainer(new QualifiedUid(oclass, organization.getUid()));

// First just check that there really are some anyObjects (devices in this case).
configuration.setAnyObjectClasses("top", "device");
configuration.setAnyObjectNameAttributes("cn");
facade = newFacade(configuration);
List<ConnectorObject> objects = TestHelpers.searchToList(
facade, deviceObjectClass, null, optionsBuilder.build());
facade, LdapSchemaMapping.ANY_OBJECT_CLASS, null, optionsBuilder.build());
assertNotNull(getObjectByName(objects, CARROT_LAPTOP_DN));

// Test the anyObject search filter
LdapConfiguration config = newConfiguration();
config.setAnyObjectSearchFilter("(cn=" + CARROT_LAPTOP_CN + ")");
facade = newFacade(config);
objects = TestHelpers.searchToList(facade, deviceObjectClass, null, optionsBuilder.build());
configuration = newConfiguration();
configuration.setAnyObjectSearchFilter("(cn=" + CARROT_LAPTOP_CN + ")");
configuration.setAnyObjectClasses("top", "device");
facade = newFacade(configuration);
objects = TestHelpers.searchToList(facade, LdapSchemaMapping.ANY_OBJECT_CLASS, null, optionsBuilder.build());
assertEquals(1, objects.size());
assertNotNull(getObjectByName(objects, CARROT_LAPTOP_DN));
}
Expand All @@ -583,10 +593,11 @@ public void anyObjectSearchFilterOnlyAppliesToAnyObjects() {
public void missingParenthesesAddedToAnyObjectSearchFilter() {
LdapConfiguration config = newConfiguration();
config.setAnyObjectSearchFilter("cn=" + CARROT_LAPTOP_CN); // No parentheses enclosing the filter.
config.setAnyObjectClasses("top", "device");
ConnectorFacade facade = newFacade(config);

// If parentheses were not added, the search would fail.
assertNotNull(searchByAttribute(facade, new ObjectClass("device"), new Name(CARROT_LAPTOP_DN)));
assertNotNull(searchByAttribute(facade, LdapSchemaMapping.ANY_OBJECT_CLASS, new Name(CARROT_LAPTOP_DN)));
}

@Test
Expand Down