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 2015/01/01 19:12:11 UTC
[16/32] syncope git commit: [SYNCOPE-620] JPA entities + basic tests
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/test/resources/persistence.properties
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/resources/persistence.properties b/syncope620/server/persistence-jpa/src/test/resources/persistence.properties
new file mode 100644
index 0000000..3106b69
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/resources/persistence.properties
@@ -0,0 +1,28 @@
+# 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.
+jpa.driverClassName=org.h2.Driver
+jpa.url=jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1
+jpa.username=sa
+jpa.password=
+jpa.dialect=org.apache.openjpa.jdbc.sql.H2Dictionary
+jpa.pool.validationQuery=SELECT 1
+#note: other connection pool settings can also be configured here, see persistenceContext.xml
+quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+quartz.scheduler.idleWaitTime=5000
+quartz.sql=tables_h2.sql
+audit.sql=audit.sql
+database.schema=
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/test/resources/persistenceTestEnv.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/resources/persistenceTestEnv.xml b/syncope620/server/persistence-jpa/src/test/resources/persistenceTestEnv.xml
new file mode 100644
index 0000000..53bc496
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/resources/persistenceTestEnv.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context.xsd">
+
+ <bean class="org.apache.syncope.server.spring.ApplicationContextProvider"/>
+
+ <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+ <property name="locations">
+ <list>
+ <value>classpath:security.properties</value>
+ </list>
+ </property>
+ <property name="ignoreResourceNotFound" value="true"/>
+ <property name="ignoreUnresolvablePlaceholders" value="true"/>
+ </bean>
+ <bean id="adminUser" class="java.lang.String">
+ <constructor-arg value="${adminUser}"/>
+ </bean>
+ <bean id="anonymousUser" class="java.lang.String">
+ <constructor-arg value="${anonymousUser}"/>
+ </bean>
+
+ <context:component-scan base-package="org.apache.syncope.server.utils"/>
+
+ <import resource="persistenceContext.xml"/>
+</beans>
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/test/resources/simplelogger.properties
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/resources/simplelogger.properties b/syncope620/server/persistence-jpa/src/test/resources/simplelogger.properties
new file mode 100644
index 0000000..8abc668
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/resources/simplelogger.properties
@@ -0,0 +1,17 @@
+# 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.
+org.slf4j.simpleLogger.defaultLogLevel=error
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/pom.xml b/syncope620/server/pom.xml
index b8c0503..fe6c089 100644
--- a/syncope620/server/pom.xml
+++ b/syncope620/server/pom.xml
@@ -34,8 +34,12 @@ under the License.
<packaging>pom</packaging>
<modules>
+ <module>provisioning-api</module>
<module>persistence-api</module>
- <!--<module>persistence-jpa</module>-->
+ <module>persistence-jpa</module>
+ <module>spring</module>
+ <module>security</module>
+ <module>utils</module>
</modules>
</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/pom.xml b/syncope620/server/provisioning-api/pom.xml
new file mode 100644
index 0000000..aa27a1c
--- /dev/null
+++ b/syncope620/server/provisioning-api/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope</groupId>
+ <artifactId>syncope-server</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Server Provisioning API</name>
+ <description>Apache Syncope Server Provisioning API</description>
+ <groupId>org.apache.syncope.server</groupId>
+ <artifactId>syncope-provisioning-api</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>net.tirasa.connid</groupId>
+ <artifactId>connector-framework</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.quartz-scheduler</groupId>
+ <artifactId>quartz</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.server</groupId>
+ <artifactId>syncope-persistence-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/ConnPoolConfUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/ConnPoolConfUtil.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/ConnPoolConfUtil.java
new file mode 100644
index 0000000..917473e
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/ConnPoolConfUtil.java
@@ -0,0 +1,69 @@
+/*
+ * 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.provisioning.api;
+
+import org.apache.syncope.common.lib.to.ConnPoolConfTO;
+import org.apache.syncope.persistence.api.entity.ConnPoolConf;
+import org.identityconnectors.common.pooling.ObjectPoolConfiguration;
+
+public final class ConnPoolConfUtil {
+
+ public static ConnPoolConf getConnPoolConf(final ConnPoolConfTO cpcto, final ConnPoolConf cpc) {
+ ObjectPoolConfiguration opc = new ObjectPoolConfiguration();
+
+ cpc.setMaxIdle(cpcto.getMaxIdle() == null ? opc.getMaxIdle() : cpcto.getMaxIdle());
+ cpc.setMaxObjects(cpcto.getMaxObjects() == null ? opc.getMaxObjects() : cpcto.getMaxObjects());
+ cpc.setMaxWait(cpcto.getMaxWait() == null ? opc.getMaxWait() : cpcto.getMaxWait());
+ cpc.setMinEvictableIdleTimeMillis(cpcto.getMinEvictableIdleTimeMillis() == null
+ ? opc.getMinEvictableIdleTimeMillis() : cpcto.getMinEvictableIdleTimeMillis());
+ cpc.setMinIdle(cpcto.getMinIdle() == null ? opc.getMinIdle() : cpcto.getMinIdle());
+
+ return cpc;
+ }
+
+ public static ObjectPoolConfiguration getObjectPoolConfiguration(final ConnPoolConf cpc) {
+ ObjectPoolConfiguration opc = new ObjectPoolConfiguration();
+ updateObjectPoolConfiguration(opc, cpc);
+ return opc;
+ }
+
+ public static void updateObjectPoolConfiguration(
+ final ObjectPoolConfiguration opc, final ConnPoolConf cpc) {
+
+ if (cpc.getMaxIdle() != null) {
+ opc.setMaxIdle(cpc.getMaxIdle());
+ }
+ if (cpc.getMaxObjects() != null) {
+ opc.setMaxObjects(cpc.getMaxObjects());
+ }
+ if (cpc.getMaxWait() != null) {
+ opc.setMaxWait(cpc.getMaxWait());
+ }
+ if (cpc.getMinEvictableIdleTimeMillis() != null) {
+ opc.setMinEvictableIdleTimeMillis(cpc.getMinEvictableIdleTimeMillis());
+ }
+ if (cpc.getMinIdle() != null) {
+ opc.setMinIdle(cpc.getMinIdle());
+ }
+ }
+
+ private ConnPoolConfUtil() {
+ // empty constructor for static utility class
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/Connector.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/Connector.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/Connector.java
new file mode 100644
index 0000000..de4b472
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/Connector.java
@@ -0,0 +1,216 @@
+/*
+ * 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.provisioning.api;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.common.lib.types.PropagationMode;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.persistence.api.entity.ConnInstance;
+import org.apache.syncope.persistence.api.entity.MappingItem;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.OperationOptions;
+import org.identityconnectors.framework.common.objects.SyncResultsHandler;
+import org.identityconnectors.framework.common.objects.SyncToken;
+import org.identityconnectors.framework.common.objects.Uid;
+import org.identityconnectors.framework.common.objects.filter.Filter;
+
+/**
+ * Entry point for making requests on underlying connector bundles.
+ */
+public interface Connector {
+
+ /**
+ * Authenticate user on a connector instance.
+ *
+ * @param username the name based credential for authentication
+ * @param password the password based credential for authentication
+ * @param options ConnId's OperationOptions
+ * @return Uid of the account that was used to authenticate
+ */
+ Uid authenticate(String username, String password, OperationOptions options);
+
+ /**
+ * Create user / role on a connector instance.
+ *
+ * @param propagationMode propagation mode
+ * @param objectClass ConnId's object class
+ * @param attrs attributes for creation
+ * @param options ConnId's OperationOptions
+ * @param propagationAttempted if creation is actually performed (based on connector instance's capabilities)
+ * @return Uid for created object
+ */
+ Uid create(PropagationMode propagationMode, ObjectClass objectClass,
+ Set<Attribute> attrs, OperationOptions options,
+ Set<String> propagationAttempted);
+
+ /**
+ * Update user / role on a connector instance.
+ *
+ * @param propagationMode propagation mode
+ * @param objectClass ConnId's object class
+ * @param uid user to be updated
+ * @param attrs attributes for update
+ * @param options ConnId's OperationOptions
+ * @param propagationAttempted if update is actually performed (based on connector instance's capabilities)
+ * @return Uid for updated object
+ */
+ Uid update(PropagationMode propagationMode, ObjectClass objectClass,
+ Uid uid, Set<Attribute> attrs, OperationOptions options,
+ Set<String> propagationAttempted);
+
+ /**
+ * Delete user / role on a connector instance.
+ *
+ * @param propagationMode propagation mode
+ * @param objectClass ConnId's object class
+ * @param uid user to be deleted
+ * @param options ConnId's OperationOptions
+ * @param propagationAttempted if deletion is actually performed (based on connector instance's capabilities)
+ */
+ void delete(PropagationMode propagationMode, ObjectClass objectClass,
+ Uid uid, OperationOptions options, Set<String> propagationAttempted);
+
+ /**
+ * Sync users / roles from a connector instance.
+ *
+ * @param objectClass ConnId's object class
+ * @param token to be passed to the underlying connector
+ * @param handler to be used to handle deltas
+ * @param options ConnId's OperationOptions
+ */
+ void sync(ObjectClass objectClass, SyncToken token, SyncResultsHandler handler, OperationOptions options);
+
+ /**
+ * Read latest sync token from a connector instance.
+ *
+ * @param objectClass ConnId's object class.
+ * @return latest sync token
+ */
+ SyncToken getLatestSyncToken(ObjectClass objectClass);
+
+ /**
+ * Get remote object.
+ *
+ * @param objectClass ConnId's object class
+ * @param uid ConnId's Uid
+ * @param options ConnId's OperationOptions
+ * @return ConnId's connector object for given uid
+ */
+ ConnectorObject getObject(ObjectClass objectClass, Uid uid, OperationOptions options);
+
+ /**
+ * Get remote object used by the propagation manager in order to choose for a create (object doesn't exist) or an
+ * update (object exists).
+ *
+ * @param propagationMode propagation mode
+ * @param operationType resource operation type
+ * @param objectClass ConnId's object class
+ * @param uid ConnId's Uid
+ * @param options ConnId's OperationOptions
+ * @return ConnId's connector object for given uid
+ */
+ ConnectorObject getObject(PropagationMode propagationMode, ResourceOperation operationType, ObjectClass objectClass,
+ Uid uid, OperationOptions options);
+
+ /**
+ * Search for remote objects.
+ *
+ * @param objectClass ConnId's object class
+ * @param filter search filter
+ * @param options ConnId's OperationOptions
+ * @return ConnId's connector objects matching the given filter
+ */
+ List<ConnectorObject> search(ObjectClass objectClass, Filter filter, OperationOptions options);
+
+ /**
+ * Get remote object used by the propagation manager in order to choose for a create (object doesn't exist) or an
+ * update (object exists).
+ *
+ * @param objectClass ConnId's object class.
+ * @param handler to be used to handle deltas.
+ * @param options ConnId's OperationOptions.
+ */
+ void getAllObjects(ObjectClass objectClass, SyncResultsHandler handler, OperationOptions options);
+
+ /**
+ * Read attribute for a given connector object.
+ *
+ * @param objectClass ConnId's object class
+ * @param uid ConnId's Uid
+ * @param options ConnId's OperationOptions
+ * @param attributeName attribute to read
+ * @return attribute (if present)
+ */
+ Attribute getObjectAttribute(ObjectClass objectClass, Uid uid, OperationOptions options, String attributeName);
+
+ /**
+ * Read attributes for a given connector object.
+ *
+ * @param objectClass ConnId's object class
+ * @param uid ConnId's Uid
+ * @param options ConnId's OperationOptions
+ * @return attributes (if present)
+ */
+ Set<Attribute> getObjectAttributes(ObjectClass objectClass, Uid uid, OperationOptions options);
+
+ /**
+ * Return resource schema names.
+ *
+ * @param includeSpecial return special attributes (like as __NAME__ or __PASSWORD__) if true
+ * @return schema names
+ */
+ Set<String> getSchemaNames(boolean includeSpecial);
+
+ /**
+ * Return ConnId's object classes supported by this connector.
+ *
+ * @return supported object classes
+ */
+ Set<ObjectClass> getSupportedObjectClasses();
+
+ /**
+ * Validate a connector instance.
+ */
+ void validate();
+
+ /**
+ * Check connection to resource.
+ */
+ void test();
+
+ /**
+ * Getter for active connector instance.
+ *
+ * @return active connector instance.
+ */
+ ConnInstance getActiveConnInstance();
+
+ /**
+ * Build options for requesting all mapped connector attributes.
+ *
+ * @param mapItems mapping items
+ * @return options for requesting all mapped connector attributes
+ * @see OperationOptions
+ */
+ OperationOptions getOperationOptions(Collection<MappingItem> mapItems);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/ConnectorFactory.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/ConnectorFactory.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/ConnectorFactory.java
new file mode 100644
index 0000000..e68975c
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/ConnectorFactory.java
@@ -0,0 +1,63 @@
+/*
+ * 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.provisioning.api;
+
+import java.util.Set;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.persistence.api.entity.ConnInstance;
+import org.apache.syncope.persistence.api.entity.ExternalResource;
+
+/**
+ * Entry point for creating and destroying connectors for external resources.
+ *
+ * @see org.apache.syncope.core.propagation.Connector
+ */
+public interface ConnectorFactory {
+
+ /**
+ * Create connector from given connector instance and configuration properties.
+ *
+ * @param connInstance connector instance
+ * @param configuration configuration properties
+ * @return connector
+ */
+ Connector createConnector(ConnInstance connInstance, Set<ConnConfProperty> configuration);
+
+ /**
+ * Get existing connector for the given resource.
+ *
+ * @param resource the resource.
+ * @return live connector bran for given resource
+ */
+ Connector getConnector(ExternalResource resource);
+
+ /**
+ * Load connectors for all existing resources.
+ *
+ * @see ExternalResource
+ */
+ void load();
+
+ /**
+ * Unload connectors for all existing resources.
+ *
+ * @see ExternalResource
+ */
+ void unload();
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/ConnectorRegistry.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/ConnectorRegistry.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/ConnectorRegistry.java
new file mode 100644
index 0000000..aa1d1c0
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/ConnectorRegistry.java
@@ -0,0 +1,41 @@
+/*
+ * 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.provisioning.api;
+
+import org.apache.syncope.persistence.api.entity.ExternalResource;
+
+/**
+ * Manage Spring beans lifecycle for connectors.
+ */
+public interface ConnectorRegistry {
+
+ /**
+ * Create and register into Spring context a bean for the given resource.
+ *
+ * @param resource external resource
+ */
+ void registerConnector(ExternalResource resource);
+
+ /**
+ * Removes the Spring bean for the given id from the context.
+ *
+ * @param id Spring bean id
+ */
+ void unregisterConnector(String id);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/ProvisioningJob.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/ProvisioningJob.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/ProvisioningJob.java
new file mode 100644
index 0000000..68e8dae
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/ProvisioningJob.java
@@ -0,0 +1,28 @@
+/*
+ * 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.provisioning.api.job;
+
+import java.util.List;
+import org.apache.syncope.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.provisioning.api.sync.ProvisioningActions;
+
+public interface ProvisioningJob<T extends ProvisioningTask, A extends ProvisioningActions> extends TaskJob {
+
+ void setActions(List<A> actions);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/PushJob.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/PushJob.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/PushJob.java
new file mode 100644
index 0000000..016623c
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/PushJob.java
@@ -0,0 +1,26 @@
+/*
+ * 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.provisioning.api.job;
+
+import org.apache.syncope.persistence.api.entity.task.PushTask;
+import org.apache.syncope.provisioning.api.sync.PushActions;
+
+public interface PushJob extends ProvisioningJob<PushTask, PushActions> {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/SyncJob.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/SyncJob.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/SyncJob.java
new file mode 100644
index 0000000..fa74c8f
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/SyncJob.java
@@ -0,0 +1,26 @@
+/*
+ * 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.provisioning.api.job;
+
+import org.apache.syncope.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.provisioning.api.sync.SyncActions;
+
+public interface SyncJob extends ProvisioningJob<SyncTask, SyncActions> {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/TaskJob.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/TaskJob.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/TaskJob.java
new file mode 100644
index 0000000..94f906e
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/job/TaskJob.java
@@ -0,0 +1,43 @@
+/*
+ * 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.provisioning.api.job;
+
+import org.quartz.DisallowConcurrentExecution;
+import org.quartz.Job;
+
+/**
+ * Interface for Quartz jobs bound to a given Task.
+ */
+@DisallowConcurrentExecution
+public interface TaskJob extends Job {
+
+ public static final String DRY_RUN_JOBDETAIL_KEY = "dryRun";
+
+ /**
+ * Task execution status.
+ */
+ public enum Status {
+
+ SUCCESS,
+ FAILURE
+
+ }
+
+ void setTaskId(Long taskId);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/propagation/PropagationActions.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/propagation/PropagationActions.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/propagation/PropagationActions.java
new file mode 100644
index 0000000..d23843e
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/propagation/PropagationActions.java
@@ -0,0 +1,30 @@
+/*
+ * 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.provisioning.api.propagation;
+
+import org.apache.syncope.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.persistence.api.entity.task.TaskExec;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+
+public interface PropagationActions {
+
+ void before(PropagationTask task, ConnectorObject beforeObj);
+
+ void after(PropagationTask task, TaskExec execution, ConnectorObject afterObj);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/ProvisioningActions.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/ProvisioningActions.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/ProvisioningActions.java
new file mode 100644
index 0000000..f69a455
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/ProvisioningActions.java
@@ -0,0 +1,42 @@
+/*
+ * 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.provisioning.api.sync;
+
+import java.util.List;
+import org.quartz.JobExecutionException;
+
+public interface ProvisioningActions {
+
+ /**
+ * Action to be executed before to start the synchronization task execution.
+ *
+ * @param profile sync profile
+ * @throws JobExecutionException in case of generic failure
+ */
+ void beforeAll(final SyncProfile<?, ?> profile) throws JobExecutionException;
+
+ /**
+ * Action to be executed after the synchronization task completion.
+ *
+ * @param profile sync profile
+ * @param results synchronization result
+ * @throws JobExecutionException in case of generic failure
+ */
+ void afterAll(final SyncProfile<?, ?> profile, final List<SyncResult> results) throws JobExecutionException;
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/PushActions.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/PushActions.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/PushActions.java
new file mode 100644
index 0000000..fc79334
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/PushActions.java
@@ -0,0 +1,137 @@
+/*
+ * 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.provisioning.api.sync;
+
+import org.apache.syncope.persistence.api.entity.Subject;
+import org.quartz.JobExecutionException;
+
+/**
+ * Interface for actions to be performed during PushJob execution.
+ */
+public interface PushActions extends ProvisioningActions {
+
+ /**
+ * Action to be executed before to assign (link & provision) a synchronized user / role to the resource.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param subject user / role to be created.
+ * @return subject.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends Subject<?, ?, ?>> T beforeAssign(
+ final SyncProfile<?, ?> profile,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to provision a synchronized user / role to the resource.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param subject user / role to be created.
+ * @return subject.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends Subject<?, ?, ?>> T beforeProvision(
+ final SyncProfile<?, ?> profile,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to update a synchronized user / role on the resource.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param subject user / role to be updated.
+ * @return subject.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends Subject<?, ?, ?>> T beforeUpdate(
+ final SyncProfile<?, ?> profile,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to link a synchronized user / role to the resource.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param subject user / role to be created.
+ * @return subject.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends Subject<?, ?, ?>> T beforeLink(
+ final SyncProfile<?, ?> profile,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to unlink a synchronized user / role from the resource.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param subject user / role to be created.
+ * @return subject.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends Subject<?, ?, ?>> T beforeUnlink(
+ final SyncProfile<?, ?> profile,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to unassign a synchronized user / role from the resource.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param subject user / role to be created.
+ * @return subject.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends Subject<?, ?, ?>> T beforeUnassign(
+ final SyncProfile<?, ?> profile,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to unassign a synchronized user / role from the resource.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param subject user / role to be created.
+ * @return subject.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends Subject<?, ?, ?>> T beforeDeprovision(
+ final SyncProfile<?, ?> profile,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before delete a synchronized user / role locally and from the resource.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param subject user / role to be created.
+ * @return subject.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends Subject<?, ?, ?>> T beforeDelete(
+ final SyncProfile<?, ?> profile,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed after each local user / role synchronization.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param subject synchronized user / role.
+ * @param result operation result.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends Subject<?, ?, ?>> void after(
+ final SyncProfile<?, ?> profile,
+ final T subject,
+ final SyncResult result) throws JobExecutionException;
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncActions.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncActions.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncActions.java
new file mode 100644
index 0000000..ae6c3b3
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncActions.java
@@ -0,0 +1,175 @@
+/*
+ * 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.provisioning.api.sync;
+
+import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+
+/**
+ * Interface for actions to be performed during SyncJob execution.
+ */
+public interface SyncActions extends ProvisioningActions {
+
+ /**
+ * Action to be executed before to create a synchronized user / role locally.
+ * User/role is created locally upon synchronization in case of the un-matching rule
+ * {@link org.apache.syncope.common.types.UnmatchingRule#PROVISION} (default un-matching rule) is applied.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param subject user / role to be created
+ * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends AbstractSubjectTO> SyncDelta beforeProvision(
+ final SyncProfile<?, ?> profile,
+ final SyncDelta delta,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before creating (and linking to the resource) a synchronized user / role locally.
+ * User/role is created locally and linked to the synchronized resource upon synchronization in case of the
+ * un-matching rule {@link org.apache.syncope.common.types.UnmatchingRule#ASSIGN} is applied.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param subject user / role to be created
+ * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends AbstractSubjectTO> SyncDelta beforeAssign(
+ final SyncProfile<?, ?> profile,
+ final SyncDelta delta,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before unlinking resource from the synchronized user / role and de-provisioning.
+ * User/role is unlinked and de-provisioned from the synchronized resource upon synchronization in case of the
+ * matching rule {@link org.apache.syncope.common.types.MatchingRule#UNASSIGN} is applied.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param subject user / role to be created
+ * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends AbstractSubjectTO> SyncDelta beforeUnassign(
+ final SyncProfile<?, ?> profile,
+ final SyncDelta delta,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before de-provisioning action only.
+ * User/role is de-provisioned (without unlinking) from the synchronized resource upon synchronization in case of
+ * the matching rule {@link org.apache.syncope.common.types.MatchingRule#DEPROVISION} is applied.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param subject user / role to be created
+ * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends AbstractSubjectTO> SyncDelta beforeDeprovision(
+ final SyncProfile<?, ?> profile,
+ final SyncDelta delta,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before unlinking resource from the synchronized user / role.
+ * User/role is unlinked (without de-provisioning) from the synchronized resource upon synchronization in case of
+ * the matching rule {@link org.apache.syncope.common.types.MatchingRule#UNLINK} is applied.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param subject user / role to be created
+ * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends AbstractSubjectTO> SyncDelta beforeUnlink(
+ final SyncProfile<?, ?> profile,
+ final SyncDelta delta,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before linking resource to the synchronized user / role.
+ * User/role is linked (without updating) to the synchronized resource upon synchronization in case of
+ * the matching rule {@link org.apache.syncope.common.types.MatchingRule#LINK} is applied.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param subject user / role to be created
+ * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends AbstractSubjectTO> SyncDelta beforeLink(
+ final SyncProfile<?, ?> profile,
+ final SyncDelta delta,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to update a synchronized user / role locally.
+ * User/role is updated upon synchronization in case of the matching rule
+ * {@link org.apache.syncope.common.types.MatchingRule#UPDATE} (default matching rule) is applied.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param subject local user / role information
+ * @param subjectMod modification
+ * @return synchronization information used for logging and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure.
+ */
+ <T extends AbstractSubjectTO, K extends AbstractSubjectMod> SyncDelta beforeUpdate(
+ final SyncProfile<?, ?> profile,
+ final SyncDelta delta,
+ final T subject,
+ final K subjectMod)
+ throws JobExecutionException;
+
+ /**
+ * Action to be executed before to delete a synchronized user / role locally.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param subject local user / role to be deleted
+ * @return synchronization information used for logging and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends AbstractSubjectTO> SyncDelta beforeDelete(
+ final SyncProfile<?, ?> profile,
+ final SyncDelta delta,
+ final T subject) throws JobExecutionException;
+
+ /**
+ * Action to be executed after each local user / role synchronization.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information (may be modified by
+ * 'beforeProvision/beforeUpdate/beforeDelete')
+ * @param subject synchronized local user / role
+ * @param result global synchronization results at the current synchronization step
+ * @throws JobExecutionException in case of generic failure
+ */
+ <T extends AbstractSubjectTO> void after(
+ final SyncProfile<?, ?> profile,
+ final SyncDelta delta,
+ final T subject,
+ final SyncResult result) throws JobExecutionException;
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncProfile.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncProfile.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncProfile.java
new file mode 100644
index 0000000..77cbfe1
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncProfile.java
@@ -0,0 +1,84 @@
+/*
+ * 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.provisioning.api.sync;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.syncope.common.lib.types.ConflictResolutionAction;
+import org.apache.syncope.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.provisioning.api.Connector;
+
+public class SyncProfile<T extends SyncTask, A extends ProvisioningActions> {
+
+ /**
+ * Syncing connector.
+ */
+ private final Connector connector;
+
+ private final T syncTask;
+
+ private Collection<SyncResult> results;
+
+ private boolean dryRun;
+
+ private ConflictResolutionAction resAct;
+
+ private List<A> actions;
+
+ public SyncProfile(final Connector connector, final T syncTask) {
+ this.connector = connector;
+ this.syncTask = syncTask;
+ }
+
+ public Connector getConnector() {
+ return connector;
+ }
+
+ public T getSyncTask() {
+ return syncTask;
+ }
+
+ public Collection<SyncResult> getResults() {
+ return results;
+ }
+
+ public boolean isDryRun() {
+ return dryRun;
+ }
+
+ public void setDryRun(final boolean dryRun) {
+ this.dryRun = dryRun;
+ }
+
+ public ConflictResolutionAction getResAct() {
+ return resAct;
+ }
+
+ public void setResAct(final ConflictResolutionAction resAct) {
+ this.resAct = resAct;
+ }
+
+ public List<A> getActions() {
+ return actions;
+ }
+
+ public void setActions(final List<A> actions) {
+ this.actions = actions;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncResult.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncResult.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncResult.java
new file mode 100644
index 0000000..e6c17ea
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncResult.java
@@ -0,0 +1,140 @@
+/*
+ * 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.provisioning.api.sync;
+
+import java.util.Collection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.TraceLevel;
+
+public class SyncResult {
+
+ public enum Status {
+
+ SUCCESS,
+ FAILURE
+
+ }
+
+ private String message;
+
+ private Status status;
+
+ private AttributableType subjectType;
+
+ private ResourceOperation operation;
+
+ private Long id;
+
+ private String name;
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(final String message) {
+ this.message = message;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(final Long id) {
+ this.id = id;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public void setStatus(final Status status) {
+ this.status = status;
+ }
+
+ public AttributableType getSubjectType() {
+ return subjectType;
+ }
+
+ public void setSubjectType(final AttributableType subjectType) {
+ this.subjectType = subjectType;
+ }
+
+ public ResourceOperation getOperation() {
+ return operation;
+ }
+
+ public void setOperation(final ResourceOperation operation) {
+ this.operation = operation;
+ }
+
+ @Override
+ public String toString() {
+ return new ReflectionToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).toString();
+ }
+
+ /**
+ * Human readable report string, using the given trace level.
+ *
+ * @param level trace level
+ * @return String for certain levels, null for level NONE
+ */
+ public String getReportString(final TraceLevel level) {
+ if (level == TraceLevel.SUMMARY) {
+ // No per entry log in this case.
+ return null;
+ } else if (level == TraceLevel.FAILURES && status == Status.FAILURE) {
+ // only report failures
+ return String.format("Failed %s (id/name): %d/%s with message: %s", operation, id, name, message);
+ } else {
+ // All
+ return String.format("%s %s (id/name): %d/%s %s", operation, status, id, name,
+ StringUtils.isBlank(message)
+ ? ""
+ : "with message: " + message);
+ }
+ }
+
+ /**
+ * Helper method to invoke logging per synchronization result for the given trace level.
+ *
+ * @param results synchronization result
+ * @param level trace level
+ * @return report as string
+ */
+ public static String produceReport(final Collection<SyncResult> results, final TraceLevel level) {
+ StringBuilder sb = new StringBuilder();
+ for (SyncResult result : results) {
+ sb.append(result.getReportString(level)).append("\n");
+ }
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncopeResultHandler.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncopeResultHandler.java
new file mode 100644
index 0000000..b3b366c
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/provisioning/api/sync/SyncopeResultHandler.java
@@ -0,0 +1,29 @@
+/*
+ * 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.provisioning.api.sync;
+
+import org.apache.syncope.persistence.api.entity.task.SyncTask;
+
+public interface SyncopeResultHandler<T extends SyncTask, A extends SyncActions> {
+
+ SyncProfile<T, A> getProfile();
+
+ void setProfilee(SyncProfile<T, A> profile);
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/security/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/security/pom.xml b/syncope620/server/security/pom.xml
new file mode 100644
index 0000000..255f04d
--- /dev/null
+++ b/syncope620/server/security/pom.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope</groupId>
+ <artifactId>syncope-server</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Server Security Features</name>
+ <description>Apache Syncope Server Security Features</description>
+ <groupId>org.apache.syncope.server</groupId>
+ <artifactId>syncope-server-security</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jasypt</groupId>
+ <artifactId>jasypt</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.common</groupId>
+ <artifactId>syncope-common-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/security/src/main/java/org/apache/syncope/server/security/AuthContextUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/security/src/main/java/org/apache/syncope/server/security/AuthContextUtil.java b/syncope620/server/security/src/main/java/org/apache/syncope/server/security/AuthContextUtil.java
new file mode 100644
index 0000000..f414a37
--- /dev/null
+++ b/syncope620/server/security/src/main/java/org/apache/syncope/server/security/AuthContextUtil.java
@@ -0,0 +1,55 @@
+/*
+ * 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.server.security;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+public final class AuthContextUtil {
+
+ public static String getAuthenticatedUsername() {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ return authentication == null ? SyncopeConstants.UNAUTHENTICATED : authentication.getName();
+ }
+
+ public static Set<String> getOwnedEntitlementNames() {
+ final Set<String> result = new HashSet<String>();
+
+ final SecurityContext ctx = SecurityContextHolder.getContext();
+
+ if (ctx != null && ctx.getAuthentication() != null && ctx.getAuthentication().getAuthorities() != null) {
+ for (GrantedAuthority authority : ctx.getAuthentication().getAuthorities()) {
+ result.add(authority.getAuthority());
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Private default constructor, for static-only classes.
+ */
+ private AuthContextUtil() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/security/src/main/java/org/apache/syncope/server/security/Encryptor.java
----------------------------------------------------------------------
diff --git a/syncope620/server/security/src/main/java/org/apache/syncope/server/security/Encryptor.java b/syncope620/server/security/src/main/java/org/apache/syncope/server/security/Encryptor.java
new file mode 100644
index 0000000..7cb0a0c
--- /dev/null
+++ b/syncope620/server/security/src/main/java/org/apache/syncope/server/security/Encryptor.java
@@ -0,0 +1,256 @@
+/*
+ * 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.server.security;
+
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.SecretKeySpec;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.jasypt.commons.CommonUtils;
+import org.jasypt.digest.StandardStringDigester;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.crypto.bcrypt.BCrypt;
+import org.springframework.security.crypto.codec.Base64;
+
+public final class Encryptor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Encryptor.class);
+
+ private static final Map<String, Encryptor> INSTANCES = new ConcurrentHashMap<String, Encryptor>();
+
+ private static final String DEFAULT_SECRET_KEY = "1abcdefghilmnopqrstuvz2!";
+
+ /**
+ * Default value for salted {@link StandardStringDigester#setIterations(int)}.
+ */
+ private static final int DEFAULT_SALT_ITERATIONS = 1;
+
+ /**
+ * Default value for {@link StandardStringDigester#setSaltSizeBytes(int)}.
+ */
+ private static final int DEFAULT_SALT_SIZE_BYTES = 8;
+
+ /**
+ * Default value for {@link StandardStringDigester#setInvertPositionOfPlainSaltInEncryptionResults(boolean)}.
+ */
+ private static final boolean DEFAULT_IPOPSIER = true;
+
+ /**
+ * Default value for salted {@link StandardStringDigester#setInvertPositionOfSaltInMessageBeforeDigesting(boolean)}.
+ */
+ private static final boolean DEFAULT_IPOSIMBD = true;
+
+ /**
+ * Default value for salted {@link StandardStringDigester#setUseLenientSaltSizeCheck(boolean)}.
+ */
+ private static final boolean DEFAULT_ULSSC = true;
+
+ private static String secretKey;
+
+ private static Integer saltIterations;
+
+ private static Integer saltSizeBytes;
+
+ private static Boolean ipopsier;
+
+ private static Boolean iposimbd;
+
+ private static Boolean ulssc;
+
+ static {
+ InputStream propStream = null;
+ try {
+ propStream = Encryptor.class.getResourceAsStream("/security.properties");
+ Properties props = new Properties();
+ props.load(propStream);
+
+ secretKey = props.getProperty("secretKey");
+ saltIterations = Integer.valueOf(props.getProperty("digester.saltIterations"));
+ saltSizeBytes = Integer.valueOf(props.getProperty("digester.saltSizeBytes"));
+ ipopsier = Boolean.valueOf(props.getProperty("digester.invertPositionOfPlainSaltInEncryptionResults"));
+ iposimbd = Boolean.valueOf(props.getProperty("digester.invertPositionOfSaltInMessageBeforeDigesting"));
+ ulssc = Boolean.valueOf(props.getProperty("digester.useLenientSaltSizeCheck"));
+ } catch (Exception e) {
+ LOG.error("Could not read security parameters", e);
+ } finally {
+ IOUtils.closeQuietly(propStream);
+ }
+
+ if (secretKey == null) {
+ secretKey = DEFAULT_SECRET_KEY;
+ LOG.debug("secretKey not found, reverting to default");
+ }
+ if (saltIterations == null) {
+ saltIterations = DEFAULT_SALT_ITERATIONS;
+ LOG.debug("digester.saltIterations not found, reverting to default");
+ }
+ if (saltSizeBytes == null) {
+ saltSizeBytes = DEFAULT_SALT_SIZE_BYTES;
+ LOG.debug("digester.saltSizeBytes not found, reverting to default");
+ }
+ if (ipopsier == null) {
+ ipopsier = DEFAULT_IPOPSIER;
+ LOG.debug("digester.invertPositionOfPlainSaltInEncryptionResults not found, reverting to default");
+ }
+ if (iposimbd == null) {
+ iposimbd = DEFAULT_IPOSIMBD;
+ LOG.debug("digester.invertPositionOfSaltInMessageBeforeDigesting not found, reverting to default");
+ }
+ if (ulssc == null) {
+ ulssc = DEFAULT_ULSSC;
+ LOG.debug("digester.useLenientSaltSizeCheck not found, reverting to default");
+ }
+ }
+
+ public static Encryptor getInstance() {
+ return getInstance(secretKey);
+ }
+
+ public static Encryptor getInstance(final String secretKey) {
+ String actualKey = StringUtils.isBlank(secretKey) ? DEFAULT_SECRET_KEY : secretKey;
+
+ Encryptor instance = INSTANCES.get(actualKey);
+ if (instance == null) {
+ instance = new Encryptor(actualKey);
+ INSTANCES.put(actualKey, instance);
+ }
+
+ return instance;
+ }
+
+ private SecretKeySpec keySpec;
+
+ private Encryptor(final String secretKey) {
+ String actualKey = secretKey;
+ if (actualKey.length() < 16) {
+ StringBuilder actualKeyPadding = new StringBuilder(actualKey);
+ for (int i = 0; i < 16 - actualKey.length(); i++) {
+ actualKeyPadding.append('0');
+ }
+ actualKey = actualKeyPadding.toString();
+ LOG.debug("actualKey too short, adding some random characters");
+ }
+
+ try {
+ keySpec = new SecretKeySpec(ArrayUtils.subarray(
+ actualKey.getBytes(SyncopeConstants.DEFAULT_ENCODING), 0, 16),
+ CipherAlgorithm.AES.getAlgorithm());
+ } catch (Exception e) {
+ LOG.error("Error during key specification", e);
+ }
+ }
+
+ public String encode(final String value, final CipherAlgorithm cipherAlgorithm)
+ throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+ IllegalBlockSizeException, BadPaddingException {
+
+ String encodedValue = null;
+
+ if (value != null) {
+ if (cipherAlgorithm == null || cipherAlgorithm == CipherAlgorithm.AES) {
+ final byte[] cleartext = value.getBytes(SyncopeConstants.DEFAULT_ENCODING);
+
+ final Cipher cipher = Cipher.getInstance(CipherAlgorithm.AES.getAlgorithm());
+ cipher.init(Cipher.ENCRYPT_MODE, keySpec);
+
+ encodedValue = new String(Base64.encode(cipher.doFinal(cleartext)));
+ } else if (cipherAlgorithm == CipherAlgorithm.BCRYPT) {
+ encodedValue = BCrypt.hashpw(value, BCrypt.gensalt());
+ } else {
+ encodedValue = getDigester(cipherAlgorithm).digest(value);
+ }
+ }
+
+ return encodedValue;
+ }
+
+ public boolean verify(final String value, final CipherAlgorithm cipherAlgorithm, final String encodedValue) {
+ boolean res = false;
+
+ try {
+ if (value != null) {
+ if (cipherAlgorithm == null || cipherAlgorithm == CipherAlgorithm.AES) {
+ res = encode(value, cipherAlgorithm).equals(encodedValue);
+ } else if (cipherAlgorithm == CipherAlgorithm.BCRYPT) {
+ res = BCrypt.checkpw(value, encodedValue);
+ } else {
+ res = getDigester(cipherAlgorithm).matches(value, encodedValue);
+ }
+ }
+ } catch (Exception e) {
+ LOG.error("Could not verify encoded value", e);
+ }
+
+ return res;
+ }
+
+ public String decode(final String encodedValue, final CipherAlgorithm cipherAlgorithm)
+ throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+ IllegalBlockSizeException, BadPaddingException {
+
+ String value = null;
+
+ if (encodedValue != null && cipherAlgorithm == CipherAlgorithm.AES) {
+ final byte[] encoded = encodedValue.getBytes(SyncopeConstants.DEFAULT_ENCODING);
+
+ final Cipher cipher = Cipher.getInstance(CipherAlgorithm.AES.getAlgorithm());
+ cipher.init(Cipher.DECRYPT_MODE, keySpec);
+
+ value = new String(cipher.doFinal(Base64.decode(encoded)), SyncopeConstants.DEFAULT_ENCODING);
+ }
+
+ return value;
+ }
+
+ private StandardStringDigester getDigester(final CipherAlgorithm cipherAlgorithm) {
+ StandardStringDigester digester = new StandardStringDigester();
+
+ if (cipherAlgorithm.getAlgorithm().startsWith("S-")) {
+ // Salted ...
+ digester.setAlgorithm(cipherAlgorithm.getAlgorithm().replaceFirst("S\\-", ""));
+ digester.setIterations(saltIterations);
+ digester.setSaltSizeBytes(saltSizeBytes);
+ digester.setInvertPositionOfPlainSaltInEncryptionResults(ipopsier);
+ digester.setInvertPositionOfSaltInMessageBeforeDigesting(iposimbd);
+ digester.setUseLenientSaltSizeCheck(ulssc);
+ } else {
+ // Not salted ...
+ digester.setAlgorithm(cipherAlgorithm.getAlgorithm());
+ digester.setIterations(1);
+ digester.setSaltSizeBytes(0);
+ }
+
+ digester.setStringOutputType(CommonUtils.STRING_OUTPUT_TYPE_HEXADECIMAL);
+ return digester;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/security/src/main/java/org/apache/syncope/server/security/SecureRandomUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/security/src/main/java/org/apache/syncope/server/security/SecureRandomUtil.java b/syncope620/server/security/src/main/java/org/apache/syncope/server/security/SecureRandomUtil.java
new file mode 100644
index 0000000..3f2735a
--- /dev/null
+++ b/syncope620/server/security/src/main/java/org/apache/syncope/server/security/SecureRandomUtil.java
@@ -0,0 +1,44 @@
+/*
+ * 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.server.security;
+
+import java.security.SecureRandom;
+
+import org.apache.commons.lang3.RandomStringUtils;
+
+public class SecureRandomUtil {
+
+ private static final SecureRandom RANDOM = new SecureRandom();
+
+ public static String generateRandomPassword(final int tokenLength) {
+ return RandomStringUtils.random(tokenLength, 0, 0, true, false, null, RANDOM);
+ }
+
+ public static String generateRandomLetter() {
+ return RandomStringUtils.random(1, 0, 0, true, false, null, RANDOM);
+ }
+
+ public static String generateRandomNumber() {
+ return RandomStringUtils.random(1, 0, 0, false, true, null, RANDOM);
+ }
+
+ public static String generateRandomSpecialCharacter(char[] characters) {
+ return RandomStringUtils.random(1, 0, 0, false, false, characters, RANDOM);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/security/src/main/resources/security.properties
----------------------------------------------------------------------
diff --git a/syncope620/server/security/src/main/resources/security.properties b/syncope620/server/security/src/main/resources/security.properties
new file mode 100644
index 0000000..c0fcd37
--- /dev/null
+++ b/syncope620/server/security/src/main/resources/security.properties
@@ -0,0 +1,30 @@
+# 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.
+adminUser=admin
+adminPassword=5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
+adminPasswordAlgorithm=SHA1
+
+anonymousUser=${anonymousUser}
+anonymousKey=${anonymousKey}
+
+secretKey=${secretKey}
+# default for LDAP / RFC2307 SSHA
+digester.saltIterations=1
+digester.saltSizeBytes=8
+digester.invertPositionOfPlainSaltInEncryptionResults=true
+digester.invertPositionOfSaltInMessageBeforeDigesting=true
+digester.useLenientSaltSizeCheck=true
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/spring/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/spring/pom.xml b/syncope620/server/spring/pom.xml
new file mode 100644
index 0000000..ef9ae41
--- /dev/null
+++ b/syncope620/server/spring/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope</groupId>
+ <artifactId>syncope-server</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Server Spring Extensions</name>
+ <description>Apache Syncope Server Spring Extensions</description>
+ <groupId>org.apache.syncope.server</groupId>
+ <artifactId>syncope-server-spring</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/spring/src/main/java/org/apache/syncope/server/spring/ApplicationContextProvider.java
----------------------------------------------------------------------
diff --git a/syncope620/server/spring/src/main/java/org/apache/syncope/server/spring/ApplicationContextProvider.java b/syncope620/server/spring/src/main/java/org/apache/syncope/server/spring/ApplicationContextProvider.java
new file mode 100644
index 0000000..0ffba20
--- /dev/null
+++ b/syncope620/server/spring/src/main/java/org/apache/syncope/server/spring/ApplicationContextProvider.java
@@ -0,0 +1,47 @@
+/*
+ * 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.server.spring;
+
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+
+public class ApplicationContextProvider implements ApplicationContextAware {
+
+ private static ConfigurableApplicationContext ctx;
+
+ public static ConfigurableApplicationContext getApplicationContext() {
+ return ctx;
+ }
+
+ public static DefaultListableBeanFactory getBeanFactory() {
+ return (DefaultListableBeanFactory) ctx.getBeanFactory();
+ }
+
+ /**
+ * Wiring the ApplicationContext into a static method.
+ *
+ * @param ctx Spring application context
+ */
+ @Override
+ public void setApplicationContext(final ApplicationContext ctx) {
+ ApplicationContextProvider.ctx = (ConfigurableApplicationContext) ctx;
+ }
+}