This is an automated email from the ASF dual-hosted git repository. ilgrosso pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push: new 7ad9a72d58 Replacing ApacheDS with UnboundID SDK as test LDAP server 7ad9a72d58 is described below commit 7ad9a72d58d536cc6413a95a0e6eb335c7c0626a Author: Francesco Chicchiriccò <ilgro...@apache.org> AuthorDate: Sat Dec 17 19:18:49 2022 +0100 Replacing ApacheDS with UnboundID SDK as test LDAP server --- .../src/test/resources/domains/MasterContent.xml | 14 +- .../src/test/resources/domains/MasterContent.xml | 14 +- .../LDAPPasswordPropagationActions.java | 48 +- fit/build-tools/pom.xml | 16 +- .../normalization/NormalizationInterceptor.java | 629 --------------------- .../fit/buildtools/ApacheDSRootDseServlet.java | 100 ---- .../fit/buildtools/ApacheDSStartStopListener.java | 276 --------- .../fit/buildtools/LDAPStartStopListener.java | 89 +++ .../fit/buildtools/LdifInputStreamLoader.java | 116 ---- .../buildtools/SyncopeBuildToolsApplication.java | 14 +- .../buildtools/cxf/DateParamConverterProvider.java | 6 +- .../src/main/resources/application.properties | 3 + fit/build-tools/src/main/resources/content.ldif | 16 +- .../org/apache/syncope/fit/core/SearchITCase.java | 2 +- pom.xml | 41 +- src/main/asciidoc/getting-started/obtain.adoc | 2 +- standalone/pom.xml | 2 +- 17 files changed, 156 insertions(+), 1232 deletions(-) diff --git a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml index bd3532be8a..70326e7b38 100644 --- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml @@ -63,7 +63,7 @@ under the License. <!-- Authentication modules --> <AuthModule id="DefaultLDAPAuthModule" authModuleState="ACTIVE" - description="LDAP auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.LDAPAuthModuleConf","userIdAttribute":"cn","bindDn": "uid=admin,ou=system", "bindCredential":"secret","ldapUrl":"ldap://localhost:1389","searchFilter":"cn={user}","baseDn":"ou=People,o=isp","subtreeSearch":true,"principalAttributeList":["sn","givenName","mail","cn"]}' + description="LDAP auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.LDAPAuthModuleConf","userIdAttribute":"cn","bindDn": "${testds.bindDn}", "bindCredential":"${testds.password}","ldapUrl":"ldap://localhost:${testds.port}","searchFilter":"cn={user}","baseDn":"ou=People,${testds.rootDn}","subtreeSearch":true,"principalAttributeList":["sn","givenName","mail","cn"]}' items='[{"intAttrName":"mail","extAttrName":"mail","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"givenName","extAttrName":"givenName","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"sn","extAttrName":"sn","conn [...] <AuthModule id="DefaultJDBCAuthModule" authModuleState="ACTIVE" description="JDBC auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.JDBCAuthModuleConf","sql":"SELECT * FROM users_table WHERE name=?", "fieldPassword": "password"}'/> @@ -89,7 +89,7 @@ under the License. <!-- Attribute repositories --> <AttrRepo id="DefaultLDAPAttrRepo" attrRepoState="ACTIVE" - description="LDAP attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.LDAPAttrRepoConf","searchFilter":"cn={user}","subtreeSearch":true,"ldapUrl":"ldap://localhost:1389","bindDn":"uid=admin,ou=system","bindCredential":"secret","baseDn":"ou=People,o=isp","attributes":{},"useAllQueryAttributes":true,"queryAttributes":{}}'/> + description="LDAP attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.LDAPAttrRepoConf","searchFilter":"cn={user}","subtreeSearch":true,"ldapUrl":"ldap://localhost:${testds.port}","bindDn":"${testds.bindDn}","bindCredential":"${testds.password}","baseDn":"ou=People,${testds.rootDn}","attributes":{},"useAllQueryAttributes":true,"queryAttributes":{}}'/> <AttrRepo id="DefaultJDBCAttrRepo" attrRepoState="ACTIVE" description="JDBC attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.JDBCAttrRepoConf","sql":"SELECT * FROM table WHERE name=?","dialect":"org.hibernate.dialect.H2Dialect","driverClass":"org.h2.Driver","url":"jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1","user":"username","password":"password","singleRow":true,"requireAllAttributes":true,"caseCanonicalization":"NONE","queryType":"AND","columnMappings":{},"username":[],"attributes":{},"caseInsensitiveQueryAttributes [...] <AttrRepo id="DefaultStubAttrRepo" attrRepoState="ACTIVE" @@ -505,12 +505,12 @@ under the License. capabilities='["CREATE","UPDATE","DELETE","SEARCH","SYNC"]'/> <ConnInstance id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" - bundleName="net.tirasa.connid.bundles.ldap" displayName="ApacheDS" + bundleName="net.tirasa.connid.bundles.ldap" displayName="TestLDAP" adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28" location="${connid.location}" connectorName="net.tirasa.connid.bundles.ldap.LdapConnector" version="${connid.ldap.version}" - jsonConf='[{"schema":{"name":"host","type":"java.lang.String","required":true,"order":1,"confidential":false,"defaultValues":[]},"values":["localhost"],"overridable":false},{"schema":{"name":"port","type":"int","required":false,"order":2,"confidential":false,"defaultValues":[389]},"values":[1389],"overridable":false},{"schema":{"name":"ssl","type":"boolean","required":false,"order":3,"confidential":false,"defaultValues":[false]},"values":["false"],"overridable":false},{"s [...] + jsonConf='[{"schema":{"name":"host","type":"java.lang.String","required":true,"order":1,"confidential":false,"defaultValues":[]},"values":["localhost"],"overridable":false},{"schema":{"name":"port","type":"int","required":false,"order":2,"confidential":false,"defaultValues":[389]},"values":[${testds.port}],"overridable":false},{"schema":{"name":"ssl","type":"boolean","required":false,"order":3,"confidential":false,"defaultValues":[false]},"values":["false"],"overridable": [...] capabilities='["CREATE","UPDATE","UPDATE_DELTA","DELETE","SEARCH"]'/> <ConnInstance id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" displayName="H2-test2" @@ -596,7 +596,7 @@ under the License. randomPwdIfNotProvided="1" enforceMandatoryCondition="1" overrideCapabilities="0" propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL" - provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":"'uid=' + username + ',ou=people,o=isp'","items":[{"intAttrName":"username","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]} [...] + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":"'uid=' + username + ',ou=people,${testds.rootDn}'","items":[{"intAttrName":"username","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transf [...] <Implementation id="LDAPMembershipPropagationActions" type="PROPAGATION_ACTIONS" engine="JAVA" body="org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions"/> <ExternalResourcePropAction resource_id="resource-ldap" implementation_id="LDAPMembershipPropagationActions"/> @@ -604,8 +604,8 @@ under the License. randomPwdIfNotProvided="1" enforceMandatoryCondition="1" overrideCapabilities="0" propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL" - jsonConf='[{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute. Default is \"entryUUID\".","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":["entryUUID"]},"overridable":true,"values":["l"]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when [...] - orgUnit='{"objectClass":"organizationalUnit","syncToken":null,"ignoreCaseMatch":false,"connObjectLink":"syncope:fullPath2Dn(fullPath, 'ou') + ',o=isp'","items":[{"intAttrName":"fullpath","extAttrName":"l","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"ou","connObjectKey":false,"password":false,"mandato [...] + jsonConf='[{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute. Default is \"entryUUID\".","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":["entryUUID"]},"overridable":true,"values":["l"]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when [...] + orgUnit='{"objectClass":"organizationalUnit","syncToken":null,"ignoreCaseMatch":false,"connObjectLink":"syncope:fullPath2Dn(fullPath, 'ou') + ',${testds.rootDn}'","items":[{"intAttrName":"fullpath","extAttrName":"l","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"ou","connObjectKey":false,"password":fal [...] <ExternalResource id="ws-target-resource-nopropagation" connector_id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b" randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0" diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml index 2068736e3c..9a0e075325 100644 --- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml @@ -63,7 +63,7 @@ under the License. <!-- Authentication modules --> <AuthModule id="DefaultLDAPAuthModule" authModuleState="ACTIVE" - description="LDAP auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.LDAPAuthModuleConf","userIdAttribute":"cn","bindDn": "uid=admin,ou=system", "bindCredential":"secret","ldapUrl":"ldap://localhost:1389","searchFilter":"cn={user}","baseDn":"ou=People,o=isp","subtreeSearch":true,"principalAttributeList":["sn","givenName","mail","cn"]}' + description="LDAP auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.LDAPAuthModuleConf","userIdAttribute":"cn","bindDn": "${testds.bindDn}", "bindCredential":"${testds.password}","ldapUrl":"ldap://localhost:${testds.port}","searchFilter":"cn={user}","baseDn":"ou=People,${testds.rootDn}","subtreeSearch":true,"principalAttributeList":["sn","givenName","mail","cn"]}' items='[{"intAttrName":"mail","extAttrName":"mail","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"givenName","extAttrName":"givenName","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"sn","extAttrName":"sn","conn [...] <AuthModule id="DefaultJDBCAuthModule" authModuleState="ACTIVE" description="JDBC auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.JDBCAuthModuleConf","sql":"SELECT * FROM users_table WHERE name=?", "fieldPassword": "password"}'/> @@ -89,7 +89,7 @@ under the License. <!-- Attribute repositories --> <AttrRepo id="DefaultLDAPAttrRepo" attrRepoState="ACTIVE" - description="LDAP attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.LDAPAttrRepoConf","searchFilter":"cn={user}","subtreeSearch":true,"ldapUrl":"ldap://localhost:1389","bindDn":"uid=admin,ou=system","bindCredential":"secret","baseDn":"ou=People,o=isp","attributes":{},"useAllQueryAttributes":true,"queryAttributes":{}}'/> + description="LDAP attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.LDAPAttrRepoConf","searchFilter":"cn={user}","subtreeSearch":true,"ldapUrl":"ldap://localhost:${testds.port}","bindDn":"${testds.bindDn}","bindCredential":"${testds.password}","baseDn":"ou=People,${testds.rootDn}","attributes":{},"useAllQueryAttributes":true,"queryAttributes":{}}'/> <AttrRepo id="DefaultJDBCAttrRepo" attrRepoState="ACTIVE" description="JDBC attr repo" jsonConf='{"_class":"org.apache.syncope.common.lib.attr.JDBCAttrRepoConf","sql":"SELECT * FROM table WHERE name=?","dialect":"org.hibernate.dialect.H2Dialect","driverClass":"org.h2.Driver","url":"jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1","user":"username","password":"password","singleRow":true,"requireAllAttributes":true,"caseCanonicalization":"NONE","queryType":"AND","columnMappings":{},"username":[],"attributes":{},"caseInsensitiveQueryAttributes [...] <AttrRepo id="DefaultStubAttrRepo" attrRepoState="ACTIVE" @@ -591,12 +591,12 @@ under the License. capabilities='["CREATE","UPDATE","DELETE","SEARCH","SYNC"]'/> <ConnInstance id="74141a3b-0762-4720-a4aa-fc3e374ef3ef" - bundleName="net.tirasa.connid.bundles.ldap" displayName="ApacheDS" + bundleName="net.tirasa.connid.bundles.ldap" displayName="TestLDAP" adminRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28" location="${connid.location}" connectorName="net.tirasa.connid.bundles.ldap.LdapConnector" version="${connid.ldap.version}" - jsonConf='[{"schema":{"name":"host","type":"java.lang.String","required":true,"order":1,"confidential":false,"defaultValues":[]},"values":["localhost"],"overridable":false},{"schema":{"name":"port","type":"int","required":false,"order":2,"confidential":false,"defaultValues":[389]},"values":[1389],"overridable":false},{"schema":{"name":"ssl","type":"boolean","required":false,"order":3,"confidential":false,"defaultValues":[false]},"values":["false"],"overridable":false},{"s [...] + jsonConf='[{"schema":{"name":"host","type":"java.lang.String","required":true,"order":1,"confidential":false,"defaultValues":[]},"values":["localhost"],"overridable":false},{"schema":{"name":"port","type":"int","required":false,"order":2,"confidential":false,"defaultValues":[389]},"values":[${testds.port}],"overridable":false},{"schema":{"name":"ssl","type":"boolean","required":false,"order":3,"confidential":false,"defaultValues":[false]},"values":["false"],"overridable": [...] capabilities='["CREATE","UPDATE","UPDATE_DELTA","DELETE","SEARCH"]'/> <ConnInstance id="a28abd9b-9f4a-4ef6-a7a8-d19ad2a8f29d" displayName="H2-test2" @@ -682,7 +682,7 @@ under the License. randomPwdIfNotProvided="1" enforceMandatoryCondition="1" overrideCapabilities="0" propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL" - provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":"'uid=' + username + ',ou=people,o=isp'","items":[{"intAttrName":"username","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]} [...] + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":"'uid=' + username + ',ou=people,${testds.rootDn}'","items":[{"intAttrName":"username","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transf [...] <Implementation id="LDAPMembershipPropagationActions" type="PROPAGATION_ACTIONS" engine="JAVA" body="org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions"/> <ExternalResourcePropAction resource_id="resource-ldap" implementation_id="LDAPMembershipPropagationActions"/> @@ -690,8 +690,8 @@ under the License. randomPwdIfNotProvided="1" enforceMandatoryCondition="1" overrideCapabilities="0" propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL" - jsonConf='[{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute. Default is \"entryUUID\".","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":["entryUUID"]},"overridable":true,"values":["l"]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when [...] - orgUnit='{"objectClass":"organizationalUnit","syncToken":null,"ignoreCaseMatch":false,"connObjectLink":"syncope:fullPath2Dn(fullPath, 'ou') + ',o=isp'","items":[{"intAttrName":"fullpath","extAttrName":"l","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"ou","connObjectKey":false,"password":false,"mandato [...] + jsonConf='[{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute. Default is \"entryUUID\".","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":["entryUUID"]},"overridable":true,"values":["l"]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when [...] + orgUnit='{"objectClass":"organizationalUnit","syncToken":null,"ignoreCaseMatch":false,"connObjectLink":"syncope:fullPath2Dn(fullPath, 'ou') + ',${testds.rootDn}'","items":[{"intAttrName":"fullpath","extAttrName":"l","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"ou","connObjectKey":false,"password":fal [...] <ExternalResource id="ws-target-resource-nopropagation" connector_id="fcf9f2b0-f7d6-42c9-84a6-61b28255a42b" randomPwdIfNotProvided="0" enforceMandatoryCondition="1" overrideCapabilities="0" diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java index eb3cee8806..879a014b0a 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java @@ -19,13 +19,13 @@ package org.apache.syncope.core.provisioning.java.propagation; import java.util.Base64; +import java.util.Optional; import java.util.Set; import javax.xml.bind.DatatypeConverter; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.CipherAlgorithm; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.ConnInstance; -import org.apache.syncope.core.persistence.api.entity.task.PropagationData; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.provisioning.api.propagation.PropagationActions; import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; @@ -39,6 +39,7 @@ import org.identityconnectors.framework.common.objects.AttributeUtil; import org.identityconnectors.framework.common.objects.OperationalAttributes; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; /** * Propagate a non-cleartext password out to a resource, if the PropagationManager has not already @@ -48,50 +49,45 @@ import org.springframework.transaction.annotation.Transactional; @SyncopeImplementation(scope = InstanceScope.PER_CONTEXT) public class LDAPPasswordPropagationActions implements PropagationActions { - private static final String CLEARTEXT = "CLEARTEXT"; + protected static final String CLEARTEXT = "CLEARTEXT"; @Autowired - private UserDAO userDAO; + protected UserDAO userDAO; @Transactional(readOnly = true) @Override public void before(final PropagationTaskInfo taskInfo) { if (AnyTypeKind.USER == taskInfo.getAnyTypeKind()) { User user = userDAO.find(taskInfo.getEntityKey()); + if (user == null || user.getPassword() == null) { + return; + } - PropagationData data = taskInfo.getPropagationData(); - if (user != null && user.getPassword() != null && data.getAttributes() != null) { - Set<Attribute> attrs = data.getAttributes(); - - Attribute missing = AttributeUtil.find(PropagationManager.MANDATORY_MISSING_ATTR_NAME, attrs); - - ConnInstance connInstance = taskInfo.getResource().getConnector(); - String cipherAlgorithm = getCipherAlgorithm(connInstance); - if (missing != null && missing.getValue() != null && missing.getValue().size() == 1 - && missing.getValue().get(0).equals(OperationalAttributes.PASSWORD_NAME) - && cipherAlgorithmMatches(getCipherAlgorithm(connInstance), user.getCipherAlgorithm())) { + Set<Attribute> attrs = taskInfo.getPropagationData().getAttributes(); - String password = user.getPassword().toLowerCase(); - byte[] decodedPassword = DatatypeConverter.parseHexBinary(password); - String base64EncodedPassword = Base64.getEncoder().encodeToString(decodedPassword); + String cipherAlgorithm = getCipherAlgorithm(taskInfo.getResource().getConnector()); + Optional.ofNullable(AttributeUtil.find(PropagationManager.MANDATORY_MISSING_ATTR_NAME, attrs)). + filter(missing -> !CollectionUtils.isEmpty(missing.getValue()) + && OperationalAttributes.PASSWORD_NAME.equals(missing.getValue().get(0)) + && cipherAlgorithmMatches(cipherAlgorithm, user.getCipherAlgorithm())). + ifPresent(missing -> { + attrs.remove(missing); - String cipherPlusPassword = ('{' + cipherAlgorithm.toLowerCase() + '}' + base64EncodedPassword); + byte[] decodedPassword = DatatypeConverter.parseHexBinary(user.getPassword().toLowerCase()); + String base64EncodedPassword = Base64.getEncoder().encodeToString(decodedPassword); - Attribute passwordAttribute = AttributeBuilder.buildPassword( - new GuardedString(cipherPlusPassword.toCharArray())); + String cipherPlusPassword = '{' + cipherAlgorithm + '}' + base64EncodedPassword; - attrs.add(passwordAttribute); - attrs.remove(missing); - } - } + attrs.add(AttributeBuilder.buildPassword(new GuardedString(cipherPlusPassword.toCharArray()))); + }); } } protected String getCipherAlgorithm(final ConnInstance connInstance) { return connInstance.getConf().stream(). filter(property -> "passwordHashAlgorithm".equals(property.getSchema().getName()) - && property.getValues() != null && !property.getValues().isEmpty()).findFirst(). - map(cipherAlgorithm -> (String) cipherAlgorithm.getValues().get(0)). + && !property.getValues().isEmpty()).findFirst(). + map(cipherAlgorithm -> cipherAlgorithm.getValues().get(0).toString()). orElse(CLEARTEXT); } diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml index 6c2bb1276a..d99c1b4a76 100644 --- a/fit/build-tools/pom.xml +++ b/fit/build-tools/pom.xml @@ -70,20 +70,8 @@ under the License. </dependency> <dependency> - <groupId>org.apache.directory.server</groupId> - <artifactId>apacheds-core-api</artifactId> - </dependency> - <dependency> - <groupId>org.apache.directory.server</groupId> - <artifactId>apacheds-core-annotations</artifactId> - </dependency> - <dependency> - <groupId>org.apache.directory.server</groupId> - <artifactId>apacheds-service-builder</artifactId> - </dependency> - <dependency> - <groupId>org.apache.directory.api</groupId> - <artifactId>api-ldap-codec-standalone</artifactId> + <groupId>com.unboundid</groupId> + <artifactId>unboundid-ldapsdk</artifactId> </dependency> <dependency> diff --git a/fit/build-tools/src/main/java/org/apache/directory/server/core/normalization/NormalizationInterceptor.java b/fit/build-tools/src/main/java/org/apache/directory/server/core/normalization/NormalizationInterceptor.java deleted file mode 100644 index 3811dde6f8..0000000000 --- a/fit/build-tools/src/main/java/org/apache/directory/server/core/normalization/NormalizationInterceptor.java +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.directory.server.core.normalization; - -// Remove this class as soon as upgrade to ApacheDS 2.0.0.AM27 is available - -// CHECKSTYLE:OFF - -import org.apache.directory.api.ldap.model.constants.SchemaConstants; -import org.apache.directory.api.ldap.model.cursor.EmptyCursor; -import org.apache.directory.api.ldap.model.entry.Entry; -import org.apache.directory.api.ldap.model.entry.Modification; -import org.apache.directory.api.ldap.model.entry.Value; -import org.apache.directory.api.ldap.model.exception.LdapException; -import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeTypeException; -import org.apache.directory.api.ldap.model.filter.AndNode; -import org.apache.directory.api.ldap.model.filter.BranchNode; -import org.apache.directory.api.ldap.model.filter.EqualityNode; -import org.apache.directory.api.ldap.model.filter.ExprNode; -import org.apache.directory.api.ldap.model.filter.LeafNode; -import org.apache.directory.api.ldap.model.filter.NotNode; -import org.apache.directory.api.ldap.model.filter.ObjectClassNode; -import org.apache.directory.api.ldap.model.filter.OrNode; -import org.apache.directory.api.ldap.model.filter.PresenceNode; -import org.apache.directory.api.ldap.model.filter.UndefinedNode; -import org.apache.directory.api.ldap.model.name.Ava; -import org.apache.directory.api.ldap.model.name.Dn; -import org.apache.directory.api.ldap.model.name.Rdn; -import org.apache.directory.api.ldap.model.schema.AttributeType; -import org.apache.directory.api.ldap.model.schema.normalizers.ConcreteNameComponentNormalizer; -import org.apache.directory.api.ldap.model.schema.normalizers.NameComponentNormalizer; -import org.apache.directory.server.core.api.DirectoryService; -import org.apache.directory.server.core.api.InterceptorEnum; -import org.apache.directory.server.core.api.filtering.EntryFilteringCursor; -import org.apache.directory.server.core.api.filtering.EntryFilteringCursorImpl; -import org.apache.directory.server.core.api.interceptor.BaseInterceptor; -import org.apache.directory.server.core.api.interceptor.context.AddOperationContext; -import org.apache.directory.server.core.api.interceptor.context.CompareOperationContext; -import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext; -import org.apache.directory.server.core.api.interceptor.context.HasEntryOperationContext; -import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext; -import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext; -import org.apache.directory.server.core.api.interceptor.context.MoveAndRenameOperationContext; -import org.apache.directory.server.core.api.interceptor.context.MoveOperationContext; -import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext; -import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext; -import org.apache.directory.server.core.api.normalization.FilterNormalizingVisitor; -import org.apache.directory.server.i18n.I18n; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * A name normalization service. This service makes sure all relative and distinguished - * names are normalized before calls are made against the respective interface methods - * on DefaultPartitionNexus. - * - * The Filters are also normalized. - * - * If the Rdn AttributeTypes are not present in the entry for an Add request, - * they will be added. - * - * @author <a href="mailto:d...@directory.apache.org">Apache Directory Project</a> - */ -public class NormalizationInterceptor extends BaseInterceptor -{ - /** logger used by this class */ - private static final Logger LOG = LoggerFactory.getLogger( NormalizationInterceptor.class ); - - /** a filter node value normalizer and undefined node remover */ - private FilterNormalizingVisitor normVisitor; - - - /** - * Creates a new instance of a NormalizationInterceptor. - */ - public NormalizationInterceptor() - { - super( InterceptorEnum.NORMALIZATION_INTERCEPTOR ); - } - - - /** - * Initialize the registries, normalizers. - */ - @Override - public void init( DirectoryService directoryService ) throws LdapException - { - LOG.debug( "Initialiazing the NormalizationInterceptor" ); - - super.init( directoryService ); - - NameComponentNormalizer ncn = new ConcreteNameComponentNormalizer( schemaManager ); - normVisitor = new FilterNormalizingVisitor( ncn, schemaManager ); - } - - - /** - * The destroy method does nothing - */ - @Override - public void destroy() - { - } - - - // ------------------------------------------------------------------------ - // Normalize all Name based arguments for ContextPartition interface operations - // ------------------------------------------------------------------------ - /** - * {@inheritDoc} - */ - @Override - public void add( AddOperationContext addContext ) throws LdapException - { - Dn addDn = addContext.getDn(); - - if ( !addDn.isSchemaAware() ) - { - addContext.setDn( new Dn( schemaManager, addDn ) ); - } - - Dn entryDn = addContext.getEntry().getDn(); - - if ( !entryDn.isSchemaAware() ) - { - addContext.getEntry().setDn( new Dn( schemaManager, entryDn ) ); - } - - addRdnAttributesToEntry( addContext.getDn(), addContext.getEntry() ); - - next( addContext ); - } - - - /** - * {@inheritDoc} - */ - @Override - public boolean compare( CompareOperationContext compareContext ) throws LdapException - { - Dn dn = compareContext.getDn(); - - if ( !dn.isSchemaAware() ) - { - compareContext.setDn( new Dn( schemaManager, dn ) ); - } - - // Get the attributeType from the OID - try - { - AttributeType attributeType = schemaManager.lookupAttributeTypeRegistry( compareContext.getOid() ); - - // Translate the value from binary to String if the AT is HR - if ( attributeType.getSyntax().isHumanReadable() && ( !compareContext.getValue().isHumanReadable() ) ) - { - compareContext.setValue( compareContext.getValue() ); - } - - compareContext.setAttributeType( attributeType ); - } - catch ( LdapException le ) - { - throw new LdapInvalidAttributeTypeException( I18n.err( I18n.ERR_266, compareContext.getOid() ) ); - } - - return next( compareContext ); - } - - - /** - * {@inheritDoc} - */ - @Override - public void delete( DeleteOperationContext deleteContext ) throws LdapException - { - Dn dn = deleteContext.getDn(); - - if ( !dn.isSchemaAware() ) - { - deleteContext.setDn( new Dn( schemaManager, dn ) ); - } - - next( deleteContext ); - } - - - /** - * {@inheritDoc} - */ - @Override - public boolean hasEntry( HasEntryOperationContext hasEntryContext ) throws LdapException - { - Dn dn = hasEntryContext.getDn(); - - if ( !dn.isSchemaAware() ) - { - hasEntryContext.setDn( new Dn( schemaManager, dn ) ); - } - - return next( hasEntryContext ); - } - - - /** - * {@inheritDoc} - */ - @Override - public Entry lookup( LookupOperationContext lookupContext ) throws LdapException - { - Dn dn = lookupContext.getDn(); - - if ( !dn.isSchemaAware() ) - { - lookupContext.setDn( new Dn( schemaManager, dn ) ); - } - - return next( lookupContext ); - } - - - /** - * {@inheritDoc} - */ - @Override - public void modify( ModifyOperationContext modifyContext ) throws LdapException - { - Dn dn = modifyContext.getDn(); - - if ( !dn.isSchemaAware() ) - { - modifyContext.setDn( new Dn( schemaManager, dn ) ); - } - - if ( modifyContext.getModItems() != null ) - { - for ( Modification modification : modifyContext.getModItems() ) - { - AttributeType attributeType = schemaManager.getAttributeType( modification.getAttribute().getId() ); - modification.apply( attributeType ); - } - } - - next( modifyContext ); - } - - - /** - * {@inheritDoc} - */ - @Override - public void move( MoveOperationContext moveContext ) throws LdapException - { - Dn moveDn = moveContext.getDn(); - - if ( !moveDn.isSchemaAware() ) - { - moveContext.setDn( new Dn( schemaManager, moveDn ) ); - } - - Dn oldSuperiorDn = moveContext.getOldSuperior(); - - if ( !oldSuperiorDn.isSchemaAware() ) - { - moveContext.setOldSuperior( new Dn( schemaManager, oldSuperiorDn ) ); - } - - Dn newSuperiorDn = moveContext.getNewSuperior(); - - if ( !newSuperiorDn.isSchemaAware() ) - { - moveContext.setNewSuperior( new Dn( schemaManager, newSuperiorDn ) ); - } - - Dn newDn = moveContext.getNewDn(); - - if ( !newDn.isSchemaAware() ) - { - moveContext.setNewDn( new Dn( schemaManager, newDn ) ); - } - - Rdn rdn = moveContext.getRdn(); - - if ( !rdn.isSchemaAware() ) - { - moveContext.setRdn( new Rdn( schemaManager, rdn ) ); - } - - next( moveContext ); - } - - - /** - * {@inheritDoc} - */ - @Override - public void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws LdapException - { - Rdn newRdn = moveAndRenameContext.getNewRdn(); - - if ( !newRdn.isSchemaAware() ) - { - moveAndRenameContext.setNewRdn( new Rdn( schemaManager, newRdn ) ); - } - - Dn dn = moveAndRenameContext.getDn(); - - if ( !dn.isSchemaAware() ) - { - moveAndRenameContext.setDn( new Dn( schemaManager, dn ) ); - } - - Dn newDn = moveAndRenameContext.getNewDn(); - - if ( !newDn.isSchemaAware() ) - { - moveAndRenameContext.setNewDn( new Dn( schemaManager, newDn ) ); - } - - Dn newSuperiorDn = moveAndRenameContext.getNewSuperiorDn(); - - if ( !newSuperiorDn.isSchemaAware() ) - { - moveAndRenameContext.setNewSuperiorDn( new Dn( schemaManager, newSuperiorDn ) ); - } - - next( moveAndRenameContext ); - } - - - /** - * {@inheritDoc} - */ - @Override - public void rename( RenameOperationContext renameContext ) throws LdapException - { - // Normalize the new Rdn and the Dn if needed - Dn dn = renameContext.getDn(); - - if ( !dn.isSchemaAware() ) - { - renameContext.setDn( new Dn( schemaManager, dn ) ); - } - - Rdn newRdn = renameContext.getNewRdn(); - - if ( !newRdn.isSchemaAware() ) - { - renameContext.setNewRdn( new Rdn( schemaManager, newRdn ) ); - } - - Dn newDn = renameContext.getNewDn(); - - if ( !newDn.isSchemaAware() ) - { - renameContext.setNewDn( new Dn( schemaManager, newDn ) ); - } - - // Push to the next interceptor - next( renameContext ); - } - - - /** - * {@inheritDoc} - */ - @Override - public EntryFilteringCursor search( SearchOperationContext searchContext ) throws LdapException - { - Dn dn = searchContext.getDn(); - - if ( !dn.isSchemaAware() ) - { - searchContext.setDn( new Dn( schemaManager, dn ) ); - } - - ExprNode filter = searchContext.getFilter(); - - if ( filter == null ) - { - LOG.warn( "undefined filter based on undefined attributeType not evaluted at all. Returning empty enumeration." ); - return new EntryFilteringCursorImpl(new EmptyCursor<>(), searchContext, schemaManager ); - } - - // Normalize the filter - filter = ( ExprNode ) filter.accept( normVisitor ); - - if ( filter == null ) - { - LOG.warn( "undefined filter based on undefined attributeType not evaluted at all. Returning empty enumeration." ); - return new EntryFilteringCursorImpl(new EmptyCursor<>(), searchContext, schemaManager ); - } - - // We now have to remove the (ObjectClass=*) filter if it's present, and to add the scope filter - ExprNode modifiedFilter = removeObjectClass( filter ); - - searchContext.setFilter( modifiedFilter ); - - // TODO Normalize the returned Attributes, storing the UP attributes to format the returned values. - return next( searchContext ); - } - - - /** - * Remove the (ObjectClass=*) node from an AndNode, if we have one. - */ - private ExprNode handleAndNode( ExprNode node ) - { - int nbNodes = 0; - AndNode newAndNode = new AndNode(); - - for ( ExprNode child : ( ( BranchNode ) node ).getChildren() ) - { - ExprNode modifiedNode = removeObjectClass( child ); - - if ( !( modifiedNode instanceof ObjectClassNode ) ) - { - newAndNode.addNode( modifiedNode ); - nbNodes++; - } - - if ( modifiedNode instanceof UndefinedNode ) - { - // We can just return an Undefined node as nothing will get selected - return UndefinedNode.UNDEFINED_NODE; - } - } - - switch ( nbNodes ) - { - case 0: - // Unlikely... But (&(ObjectClass=*)) or (|(ObjectClass=*)) are still an option - return ObjectClassNode.OBJECT_CLASS_NODE; - - case 1: - // We can safely remove the AND/OR node and replace it with its first child - return newAndNode.getFirstChild(); - - default: - return newAndNode; - } - } - - - /** - * Remove the (ObjectClass=*) node from a NotNode, if we have one. - */ - private ExprNode handleNotNode( ExprNode node ) - { - NotNode newNotNode = new NotNode(); - - for ( ExprNode child : ( ( BranchNode ) node ).getChildren() ) - { - ExprNode modifiedNode = removeObjectClass( child ); - - if ( modifiedNode instanceof ObjectClassNode ) - { - // We don't want any entry which has an ObjectClass, return an undefined node - return UndefinedNode.UNDEFINED_NODE; - } - - if ( modifiedNode instanceof UndefinedNode ) - { - // Here, we will select everything - return ObjectClassNode.OBJECT_CLASS_NODE; - } - - newNotNode.addNode( modifiedNode ); - - } - - return newNotNode; - } - - - /** - * Remove the (ObjectClass=*) node from an OrNode, if we have one. - */ - private ExprNode handleOrNode( ExprNode node ) - { - OrNode newOrNode = new OrNode(); - - for ( ExprNode child : ( ( BranchNode ) node ).getChildren() ) - { - ExprNode modifiedNode = removeObjectClass( child ); - - if ( modifiedNode instanceof ObjectClassNode ) - { - // We can return immediately with an ObjectClass node - return ObjectClassNode.OBJECT_CLASS_NODE; - } - - newOrNode.addNode( modifiedNode ); - } - - return newOrNode; - } - - - /** - * Remove the (ObjectClass=*) and ( ObjectClass=top) nodes from the filter, if we have one. - */ - private ExprNode removeObjectClass( ExprNode node ) - { - if ( node instanceof LeafNode ) - { - LeafNode leafNode = ( LeafNode ) node; - - if ( leafNode.getAttributeType() == directoryService.getAtProvider().getObjectClass() ) - { - if ( leafNode instanceof PresenceNode ) - { - // We can safely remove the node and return an undefined node - return ObjectClassNode.OBJECT_CLASS_NODE; - } - else if ( leafNode instanceof EqualityNode ) - { - @SuppressWarnings("unchecked") - Value value = ( ( EqualityNode<String> ) leafNode ).getValue(); - - if ( value.equals( SchemaConstants.TOP_OC ) ) - { - // Here too we can safely remove the node and return an undefined node - return ObjectClassNode.OBJECT_CLASS_NODE; - } - } - } - } - - // -------------------------------------------------------------------- - // H A N D L E B R A N C H N O D E S - // -------------------------------------------------------------------- - - if ( node instanceof AndNode ) - { - return handleAndNode( node ); - } - else if ( node instanceof OrNode ) - { - return handleOrNode( node ); - } - else if ( node instanceof NotNode ) - { - return handleNotNode( node ); - } - else - { - // Failover : we return the initial node as is - return node; - } - } - - - // ------------------------------------------------------------------------ - // Normalize all Name based arguments for other interface operations - // ------------------------------------------------------------------------ - /** - * Adds missing Rdn's attributes and values to the entry. - * - * @param dn the Dn - * @param entry the entry - */ - private void addRdnAttributesToEntry( Dn dn, Entry entry ) throws LdapException - { - if ( dn == null || entry == null ) - { - return; - } - - Rdn rdn = dn.getRdn(); - - // Loop on all the AVAs - for ( Ava ava : rdn ) - { - Value value = ava.getValue(); - String upValue = ava.getValue().getString(); - String upId = ava.getType(); - - // Check that the entry contains this Ava - if ( !entry.contains( upId, value ) ) - { - String message = "The Rdn '" + upId + "=" + upValue + "' is not present in the entry"; - LOG.warn( message ); - - // We don't have this attribute : add it. - // Two cases : - // 1) The attribute does not exist - if ( !entry.containsAttribute( upId ) ) - { - entry.add( upId, upValue ); - } - // 2) The attribute exists - else - { - AttributeType at = schemaManager.lookupAttributeTypeRegistry( upId ); - - // 2.1 if the attribute is single valued, replace the value - if ( at.isSingleValued() ) - { - entry.removeAttributes( upId ); - entry.add( upId, upValue ); - } - // 2.2 the attribute is multi-valued : add the missing value - else - { - entry.add( upId, upValue ); - } - } - } - } - } -} diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ApacheDSRootDseServlet.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ApacheDSRootDseServlet.java deleted file mode 100644 index 0be4ef3a7d..0000000000 --- a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ApacheDSRootDseServlet.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.fit.buildtools; - -import java.io.PrintWriter; -import java.util.Properties; -import javax.naming.Context; -import javax.naming.NamingEnumeration; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.naming.directory.DirContext; -import javax.naming.directory.InitialDirContext; -import javax.naming.directory.SearchControls; -import javax.naming.directory.SearchResult; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.directory.server.core.api.DirectoryService; -import org.apache.directory.server.core.jndi.CoreContextFactory; - -@WebServlet(urlPatterns = "/apacheDS") -public class ApacheDSRootDseServlet extends HttpServlet { - - private static final long serialVersionUID = 1514567335969002735L; - - @Override - protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException { - try { - resp.setContentType("text/plain"); - PrintWriter out = resp.getWriter(); - - out.println("*** ApacheDS RootDSE ***\n"); - - DirContext ctx = new InitialDirContext(this.createEnv()); - - SearchControls ctls = new SearchControls(); - ctls.setReturningAttributes(new String[] { "*", "+" }); - ctls.setSearchScope(SearchControls.OBJECT_SCOPE); - - NamingEnumeration<SearchResult> result = ctx.search("", "(objectClass=*)", ctls); - if (result.hasMore()) { - SearchResult entry = result.next(); - Attributes as = entry.getAttributes(); - - NamingEnumeration<String> ids = as.getIDs(); - while (ids.hasMore()) { - String id = ids.next(); - Attribute attr = as.get(id); - for (int i = 0; i < attr.size(); ++i) { - out.println(id + ": " + attr.get(i)); - } - } - } - ctx.close(); - - out.flush(); - } catch (Exception e) { - throw new ServletException(e); - } - } - - /** - * Creates an environment configuration for JNDI access. - */ - private Properties createEnv() { - // Fetch directory service from servlet context - ServletContext servletContext = this.getServletContext(); - DirectoryService directoryService = (DirectoryService) servletContext.getAttribute(DirectoryService.JNDI_KEY); - - Properties env = new Properties(); - env.put(DirectoryService.JNDI_KEY, directoryService); - env.put(Context.PROVIDER_URL, ""); - env.put(Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName()); - - env.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system"); - env.put(Context.SECURITY_CREDENTIALS, "secret"); - env.put(Context.SECURITY_AUTHENTICATION, "simple"); - - return env; - } -} diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ApacheDSStartStopListener.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ApacheDSStartStopListener.java deleted file mode 100644 index 6a3322fdbe..0000000000 --- a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ApacheDSStartStopListener.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.fit.buildtools; - -import java.io.File; -import java.io.IOException; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.annotation.WebListener; -import org.apache.directory.api.ldap.model.constants.SchemaConstants; -import org.apache.directory.api.ldap.model.entry.Entry; -import org.apache.directory.api.ldap.model.name.Dn; -import org.apache.directory.api.ldap.model.schema.LdapComparator; -import org.apache.directory.api.ldap.model.schema.SchemaManager; -import org.apache.directory.api.ldap.model.schema.comparators.NormalizingComparator; -import org.apache.directory.api.ldap.model.schema.registries.ComparatorRegistry; -import org.apache.directory.api.ldap.model.schema.registries.SchemaLoader; -import org.apache.directory.api.ldap.schema.extractor.SchemaLdifExtractor; -import org.apache.directory.api.ldap.schema.extractor.impl.DefaultSchemaLdifExtractor; -import org.apache.directory.api.ldap.schema.loader.LdifSchemaLoader; -import org.apache.directory.api.ldap.schema.manager.impl.DefaultSchemaManager; -import org.apache.directory.api.util.exception.Exceptions; -import org.apache.directory.server.constants.ServerDNConstants; -import org.apache.directory.server.core.DefaultDirectoryService; -import org.apache.directory.server.core.api.DirectoryService; -import org.apache.directory.server.core.api.DnFactory; -import org.apache.directory.server.core.api.InstanceLayout; -import org.apache.directory.server.core.api.partition.Partition; -import org.apache.directory.server.core.api.schema.SchemaPartition; -import org.apache.directory.server.core.factory.JdbmPartitionFactory; -import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex; -import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition; -import org.apache.directory.server.core.partition.ldif.LdifPartition; -import org.apache.directory.server.i18n.I18n; -import org.apache.directory.server.ldap.LdapServer; -import org.apache.directory.server.protocol.shared.transport.TcpTransport; -import org.apache.directory.server.xdbm.Index; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.core.io.Resource; -import org.springframework.web.context.support.WebApplicationContextUtils; - -/** - * Start and stop an embedded ApacheDS instance alongside with Servlet Context. - */ -@WebListener -public class ApacheDSStartStopListener implements ServletContextListener { - - private static final Logger LOG = LoggerFactory.getLogger(ApacheDSStartStopListener.class); - - private DirectoryService service; - - private LdapServer server; - - /** - * Add a new partition to the server. - * - * @param partitionId The partition Id - * @param partitionDn The partition DN - * @param dnFactory the DN factory - * @return The newly added partition - * @throws Exception If the partition can't be added - */ - private void addPartition(final String partitionId, final String partitionDn, final DnFactory dnFactory) - throws Exception { - - // Create a new partition with the given partition id - JdbmPartition partition = new JdbmPartition(service.getSchemaManager(), dnFactory); - partition.setId(partitionId); - partition.setPartitionPath(new File(service.getInstanceLayout().getPartitionsDirectory(), partitionId).toURI()); - partition.setSuffixDn(new Dn(partitionDn)); - service.addPartition(partition); - - Set<Index<?, String>> indexedAttributes = Stream.of( - SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.OU_AT, - SchemaConstants.UID_AT, SchemaConstants.CN_AT). - map(attr -> new JdbmIndex<String>(attr, false)).collect(Collectors.toSet()); - partition.setIndexedAttributes(indexedAttributes); - } - - /** - * Initialize the schema manager and add the schema partition to directory service. - * - * @throws Exception if the schema LDIF files are not found on the classpath - */ - private void initSchemaPartition() throws Exception { - File workingDirectory = service.getInstanceLayout().getPartitionsDirectory(); - - // Extract the schema on disk (a brand new one) and load the registries - File schemaRepository = new File(workingDirectory, "schema"); - SchemaLdifExtractor extractor = new DefaultSchemaLdifExtractor(workingDirectory); - try { - extractor.extractOrCopy(); - } catch (IOException ioe) { - // The schema has already been extracted, bypass - } - - SchemaLoader loader = new LdifSchemaLoader(schemaRepository); - SchemaManager schemaManager = new DefaultSchemaManager(loader); - - // We have to load the schema now, otherwise we won't be able - // to initialize the Partitions, as we won't be able to parse - // and normalize their suffix Dn - schemaManager.loadAllEnabled(); - - // Tell all the normalizer comparators that they should not normalize anything - ComparatorRegistry comparatorRegistry = schemaManager.getComparatorRegistry(); - for (LdapComparator<?> comparator : comparatorRegistry) { - if (comparator instanceof NormalizingComparator) { - ((NormalizingComparator) comparator).setOnServer(); - } - } - - service.setSchemaManager(schemaManager); - - // Init the LdifPartition - LdifPartition ldifPartition = new LdifPartition(schemaManager, service.getDnFactory()); - ldifPartition.setPartitionPath(new File(workingDirectory, "schema").toURI()); - SchemaPartition schemaPartition = new SchemaPartition(schemaManager); - schemaPartition.setWrappedPartition(ldifPartition); - service.setSchemaPartition(schemaPartition); - - List<Throwable> errors = schemaManager.getErrors(); - if (!errors.isEmpty()) { - throw new IllegalStateException(I18n.err(I18n.ERR_317, Exceptions.printErrors(errors))); - } - } - - private void initSystemPartition() throws Exception { - JdbmPartitionFactory partitionFactory = new JdbmPartitionFactory(); - - Partition systemPartition = partitionFactory.createPartition( - service.getSchemaManager(), - service.getDnFactory(), - "system", - ServerDNConstants.SYSTEM_DN, - 500, - new File(service.getInstanceLayout().getPartitionsDirectory(), "system")); - systemPartition.setSchemaManager(service.getSchemaManager()); - - partitionFactory.addIndex(systemPartition, SchemaConstants.OBJECT_CLASS_AT, 100); - - service.setSystemPartition(systemPartition); - } - - /** - * Initialize the server. It creates the partition, adds the index, and injects the context entries for the created - * partitions. - * - * @param workDir the directory to be used for storing the data - * @param loadDefaultContent if default content should be loaded - * @throws Exception if there were some problems while initializing - */ - private void initDirectoryService(final ServletContext servletContext, final File workDir, - final boolean loadDefaultContent) throws Exception { - - // Initialize the LDAP service - service = new DefaultDirectoryService(); - service.setInstanceLayout(new InstanceLayout(workDir)); - - // first load the schema - initSchemaPartition(); - - // then the system partition - initSystemPartition(); - - // Disable the ChangeLog system - service.getChangeLog().setEnabled(false); - service.setDenormalizeOpAttrsEnabled(true); - - // Now we can create as many partitions as we need - addPartition("isp", "o=isp", service.getDnFactory()); - - // And start the service - service.startup(); - - if (loadDefaultContent) { - Resource contentLdif = Objects.requireNonNull( - WebApplicationContextUtils.getWebApplicationContext(servletContext)) - .getResource("classpath:/content.ldif"); - LdifInputStreamLoader contentLoader = new LdifInputStreamLoader(service.getAdminSession(), - contentLdif.getInputStream()); - int numEntries = contentLoader.execute(); - LOG.info("Successfully created {} entries", numEntries); - } - } - - /** - * Startup ApacheDS embedded. - * - * @param sce ServletContext event - */ - @Override - public void contextInitialized(final ServletContextEvent sce) { - File workDir = (File) sce.getServletContext().getAttribute("javax.servlet.context.tempdir"); - workDir = new File(workDir, "server-work"); - - final boolean loadDefaultContent = !workDir.exists(); - - if (loadDefaultContent && !workDir.mkdirs()) { - throw new RuntimeException("Could not create " + workDir.getAbsolutePath()); - } - - Entry result; - try { - initDirectoryService(sce.getServletContext(), workDir, loadDefaultContent); - - ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext( - sce.getServletContext()); - server = new LdapServer(); - server.setTransports(new TcpTransport(Integer.parseInt( - Objects.requireNonNull( - Objects.requireNonNull(applicationContext).getEnvironment().getProperty("testds.port"))))); - server.setDirectoryService(service); - - server.start(); - - // store directoryService in context to provide it to servlets etc. - sce.getServletContext().setAttribute(DirectoryService.JNDI_KEY, service); - - result = service.getAdminSession().lookup(new Dn("o=isp")); - } catch (Exception e) { - LOG.error("Fatal error in context init", e); - throw new RuntimeException(e); - } - - if (result == null) { - throw new RuntimeException("Base DN not found"); - } else { - LOG.info("ApacheDS startup completed successfully"); - } - } - - /** - * Shutdown ApacheDS embedded. - * - * @param sce ServletContext event - */ - @Override - public void contextDestroyed(final ServletContextEvent sce) { - try { - if (server != null) { - server.stop(); - } - if (service != null) { - service.shutdown(); - } - } catch (Exception e) { - LOG.error("Fatal error in context shutdown", e); - throw new RuntimeException(e); - } - } -} diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/LDAPStartStopListener.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/LDAPStartStopListener.java new file mode 100644 index 0000000000..1987db58e4 --- /dev/null +++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/LDAPStartStopListener.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.fit.buildtools; + +import com.unboundid.ldap.listener.Base64PasswordEncoderOutputFormatter; +import com.unboundid.ldap.listener.InMemoryDirectoryServer; +import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; +import com.unboundid.ldap.listener.InMemoryListenerConfig; +import com.unboundid.ldap.listener.UnsaltedMessageDigestInMemoryPasswordEncoder; +import com.unboundid.ldap.sdk.schema.Schema; +import java.net.InetAddress; +import java.security.MessageDigest; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +/** + * Start and stop an in-memory LDAP server instance alongside with Servlet Context. + */ +@WebListener +public class LDAPStartStopListener implements ServletContextListener { + + private static final Logger LOG = LoggerFactory.getLogger(LDAPStartStopListener.class); + + private InMemoryDirectoryServer ldapServer; + + @Override + public void contextInitialized(final ServletContextEvent sce) { + try { + ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()); + + InMemoryDirectoryServerConfig config = + new InMemoryDirectoryServerConfig(ctx.getEnvironment().getProperty("testds.rootDn")); + + config.addAdditionalBindCredentials( + ctx.getEnvironment().getProperty("testds.bindDn"), + ctx.getEnvironment().getProperty("testds.password")); + + InMemoryListenerConfig listenerConfig = InMemoryListenerConfig.createLDAPConfig( + "test-listener", + InetAddress.getLoopbackAddress(), + Integer.parseInt(ctx.getEnvironment().getProperty("testds.port")), + null); + config.setListenerConfigs(listenerConfig); + + config.setSchema(Schema.getDefaultStandardSchema()); + + config.setPasswordEncoders( + new UnsaltedMessageDigestInMemoryPasswordEncoder( + "{SHA}", + Base64PasswordEncoderOutputFormatter.getInstance(), + MessageDigest.getInstance("SHA-1"))); + + ldapServer = new InMemoryDirectoryServer(config); + ldapServer.importFromLDIF(false, ctx.getResource("classpath:/content.ldif").getFile()); + ldapServer.startListening(); + } catch (Exception e) { + LOG.error("Fatal error in context init", e); + throw new RuntimeException(e); + } + } + + @Override + public void contextDestroyed(final ServletContextEvent sce) { + if (ldapServer != null) { + ldapServer.shutDown(true); + } + } +} diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/LdifInputStreamLoader.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/LdifInputStreamLoader.java deleted file mode 100644 index fe1116e572..0000000000 --- a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/LdifInputStreamLoader.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.fit.buildtools; - -import java.io.InputStream; -import java.util.List; -import org.apache.directory.api.ldap.model.entry.DefaultEntry; -import org.apache.directory.api.ldap.model.entry.Entry; -import org.apache.directory.api.ldap.model.entry.Modification; -import org.apache.directory.api.ldap.model.exception.LdapException; -import org.apache.directory.api.ldap.model.ldif.LdifEntry; -import org.apache.directory.api.ldap.model.ldif.LdifReader; -import org.apache.directory.api.ldap.model.name.Dn; -import org.apache.directory.server.core.api.CoreSession; -import org.apache.directory.server.i18n.I18n; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class LdifInputStreamLoader { - - /** - * The log for this class. - */ - private static final Logger LOG = LoggerFactory.getLogger(LdifInputStreamLoader.class); - - /** - * A handle on the top core session. - */ - protected CoreSession coreSession; - - /** - * The LDIF input stream file containing LDIFs to load. - */ - protected InputStream ldif; - - /** - * the total count of entries loaded - */ - private int count; - - /** - * Creates a new instance of LdifFileLoader. - * - * @param coreSession the context to load the entries into. - * @param ldif the file of LDIF entries to load. - */ - public LdifInputStreamLoader(final CoreSession coreSession, final InputStream ldif) { - this.coreSession = coreSession; - this.ldif = ldif; - } - - /** - * Opens the LDIF file and loads the entries into the context. - * - * @return The count of entries created. - */ - public int execute() { - try { - try { - for (LdifEntry ldifEntry : new LdifReader(ldif)) { - Dn dn = ldifEntry.getDn(); - - if (ldifEntry.isEntry()) { - Entry entry = ldifEntry.getEntry(); - - try { - coreSession.lookup(dn); - LOG.debug("Found {}, will not create.", dn); - } catch (Exception e) { - try { - coreSession.add( - new DefaultEntry(coreSession.getDirectoryService().getSchemaManager(), entry)); - count++; - LOG.debug("Created {}.", dn); - } catch (LdapException e1) { - LOG.error("Could not create entry " + entry, e1); - } - } - } else { - //modify - List<Modification> items = ldifEntry.getModifications(); - - try { - coreSession.modify(dn, items); - LOG.debug("Modified: " + dn + " with modificationItems: " + items); - } catch (LdapException e) { - LOG.debug("Could not modify: " + dn + " with modificationItems: " + items, e); - } - } - } - } finally { - ldif.close(); - } - } catch (Exception ioe) { - LOG.error(I18n.err(I18n.ERR_174), ioe); - } - - return count; - } -} diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/SyncopeBuildToolsApplication.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/SyncopeBuildToolsApplication.java index ec1ea7249b..772dc05183 100644 --- a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/SyncopeBuildToolsApplication.java +++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/SyncopeBuildToolsApplication.java @@ -82,7 +82,7 @@ public class SyncopeBuildToolsApplication extends SpringBootServletInitializer { @Bean public Endpoint soapProvisioning(final Provisioning provisioning, - final Bus bus) { + final Bus bus) { EndpointImpl soapProvisioning = new EndpointImpl(provisioning); soapProvisioning.setBus(bus); soapProvisioning.publish("/soap"); @@ -100,8 +100,12 @@ public class SyncopeBuildToolsApplication extends SpringBootServletInitializer { } @Bean - public Server restProvisioning(final GreenMailService greenMailService, final UserService userService, - final ApplicationContext ctx, final Bus bus) { + public Server restProvisioning( + final GreenMailService greenMailService, + final UserService userService, + final ApplicationContext ctx, + final Bus bus) { + SpringJAXRSServerFactoryBean restProvisioning = new SpringJAXRSServerFactoryBean(); restProvisioning.setApplicationContext(ctx); restProvisioning.setBus(bus); @@ -115,12 +119,10 @@ public class SyncopeBuildToolsApplication extends SpringBootServletInitializer { @Override public void onStartup(final ServletContext sc) throws ServletException { sc.addListener(new ConnectorServerStartStopListener()); - sc.addListener(new ApacheDSStartStopListener()); + sc.addListener(new LDAPStartStopListener()); sc.addListener(new H2StartStopListener()); sc.addListener(new GreenMailStartStopListener()); - ServletRegistration.Dynamic apacheDS = sc.addServlet("ApacheDSRootDseServlet", ApacheDSRootDseServlet.class); - apacheDS.addMapping("/apacheDS"); ServletRegistration.Dynamic sts = sc.addServlet("ServiceTimeoutServlet", ServiceTimeoutServlet.class); sts.addMapping("/services/*"); diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/DateParamConverterProvider.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/DateParamConverterProvider.java index 123bde8161..80b1b9947a 100644 --- a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/DateParamConverterProvider.java +++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/DateParamConverterProvider.java @@ -23,7 +23,7 @@ import java.lang.reflect.Type; import java.util.Date; import javax.ws.rs.ext.ParamConverter; import javax.ws.rs.ext.ParamConverterProvider; -import org.apache.commons.lang3.StringUtils; +import org.springframework.util.StringUtils; public class DateParamConverterProvider implements ParamConverterProvider { @@ -31,11 +31,11 @@ public class DateParamConverterProvider implements ParamConverterProvider { @Override public Date fromString(final String value) { - if (StringUtils.isBlank(value)) { + if (!StringUtils.hasText(value)) { return null; } try { - return new Date(Long.valueOf(value)); + return new Date(Long.parseLong(value)); } catch (final NumberFormatException e) { throw new IllegalArgumentException("Unparsable date: " + value, e); } diff --git a/fit/build-tools/src/main/resources/application.properties b/fit/build-tools/src/main/resources/application.properties index 6ee9cb47c8..4dd3aff457 100644 --- a/fit/build-tools/src/main/resources/application.properties +++ b/fit/build-tools/src/main/resources/application.properties @@ -32,6 +32,9 @@ testdb.username=${testdb.username} testdb.password=${testdb.password} testdb.webport=${testdb.webport} +testds.rootDn=${testds.rootDn} +testds.bindDn=${testds.bindDn} +testds.password=${testds.password} testds.port=${testds.port} testconnectorserver.port=${testconnectorserver.port} diff --git a/fit/build-tools/src/main/resources/content.ldif b/fit/build-tools/src/main/resources/content.ldif index d37c13e2dd..6b05f91826 100644 --- a/fit/build-tools/src/main/resources/content.ldif +++ b/fit/build-tools/src/main/resources/content.ldif @@ -14,25 +14,25 @@ objectClass: organization objectClass: top o: isp -DN: ou=People,o=isp +DN: ou=people,o=isp objectClass: organizationalUnit objectClass: top -ou: People +ou: people -DN: ou=Groups,o=isp +DN: ou=groups,o=isp objectClass: organizationalUnit objectClass: top -ou: Groups +ou: groups -DN: cn=testLDAPGroup,ou=Groups,o=isp +DN: cn=testLDAPGroup,ou=groups,o=isp objectClass: groupOfUniqueNames objectClass: top cn: testLDAPGroup uniqueMember: uid=admin,ou=system -uniqueMember: uid=pullFromLDAP,ou=People,o=isp -owner: uid=pullFromLDAP,ou=People,o=isp +uniqueMember: uid=pullFromLDAP,ou=people,o=isp +owner: uid=pullFromLDAP,ou=people,o=isp -DN: uid=pullFromLDAP,ou=People,o=isp +DN: uid=pullFromLDAP,ou=people,o=isp objectClass: organizationalPerson objectClass: person objectClass: inetOrgPerson diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java index d28f681cfe..933bd95fe9 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java @@ -528,7 +528,7 @@ public class SearchITCase extends AbstractITCase { matches = null; boolean succeeded = false; - // needed because ApacheDS seems to randomly fail when searching with cookie + // needed because embedded LDAP server seems to randomly fail when searching with cookie for (int i = 0; i < 5 && !succeeded; i++) { try { matches = RESOURCE_SERVICE.searchConnObjects( diff --git a/pom.xml b/pom.xml index 10c81a106e..86cb32ac82 100644 --- a/pom.xml +++ b/pom.xml @@ -434,9 +434,6 @@ under the License. <elasticsearch.version>8.5.2</elasticsearch.version> - <apacheds.version>2.0.0.AM26</apacheds.version> - <apachedirapi.version>2.0.0</apachedirapi.version> - <log4j2.version>2.19.0</log4j2.version> <disruptor.version>3.4.4</disruptor.version> @@ -480,13 +477,16 @@ under the License. <curator.version>5.4.0</curator.version> <zookeeper.version>3.8.0</zookeeper.version> + <testds.rootDn>o=isp</testds.rootDn> + <testds.bindDn>uid=admin,ou=system</testds.bindDn> + <testds.password>secret</testds.password> <testds.port>1389</testds.port> - <testdb.webport>9082</testdb.webport> <testdb.driver>org.h2.Driver</testdb.driver> <testdb.url>jdbc:h2:tcp://localhost:9092/mem:testdb;DB_CLOSE_DELAY=-1</testdb.url> <testdb.username>sa</testdb.username> <testdb.password>sa</testdb.password> + <testdb.webport>9082</testdb.webport> <testconnectorserver.port>4554</testconnectorserver.port> <testconnectorserver.key>testconnectorserver</testconnectorserver.key> @@ -1144,39 +1144,6 @@ under the License. <version>${h2.version}</version> </dependency> - <dependency> - <groupId>org.apache.directory.server</groupId> - <artifactId>apacheds-core-api</artifactId> - <version>${apacheds.version}</version> - </dependency> - <dependency> - <groupId>org.apache.directory.server</groupId> - <artifactId>apacheds-core-annotations</artifactId> - <version>${apacheds.version}</version> - <exclusions> - <exclusion> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>org.apache.directory.server</groupId> - <artifactId>apacheds-service-builder</artifactId> - <version>${apacheds.version}</version> - <exclusions> - <exclusion> - <groupId>org.apache.directory.server</groupId> - <artifactId>apacheds-http-integration</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>org.apache.directory.api</groupId> - <artifactId>api-ldap-codec-standalone</artifactId> - <version>${apachedirapi.version}</version> - </dependency> - <dependency> <groupId>com.icegreen</groupId> <artifactId>greenmail</artifactId> diff --git a/src/main/asciidoc/getting-started/obtain.adoc b/src/main/asciidoc/getting-started/obtain.adoc index 457ffd117a..fcbd1ecc91 100644 --- a/src/main/asciidoc/getting-started/obtain.adoc +++ b/src/main/asciidoc/getting-started/obtain.adoc @@ -678,7 +678,7 @@ Credentials: `admin` / `password` Click 'Connect' button | External resource: LDAP -| An http://directory.apache.org/apacheds/[Apache DS^] instance is available. + +| An embedded instance is available. + You can configure any LDAP client (such as http://jxplorer.org/[JXplorer^], for example) with the following information: + + host: `localhost` + diff --git a/standalone/pom.xml b/standalone/pom.xml index 5779ca2281..b1d3bd8803 100644 --- a/standalone/pom.xml +++ b/standalone/pom.xml @@ -171,7 +171,7 @@ under the License. <mkdir dir="${work.dir}/apache-tomcat-${tomcat.version}/${test.csvdir.path}"/> <copy file="../fit/core-reference/src/test/resources/test.csv" todir="${work.dir}/apache-tomcat-${tomcat.version}/${test.csvdir.path}"/> - <!-- Syncope build tools (provide H2, Apache DS and REST / SOAP resources + ConnId connector server) --> + <!-- Syncope build tools (provide H2, LDAP and REST / SOAP resources + ConnId connector server) --> <copy todir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-fit-build-tools"> <fileset dir="../fit/build-tools/target/syncope-fit-build-tools-${project.version}" includes="**/*"/> </copy>