Skip to content

Commit

Permalink
[LDAP-44] Cater for extendability and inheritance - prepares for AD-75 (
Browse files Browse the repository at this point in the history
  • Loading branch information
Sylinsic authored Jan 31, 2024
1 parent 5a30900 commit 6b33cf7
Show file tree
Hide file tree
Showing 26 changed files with 237 additions and 213 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@

public class LdapAuthenticate {

private final LdapConnection conn;
protected final LdapConnection conn;

private final ObjectClass oclass;
protected final ObjectClass oclass;

private final String username;
protected final String username;

private final OperationOptions options;
protected final OperationOptions options;

public LdapAuthenticate(LdapConnection conn, ObjectClass oclass, String username, OperationOptions options) {
this.conn = conn;
Expand Down Expand Up @@ -90,7 +90,7 @@ public Uid resolveUsername() {
return authnObject.getUid();
}

private ConnectorObject getObjectToAuthenticate() {
protected ConnectorObject getObjectToAuthenticate() {
List<String> userNameAttrs = getUserNameAttributes();
Map<String, ConnectorObject> entryDN2Object = new HashMap<String, ConnectorObject>();
final String dnAttributeName = conn.getConfiguration().getDnAttribute();
Expand All @@ -113,15 +113,15 @@ private ConnectorObject getObjectToAuthenticate() {
return null;
}

private List<String> getUserNameAttributes() {
protected List<String> getUserNameAttributes() {
String[] result = LdapConstants.getLdapUidAttributes(options);
if (result != null && result.length > 0) {
return Arrays.asList(result);
}
return conn.getSchemaMapping().getUserNameLdapAttributes(oclass);
return conn.getSchema().getUserNameLdapAttributes(oclass);
}

private static boolean isSuccess(AuthenticationResult authResult) {
protected static boolean isSuccess(AuthenticationResult authResult) {
// We consider PASSWORD_EXPIRED to be a success, because it means the credentials were right.
return authResult.getType() != null
&& (authResult.getType().equals(AuthenticationResultType.SUCCESS)
Expand Down
46 changes: 33 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 @@ -37,7 +37,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.schema.LdapSchema;
import net.tirasa.connid.bundles.ldap.search.DefaultSearchStrategy;
import net.tirasa.connid.bundles.ldap.sync.LdapSyncStrategy;
import net.tirasa.connid.bundles.ldap.sync.sunds.SunDSChangeLogSyncStrategy;
Expand Down Expand Up @@ -225,6 +225,10 @@ public enum SearchScope {

private Class<? extends LdapSyncStrategy> syncStrategyClass = null;

private Class<? extends LdapSyncStrategy> fallbackSyncStrategyClass = SunDSChangeLogSyncStrategy.class;

private Class<? extends LdapConnection> connectionClass = LdapConnection.class;

/**
* The SearchScope for user objects
*/
Expand Down Expand Up @@ -258,7 +262,7 @@ public enum SearchScope {
false, CollectionUtil.newList("cn"));

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

Expand Down Expand Up @@ -365,13 +369,13 @@ public void validate() {
checkLdapSyncStrategy();
}

private void checkNotBlank(String value, String errorMessage) {
protected void checkNotBlank(String value, String errorMessage) {
if (StringUtil.isBlank(value)) {
failValidation(errorMessage);
}
}

private void checkNotBlank(GuardedByteArray array, String errorMessage) {
protected void checkNotBlank(GuardedByteArray array, String errorMessage) {
final int[] length = { 0 };
if (array != null) {
array.access(new Accessor() {
Expand All @@ -388,7 +392,7 @@ public void access(byte[] clearBytes) {
}

@SuppressWarnings("unchecked")
private void checkLdapSyncStrategy() {
protected void checkLdapSyncStrategy() {
try {
Class<?> clazz = Class.forName(syncStrategy);
if (LdapSyncStrategy.class.isAssignableFrom(clazz) && !Modifier.isAbstract(clazz.getModifiers())) {
Expand All @@ -401,35 +405,35 @@ private void checkLdapSyncStrategy() {
}
}

private void checkNotEmpty(Collection<?> collection, String errorMessage) {
protected void checkNotEmpty(Collection<?> collection, String errorMessage) {
if (collection.isEmpty()) {
failValidation(errorMessage);
}
}

private void checkNotEmpty(String[] array, String errorMessage) {
protected void checkNotEmpty(String[] array, String errorMessage) {
if (array == null || array.length < 1) {
failValidation(errorMessage);
}
}

private void checkNoBlankValues(Collection<String> collection, String errorMessage) {
protected void checkNoBlankValues(Collection<String> collection, String errorMessage) {
for (String each : collection) {
if (StringUtil.isBlank(each)) {
failValidation(errorMessage);
}
}
}

private void checkNoBlankValues(String[] array, String errorMessage) {
protected void checkNoBlankValues(String[] array, String errorMessage) {
for (String each : array) {
if (StringUtil.isBlank(each)) {
failValidation(errorMessage);
}
}
}

private void checkNoInvalidLdapNames(String[] array, String errorMessage) {
protected void checkNoInvalidLdapNames(String[] array, String errorMessage) {
for (String each : array) {
try {
new LdapName(each);
Expand All @@ -439,7 +443,7 @@ private void checkNoInvalidLdapNames(String[] array, String errorMessage) {
}
}

private void checkValidScope(String scope, String errorMessage) {
protected void checkValidScope(String scope, String errorMessage) {
switch (scope) {
case OperationOptions.SCOPE_OBJECT:
case OperationOptions.SCOPE_ONE_LEVEL:
Expand All @@ -450,7 +454,7 @@ private void checkValidScope(String scope, String errorMessage) {
}
}

private void failValidation(String key, Object... args) {
protected void failValidation(String key, Object... args) {
String message = getConnectorMessages().format(key, null, args);
throw new ConfigurationException(message);
}
Expand Down Expand Up @@ -1033,6 +1037,22 @@ public Class<? extends LdapSyncStrategy> getSyncStrategyClass() {
return syncStrategyClass;
}

protected Class<? extends LdapSyncStrategy> getFallbackSyncStrategyClass() {
return fallbackSyncStrategyClass;
}

protected void setFallbackSyncStrategyClass(Class<? extends LdapSyncStrategy> fallbackSyncStrategyClass) {
this.fallbackSyncStrategyClass = fallbackSyncStrategyClass;
}

protected Class<? extends LdapConnection> getConnectionClass() {
return connectionClass;
}

protected void setConnectionClass(Class<? extends LdapConnection> connectionClass) {
this.connectionClass = connectionClass;
}

// Getters and setters for configuration properties end here.
public List<LdapName> getBaseContextsAsLdapNames() {
if (baseContextsAsLdapNames == null) {
Expand Down Expand Up @@ -1090,7 +1110,7 @@ public Map<ObjectClass, ObjectClassMappingConfig> getObjectClassMappingConfigs()
return result;
}

private EqualsHashCodeBuilder createHashCodeBuilder() {
protected EqualsHashCodeBuilder createHashCodeBuilder() {
EqualsHashCodeBuilder builder = new EqualsHashCodeBuilder();
// Exposed configuration properties.
builder.append(host);
Expand Down
40 changes: 20 additions & 20 deletions src/main/java/net/tirasa/connid/bundles/ldap/LdapConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
import net.tirasa.connid.bundles.ldap.commons.LdapUtil;
import net.tirasa.connid.bundles.ldap.commons.ServerNativeSchema;
import net.tirasa.connid.bundles.ldap.commons.StaticNativeSchema;
import net.tirasa.connid.bundles.ldap.schema.LdapSchemaMapping;
import net.tirasa.connid.bundles.ldap.schema.LdapSchema;
import org.identityconnectors.common.CollectionUtil;
import org.identityconnectors.common.Pair;
import org.identityconnectors.common.StringUtil;
Expand Down Expand Up @@ -95,23 +95,23 @@ public class LdapConnection {
LDAP_BINARY_OPTION_ATTRS.add("supportedAlgorithms");
}

private static final String LDAP_CTX_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
protected static final String LDAP_CTX_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";

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

private final LdapConfiguration config;
protected final LdapConfiguration config;

private final LdapSchemaMapping schemaMapping;
protected LdapSchema schema;

private LdapContext initCtx;
protected LdapContext initCtx;

private Set<String> supportedControls;
protected Set<String> supportedControls;

private ServerType serverType;
protected ServerType serverType;

public LdapConnection(LdapConfiguration config) {
this.config = config;
schemaMapping = new LdapSchemaMapping(this);
schema = new LdapSchema(this);
}

public String format(String key, String dflt, Object... args) {
Expand All @@ -130,7 +130,7 @@ public LdapContext getInitialContext() {
return initCtx;
}

private LdapContext connect(String principal, GuardedString credentials) {
protected LdapContext connect(String principal, GuardedString credentials) {
Pair<AuthenticationResult, LdapContext> pair = createContext(principal, credentials);
if (pair.first.getType().equals(AuthenticationResultType.SUCCESS)) {
return pair.second;
Expand All @@ -139,7 +139,7 @@ private LdapContext connect(String principal, GuardedString credentials) {
throw new IllegalStateException("Should never get here");
}

private Pair<AuthenticationResult, LdapContext> createContext(String principal, GuardedString credentials) {
protected Pair<AuthenticationResult, LdapContext> createContext(String principal, GuardedString credentials) {
final List<Pair<AuthenticationResult, LdapContext>> result =
new ArrayList<Pair<AuthenticationResult, LdapContext>>(1);

Expand Down Expand Up @@ -183,7 +183,7 @@ public void access(final char[] clearChars) {
return result.get(0);
}

private Pair<AuthenticationResult, LdapContext> createContext(final Hashtable<?, ?> env) {
protected Pair<AuthenticationResult, LdapContext> createContext(final Hashtable<?, ?> env) {
AuthenticationResult authnResult = null;
InitialLdapContext context = null;
try {
Expand Down Expand Up @@ -214,7 +214,7 @@ private Pair<AuthenticationResult, LdapContext> createContext(final Hashtable<?,
return new Pair<AuthenticationResult, LdapContext>(authnResult, context);
}

private static boolean hasPasswordExpiredControl(Control[] controls) {
protected static boolean hasPasswordExpiredControl(Control[] controls) {
if (controls != null) {
for (Control control : controls) {
if (control instanceof PasswordExpiredResponseControl) {
Expand All @@ -225,7 +225,7 @@ private static boolean hasPasswordExpiredControl(Control[] controls) {
return false;
}

private String getLdapUrls() {
protected String getLdapUrls() {
StringBuilder builder = new StringBuilder();
builder.append("ldap://");
builder.append(config.getHost());
Expand All @@ -246,7 +246,7 @@ public void close() {
}
}

private static void quietClose(LdapContext ctx) {
protected static void quietClose(LdapContext ctx) {
try {
if (ctx != null) {
ctx.close();
Expand All @@ -256,8 +256,8 @@ private static void quietClose(LdapContext ctx) {
}
}

public LdapSchemaMapping getSchemaMapping() {
return schemaMapping;
public LdapSchema getSchema() {
return schema;
}

public LdapNativeSchema createNativeSchema() {
Expand Down Expand Up @@ -303,7 +303,7 @@ public boolean supportsControl(final String oid) {
return getSupportedControls().contains(oid);
}

private Set<String> getSupportedControls() {
protected Set<String> getSupportedControls() {
if (supportedControls == null) {
try {
Attributes attrs = getInitialContext().getAttributes("", new String[] { "supportedControl" });
Expand All @@ -324,7 +324,7 @@ public ServerType getServerType() {
return serverType;
}

private ServerType detectServerType() {
protected ServerType detectServerType() {
try {
Attributes attrs = getInitialContext().getAttributes("", new String[] { "vendorVersion" });
String vendorVersion = LdapUtil.getStringAttrValue(attrs, "vendorVersion");
Expand Down Expand Up @@ -379,9 +379,9 @@ public void propagate(Exception cause) {

public static class AuthenticationResult {

private final AuthenticationResultType type;
protected final AuthenticationResultType type;

private final Exception cause;
protected final Exception cause;

public AuthenticationResult(AuthenticationResultType type) {
this(type, null);
Expand Down
36 changes: 26 additions & 10 deletions src/main/java/net/tirasa/connid/bundles/ldap/LdapConnector.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ public class LdapConnector implements
/**
* The configuration for this connector instance.
*/
private LdapConfiguration config;
protected LdapConfiguration config;

/**
* The connection to the LDAP server.
*/
private LdapConnection conn;
protected LdapConnection conn;

private LdapSyncStrategy syncStrategy;
protected LdapSyncStrategy syncStrategy;

@Override
public Configuration getConfiguration() {
Expand All @@ -87,15 +87,31 @@ public Configuration getConfiguration() {
@Override
public void init(Configuration cfg) {
config = (LdapConfiguration) cfg;
conn = new LdapConnection(config);

Class<? extends LdapSyncStrategy> syncStrategyClass = config.getSyncStrategyClass();
Class<? extends LdapConnection> connectionClass = config.getConnectionClass();

try {
conn = connectionClass.getConstructor(LdapConfiguration.class).newInstance(config);
} catch (Exception e) {
LOG.error(e, "Could not instantiate the configured connection class implementation {0}, reverting to {1}",
connectionClass.getName(), LdapConnection.class.getName());
conn = new LdapConnection(config);
}

try {
syncStrategy = syncStrategyClass.getConstructor(LdapConnection.class).newInstance(conn);
syncStrategy = syncStrategyClass.getConstructor(connectionClass).newInstance(conn);
} catch (Exception e) {
Class<? extends LdapSyncStrategy> fallbackSyncStrategyClass = config.getFallbackSyncStrategyClass();
LOG.error(e, "Could not instantiate the configured {0} implementation, reverting to {1}",
LdapSyncStrategy.class.getName(), SunDSChangeLogSyncStrategy.class.getName());
syncStrategy = new SunDSChangeLogSyncStrategy(conn);
LdapSyncStrategy.class.getName(), fallbackSyncStrategyClass.getName());
try {
syncStrategy = config.getFallbackSyncStrategyClass().getConstructor(connectionClass)
.newInstance(conn);
} catch (Exception ex) {
LOG.error(e, "Could not instantiate the configured fallback {0} imeplementation, falling back to {1}",
LdapSyncStrategy.class.getName(), SunDSChangeLogSyncStrategy.class);
syncStrategy = new SunDSChangeLogSyncStrategy(conn);
}
}
}

Expand All @@ -116,7 +132,7 @@ public void checkAlive() {

@Override
public Schema schema() {
return conn.getSchemaMapping().schema();
return conn.getSchema().schema();
}

@Override
Expand All @@ -142,7 +158,7 @@ public Uid resolveUsername(
public FilterTranslator<LdapFilter> createFilterTranslator(
final ObjectClass oclass,
final OperationOptions options) {
return new LdapFilterTranslator(conn.getSchemaMapping(), oclass);
return new LdapFilterTranslator(conn.getSchema(), oclass);
}

@Override
Expand Down
Loading

0 comments on commit 6b33cf7

Please sign in to comment.