You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2022/12/17 18:19:00 UTC
[syncope] branch master updated: Replacing ApacheDS with UnboundID SDK as test LDAP server
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ò <il...@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:dev@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>