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 2016/03/09 12:52:37 UTC
[01/17] syncope git commit: [SYNCOPE-701] Removing unwanted core/misc
dependency
Repository: syncope
Updated Branches:
refs/heads/master 8557d2acf -> 28569df55
[SYNCOPE-701] Removing unwanted core/misc dependency
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/0d09829e
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/0d09829e
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/0d09829e
Branch: refs/heads/master
Commit: 0d09829ed34b62b942ed68216e8b08ffd8861335
Parents: 8557d2a
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Mar 8 16:27:57 2016 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Mar 9 12:41:03 2016 +0100
----------------------------------------------------------------------
client/enduser/pom.xml | 9 +-------
.../enduser/SyncopeEnduserApplication.java | 24 ++++++++++----------
.../enduser/resources/AbstractBaseResource.java | 3 +++
.../client/enduser/resources/InfoResource.java | 5 ++--
.../client/enduser/resources/LoginResource.java | 9 ++------
.../enduser/resources/SchemaResource.java | 3 +--
.../resources/SecurityQuestionResource.java | 5 ++--
.../resources/SyncopeAnyClassTypeResource.java | 5 ++--
.../resources/SyncopeAnyTypeResource.java | 3 +--
.../enduser/resources/SyncopeGroupResource.java | 3 +--
.../resources/SyncopeResourceResource.java | 3 +--
.../resources/UserSelfCreateResource.java | 9 ++++----
.../enduser/resources/UserSelfReadResource.java | 3 +--
.../resources/UserSelfUpdateResource.java | 9 +++-----
14 files changed, 36 insertions(+), 57 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/pom.xml
----------------------------------------------------------------------
diff --git a/client/enduser/pom.xml b/client/enduser/pom.xml
index f6132cb..eca2124 100644
--- a/client/enduser/pom.xml
+++ b/client/enduser/pom.xml
@@ -38,13 +38,6 @@ under the License.
</properties>
<dependencies>
-
- <dependency>
- <groupId>org.apache.syncope.core</groupId>
- <artifactId>syncope-core-misc</artifactId>
- <version>${project.version}</version>
- </dependency>
-
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
@@ -175,7 +168,7 @@ under the License.
<groupId>org.webjars</groupId>
<artifactId>jquery-ui</artifactId>
</dependency>
-
+
<!--Logging-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
index 2c6f348..9a3e32e 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
@@ -52,7 +52,7 @@ import org.apache.wicket.request.Request;
import org.apache.wicket.request.Response;
import org.apache.wicket.request.resource.IResource;
import org.apache.wicket.request.resource.ResourceReference;
-import org.springframework.util.Assert;
+import org.apache.wicket.util.lang.Args;
public class SyncopeEnduserApplication extends WebApplication implements Serializable {
@@ -105,30 +105,30 @@ public class SyncopeEnduserApplication extends WebApplication implements Seriali
throw new WicketRuntimeException("Could not read " + ENDUSER_PROPERTIES, e);
}
version = props.getProperty("version");
- Assert.notNull(version, "<version> not set");
+ Args.notNull(version, "<version> not set");
site = props.getProperty("site");
- Assert.notNull(site, "<site> not set");
+ Args.notNull(site, "<site> not set");
license = props.getProperty("license");
- Assert.notNull(license, "<license> not set");
+ Args.notNull(license, "<license> not set");
anonymousUser = props.getProperty("anonymousUser");
- Assert.notNull(anonymousUser, "<anonymousUser> not set");
+ Args.notNull(anonymousUser, "<anonymousUser> not set");
anonymousKey = props.getProperty("anonymousKey");
- Assert.notNull(anonymousKey, "<anonymousKey> not set");
+ Args.notNull(anonymousKey, "<anonymousKey> not set");
captchaEnabled = Boolean.parseBoolean(props.getProperty("captcha"));
- Assert.notNull(captchaEnabled, "<captcha> not set");
+ Args.notNull(captchaEnabled, "<captcha> not set");
xsrfEnabled = Boolean.parseBoolean(props.getProperty("xsrf"));
- Assert.notNull(xsrfEnabled, "<xsrf> not set");
+ Args.notNull(xsrfEnabled, "<xsrf> not set");
String scheme = props.getProperty("scheme");
- Assert.notNull(scheme, "<scheme> not set");
+ Args.notNull(scheme, "<scheme> not set");
String host = props.getProperty("host");
- Assert.notNull(host, "<host> not set");
+ Args.notNull(host, "<host> not set");
String port = props.getProperty("port");
- Assert.notNull(port, "<port> not set");
+ Args.notNull(port, "<port> not set");
String rootPath = props.getProperty("rootPath");
- Assert.notNull(rootPath, "<rootPath> not set");
+ Args.notNull(rootPath, "<rootPath> not set");
clientFactory = new SyncopeClientFactoryBean().setAddress(scheme + "://" + host + ":" + port + "/" + rootPath);
clientFactory.setContentType(SyncopeClientFactoryBean.ContentType.JSON);
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java
index 6c402db..a5ebe63 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.client.enduser.resources;
+import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.enduser.SyncopeEnduserApplication;
@@ -34,6 +35,8 @@ public abstract class AbstractBaseResource extends AbstractResource {
private static final Logger LOG = LoggerFactory.getLogger(AbstractBaseResource.class);
+ protected static final ObjectMapper MAPPER = new ObjectMapper();
+
protected final boolean isSelfRegistrationAllowed() {
Boolean result = null;
try {
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
index acfbac9..8b36907 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
@@ -25,7 +25,6 @@ import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
import org.apache.syncope.client.enduser.adapters.PlatformInfoAdapter;
import org.apache.syncope.client.enduser.util.SaltGenerator;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.apache.wicket.request.resource.IResource;
import org.apache.wicket.util.cookies.CookieUtils;
import org.slf4j.Logger;
@@ -57,9 +56,9 @@ public class InfoResource extends AbstractBaseResource {
@Override
public void writeData(final IResource.Attributes attributes) throws IOException {
attributes.getResponse().write(
- POJOHelper.serialize(
+ MAPPER.writeValueAsString(
PlatformInfoAdapter.toPlatformInfoRequest(
- SyncopeEnduserSession.get().getPlatformInfo())));
+ SyncopeEnduserSession.get().getPlatformInfo())));
}
});
response.setStatusCode(Response.Status.OK.getStatusCode());
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
index 28d19a3..db99669 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
@@ -24,7 +24,6 @@ import javax.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.enduser.model.Credentials;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.request.resource.IResource;
import org.apache.wicket.util.io.IOUtils;
@@ -37,12 +36,8 @@ public class LoginResource extends AbstractBaseResource {
private static final Logger LOG = LoggerFactory.getLogger(LoginResource.class);
- public LoginResource() {
- }
-
@Override
protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-
AbstractResource.ResourceResponse response = new AbstractResource.ResourceResponse();
try {
@@ -54,8 +49,8 @@ public class LoginResource extends AbstractBaseResource {
return response;
}
- Credentials credentials = POJOHelper.deserialize(IOUtils.toString(request.getInputStream()),
- Credentials.class);
+ Credentials credentials = MAPPER.readValue(
+ IOUtils.toString(request.getInputStream()), Credentials.class);
final String username = credentials.getUsername();
final String password = credentials.getPassword().isEmpty() ? null : credentials.getPassword();
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
index 4783b79..3b32d05 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
@@ -34,7 +34,6 @@ import org.apache.syncope.common.lib.types.SchemaType;
import org.apache.syncope.common.rest.api.beans.SchemaQuery;
import org.apache.syncope.common.rest.api.service.AnyTypeService;
import org.apache.syncope.common.rest.api.service.SchemaService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.request.resource.IResource;
import org.slf4j.Logger;
@@ -94,7 +93,7 @@ public class SchemaResource extends AbstractBaseResource {
@Override
public void writeData(final IResource.Attributes attributes) throws IOException {
- attributes.getResponse().write(POJOHelper.serialize(new SchemaResponse().
+ attributes.getResponse().write(MAPPER.writeValueAsString(new SchemaResponse().
plainSchemas(plainSchemas).
derSchemas(derSchemas).
virSchemas(virSchemas)));
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
index 7e79b1b..0893c22 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
@@ -25,7 +25,6 @@ import javax.ws.rs.core.Response;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
import org.apache.syncope.common.lib.to.SecurityQuestionTO;
import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.request.resource.IResource;
@@ -72,7 +71,7 @@ public class SecurityQuestionResource extends AbstractBaseResource {
@Override
public void writeData(final IResource.Attributes attributes) throws IOException {
- attributes.getResponse().write(POJOHelper.serialize(securityQuestionTO));
+ attributes.getResponse().write(MAPPER.writeValueAsString(securityQuestionTO));
}
});
} else {
@@ -82,7 +81,7 @@ public class SecurityQuestionResource extends AbstractBaseResource {
@Override
public void writeData(final IResource.Attributes attributes) throws IOException {
- attributes.getResponse().write(POJOHelper.serialize(securityQuestionTOs));
+ attributes.getResponse().write(MAPPER.writeValueAsString(securityQuestionTOs));
}
});
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java
index 2528150..bdb6f98 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java
@@ -25,7 +25,6 @@ import javax.ws.rs.core.Response;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
import org.apache.syncope.common.lib.to.AnyTypeClassTO;
import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.apache.wicket.request.resource.AbstractResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,7 +37,7 @@ public class SyncopeAnyClassTypeResource extends AbstractBaseResource {
private final AnyTypeClassService anyTypeClassService;
- public SyncopeAnyClassTypeResource() {
+ public SyncopeAnyClassTypeResource() {
anyTypeClassService = SyncopeEnduserSession.get().getService(AnyTypeClassService.class);
}
@@ -64,7 +63,7 @@ public class SyncopeAnyClassTypeResource extends AbstractBaseResource {
@Override
public void writeData(final Attributes attributes) throws IOException {
- attributes.getResponse().write(POJOHelper.serialize(anyTypeClassTOs));
+ attributes.getResponse().write(MAPPER.writeValueAsString(anyTypeClassTOs));
}
});
response.setStatusCode(Response.Status.OK.getStatusCode());
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java
index 7d2bcde..9c9b1ad 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java
@@ -24,7 +24,6 @@ import javax.ws.rs.core.Response;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
import org.apache.syncope.common.lib.to.AnyTypeTO;
import org.apache.syncope.common.rest.api.service.AnyTypeService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.apache.wicket.request.resource.AbstractResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -64,7 +63,7 @@ public class SyncopeAnyTypeResource extends AbstractBaseResource {
@Override
public void writeData(final Attributes attributes) throws IOException {
- attributes.getResponse().write(POJOHelper.serialize(anyTypeTO));
+ attributes.getResponse().write(MAPPER.writeValueAsString(anyTypeTO));
}
});
response.setStatusCode(Response.Status.OK.getStatusCode());
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeGroupResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeGroupResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeGroupResource.java
index 8ae82ce..09e3b85 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeGroupResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeGroupResource.java
@@ -27,7 +27,6 @@ import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.common.rest.api.beans.AnyListQuery;
import org.apache.syncope.common.rest.api.service.GroupService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.apache.wicket.request.resource.AbstractResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -69,7 +68,7 @@ public class SyncopeGroupResource extends AbstractBaseResource {
@Override
public void writeData(final Attributes attributes) throws IOException {
- attributes.getResponse().write(POJOHelper.serialize(groupTOs));
+ attributes.getResponse().write(MAPPER.writeValueAsString(groupTOs));
}
});
response.setStatusCode(Response.Status.OK.getStatusCode());
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeResourceResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeResourceResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeResourceResource.java
index 8d08ac2..8a6d0a9 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeResourceResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeResourceResource.java
@@ -25,7 +25,6 @@ import javax.ws.rs.core.Response;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.rest.api.service.ResourceService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.request.resource.IResource;
import org.slf4j.Logger;
@@ -65,7 +64,7 @@ public class SyncopeResourceResource extends AbstractBaseResource {
@Override
public void writeData(final IResource.Attributes attributes) throws IOException {
- attributes.getResponse().write(POJOHelper.serialize(resourceTOs));
+ attributes.getResponse().write(MAPPER.writeValueAsString(resourceTOs));
}
});
response.setStatusCode(Response.Status.OK.getStatusCode());
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
index 88059d6..4ab2ca5 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
@@ -25,7 +25,6 @@ import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.rest.api.service.UserSelfService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,7 +57,7 @@ public class UserSelfCreateResource extends AbstractBaseResource {
String jsonString = request.getReader().readLine();
- final UserTO userTO = POJOHelper.deserialize(jsonString, UserTO.class);
+ final UserTO userTO = MAPPER.readValue(jsonString, UserTO.class);
if (!captchaCheck(request.getHeader("captcha"), request.getSession().getAttribute(
SyncopeEnduserConstants.CAPTCHA_SESSION_KEY).toString())) {
@@ -79,7 +78,7 @@ public class UserSelfCreateResource extends AbstractBaseResource {
attributes.getResponse().write(res.getStatusInfo().getFamily().equals(
Response.Status.Family.SUCCESSFUL)
? responseMessage.append("User: ").append(userTO.getUsername()).append(
- " successfully created")
+ " successfully created")
: new StringBuilder().append("ErrorMessage{{ ").
append(res.getStatusInfo().getReasonPhrase()).append(" }}"));
}
@@ -88,8 +87,8 @@ public class UserSelfCreateResource extends AbstractBaseResource {
} else {
response.setError(Response.Status.FORBIDDEN.getStatusCode(), new StringBuilder().
append("ErrorMessage{{").append(userTO == null
- ? "Request received is not valid }}"
- : "Self registration not allowed }}").toString());
+ ? "Request received is not valid }}"
+ : "Self registration not allowed }}").toString());
}
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
index 2cca020..2411adf 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
@@ -22,7 +22,6 @@ import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Response;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.request.resource.IResource;
import org.slf4j.Logger;
@@ -56,7 +55,7 @@ public class UserSelfReadResource extends AbstractBaseResource {
return response;
}
- final String selfTOJson = POJOHelper.serialize(SyncopeEnduserSession.get().getSelfTO());
+ final String selfTOJson = MAPPER.writeValueAsString(SyncopeEnduserSession.get().getSelfTO());
response.setWriteCallback(new WriteCallback() {
http://git-wip-us.apache.org/repos/asf/syncope/blob/0d09829e/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
index d913e6e..8e2c148 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
@@ -25,7 +25,6 @@ import org.apache.syncope.client.enduser.SyncopeEnduserConstants;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.rest.api.service.UserSelfService;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.request.resource.IResource;
import org.slf4j.Logger;
@@ -39,14 +38,12 @@ public class UserSelfUpdateResource extends AbstractBaseResource {
private final UserSelfService userSelfService;
-
public UserSelfUpdateResource() {
userSelfService = SyncopeEnduserSession.get().getService(UserSelfService.class);
}
@Override
protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
-
AbstractResource.ResourceResponse response = new AbstractResource.ResourceResponse();
try {
@@ -59,14 +56,14 @@ public class UserSelfUpdateResource extends AbstractBaseResource {
String jsonString = request.getReader().readLine();
- final UserTO userTO = POJOHelper.deserialize(jsonString, UserTO.class);
+ final UserTO userTO = MAPPER.readValue(jsonString, UserTO.class);
if (!captchaCheck(request.getHeader("captcha"), request.getSession().getAttribute(
SyncopeEnduserConstants.CAPTCHA_SESSION_KEY).toString())) {
LOG.error("Entered captcha is not matching");
throw new Exception("Entered captcha is not matching");
}
-
+
LOG.debug("User {} id updating himself", userTO.getUsername());
// update user
@@ -74,7 +71,7 @@ public class UserSelfUpdateResource extends AbstractBaseResource {
final String responseMessage = res.getStatusInfo().getFamily().equals(Response.Status.Family.SUCCESSFUL)
? new StringBuilder().append("User").append(userTO.getUsername()).append(
- " successfully updated").toString()
+ " successfully updated").toString()
: new StringBuilder().append("ErrorMessage{{ ").
append(res.getStatusInfo().getReasonPhrase()).append(" }}").toString();
[16/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
deleted file mode 100644
index 9c64734..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/JexlUtils.java
+++ /dev/null
@@ -1,241 +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.core.misc.jexl;
-
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Field;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.jexl3.JexlBuilder;
-import org.apache.commons.jexl3.JexlContext;
-import org.apache.commons.jexl3.JexlEngine;
-import org.apache.commons.jexl3.JexlException;
-import org.apache.commons.jexl3.JexlExpression;
-import org.apache.commons.jexl3.JxltEngine;
-import org.apache.commons.jexl3.MapContext;
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.utils.FormatUtils;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.provisioning.api.DerAttrHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * JEXL <a href="http://commons.apache.org/jexl/reference/index.html">reference</a> is available.
- */
-public final class JexlUtils {
-
- private static final Logger LOG = LoggerFactory.getLogger(JexlUtils.class);
-
- private static final String[] IGNORE_FIELDS = { "password", "clearPassword", "serialVersionUID", "class" };
-
- private static JexlEngine JEXL_ENGINE;
-
- private static JexlEngine getEngine() {
- synchronized (LOG) {
- if (JEXL_ENGINE == null) {
- JEXL_ENGINE = new JexlBuilder().
- uberspect(new ClassFreeUberspect()).
- loader(new EmptyClassLoader()).
- cache(512).
- silent(false).
- strict(false).
- create();
- }
- }
-
- return JEXL_ENGINE;
- }
-
- public static JxltEngine newJxltEngine() {
- return getEngine().createJxltEngine(false);
- }
-
- public static boolean isExpressionValid(final String expression) {
- boolean result;
- try {
- getEngine().createExpression(expression);
- result = true;
- } catch (JexlException e) {
- LOG.error("Invalid jexl expression: " + expression, e);
- result = false;
- }
-
- return result;
- }
-
- public static String evaluate(final String expression, final JexlContext jexlContext) {
- String result = StringUtils.EMPTY;
-
- if (StringUtils.isNotBlank(expression) && jexlContext != null) {
- try {
- JexlExpression jexlExpression = getEngine().createExpression(expression);
- Object evaluated = jexlExpression.evaluate(jexlContext);
- if (evaluated != null) {
- result = evaluated.toString();
- }
- } catch (Exception e) {
- LOG.error("Error while evaluating JEXL expression: " + expression, e);
- }
- } else {
- LOG.debug("Expression not provided or invalid context");
- }
-
- return result;
- }
-
- public static JexlContext addFieldsToContext(final Object object, final JexlContext jexlContext) {
- JexlContext context = jexlContext == null ? new MapContext() : jexlContext;
-
- try {
- for (PropertyDescriptor desc : Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors()) {
- Class<?> type = desc.getPropertyType();
- String fieldName = desc.getName();
-
- if ((!fieldName.startsWith("pc"))
- && (!ArrayUtils.contains(IGNORE_FIELDS, fieldName))
- && (!Iterable.class.isAssignableFrom(type))
- && (!type.isArray())) {
-
- try {
- Object fieldValue;
- if (desc.getReadMethod() == null) {
- final Field field = object.getClass().getDeclaredField(fieldName);
- field.setAccessible(true);
- fieldValue = field.get(object);
- } else {
- fieldValue = desc.getReadMethod().invoke(object);
- }
-
- context.set(fieldName, fieldValue == null
- ? StringUtils.EMPTY
- : (type.equals(Date.class)
- ? FormatUtils.format((Date) fieldValue, false)
- : fieldValue));
-
- LOG.debug("Add field {} with value {}", fieldName, fieldValue);
- } catch (Exception iae) {
- LOG.error("Reading '{}' value error", fieldName, iae);
- }
- }
- }
- } catch (IntrospectionException ie) {
- LOG.error("Reading class attributes error", ie);
- }
-
- if (object instanceof Any) {
- Any<?> any = (Any<?>) object;
- if (any.getRealm() != null) {
- context.set("realm", any.getRealm().getName());
- }
- }
-
- return context;
- }
-
- public static void addPlainAttrsToContext(
- final Collection<? extends PlainAttr<?>> attrs, final JexlContext jexlContext) {
-
- for (PlainAttr<?> attr : attrs) {
- if (attr.getSchema() != null) {
- List<String> attrValues = attr.getValuesAsStrings();
- String expressionValue = attrValues.isEmpty()
- ? StringUtils.EMPTY
- : attrValues.get(0);
-
- LOG.debug("Add attribute {} with value {}", attr.getSchema().getKey(), expressionValue);
-
- jexlContext.set(attr.getSchema().getKey(), expressionValue);
- }
- }
- }
-
- public static void addDerAttrsToContext(final Any<?> any, final JexlContext jexlContext) {
- Map<DerSchema, String> derAttrs =
- ApplicationContextProvider.getBeanFactory().getBean(DerAttrHandler.class).getValues(any);
-
- for (Map.Entry<DerSchema, String> entry : derAttrs.entrySet()) {
- jexlContext.set(entry.getKey().getKey(), entry.getValue());
- }
- }
-
- public static boolean evaluateMandatoryCondition(final String mandatoryCondition, final Any<?> any) {
- JexlContext jexlContext = new MapContext();
- addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
- addDerAttrsToContext(any, jexlContext);
-
- return Boolean.parseBoolean(evaluate(mandatoryCondition, jexlContext));
- }
-
- public static String evaluate(final String expression, final AnyTO anyTO) {
- final JexlContext context = new MapContext();
-
- addFieldsToContext(anyTO, context);
-
- for (AttrTO plainAttr : anyTO.getPlainAttrs()) {
- List<String> values = plainAttr.getValues();
- String expressionValue = values.isEmpty()
- ? StringUtils.EMPTY
- : values.get(0);
-
- LOG.debug("Add plain attribute {} with value {}", plainAttr.getSchema(), expressionValue);
-
- context.set(plainAttr.getSchema(), expressionValue);
- }
- for (AttrTO derAttr : anyTO.getDerAttrs()) {
- List<String> values = derAttr.getValues();
- String expressionValue = values.isEmpty()
- ? StringUtils.EMPTY
- : values.get(0);
-
- LOG.debug("Add derived attribute {} with value {}", derAttr.getSchema(), expressionValue);
-
- context.set(derAttr.getSchema(), expressionValue);
- }
- for (AttrTO virAttr : anyTO.getVirAttrs()) {
- List<String> values = virAttr.getValues();
- String expressionValue = values.isEmpty()
- ? StringUtils.EMPTY
- : values.get(0);
-
- LOG.debug("Add virtual attribute {} with value {}", virAttr.getSchema(), expressionValue);
-
- context.set(virAttr.getSchema(), expressionValue);
- }
-
- // Evaluate expression using the context prepared before
- return evaluate(expression, context);
- }
-
- /**
- * Private default constructor, for static-only classes.
- */
- private JexlUtils() {
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyException.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyException.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyException.java
deleted file mode 100644
index 0d3eff7..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyException.java
+++ /dev/null
@@ -1,32 +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.core.misc.policy;
-
-public class AccountPolicyException extends PolicyException {
-
- private static final long serialVersionUID = 2779416455067691813L;
-
- public AccountPolicyException() {
- super();
- }
-
- public AccountPolicyException(final String message) {
- super(message);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/policy/InvalidPasswordRuleConf.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/InvalidPasswordRuleConf.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/InvalidPasswordRuleConf.java
deleted file mode 100644
index 4b13807..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/InvalidPasswordRuleConf.java
+++ /dev/null
@@ -1,37 +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.core.misc.policy;
-
-/**
- * Raise when the merge of two or more PasswordRuleconf instances led to an inconsistent condition.
- *
- * @see org.apache.syncope.common.lib.policy.PasswordRuleConf
- */
-public class InvalidPasswordRuleConf extends Exception {
-
- private static final long serialVersionUID = 4810651743226663580L;
-
- public InvalidPasswordRuleConf(final String msg) {
- super(msg);
- }
-
- public InvalidPasswordRuleConf(final String msg, final Exception e) {
- super(msg, e);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyException.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyException.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyException.java
deleted file mode 100644
index 7bf530b..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyException.java
+++ /dev/null
@@ -1,32 +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.core.misc.policy;
-
-public class PasswordPolicyException extends PolicyException {
-
- private static final long serialVersionUID = 8072104484395278469L;
-
- public PasswordPolicyException() {
- super();
- }
-
- public PasswordPolicyException(final String message) {
- super(message);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyException.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyException.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyException.java
deleted file mode 100644
index 5a2ef36..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyException.java
+++ /dev/null
@@ -1,32 +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.core.misc.policy;
-
-public class PolicyException extends RuntimeException {
-
- private static final long serialVersionUID = -6082115004491662910L;
-
- public PolicyException() {
- super();
- }
-
- public PolicyException(final String message) {
- super(message);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyPattern.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyPattern.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyPattern.java
deleted file mode 100644
index ecb4e6c..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PolicyPattern.java
+++ /dev/null
@@ -1,50 +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.core.misc.policy;
-
-import java.util.regex.Pattern;
-
-public final class PolicyPattern {
-
- public static final Pattern DIGIT = Pattern.compile(".*\\d+.*");
-
- public static final Pattern ALPHA_LOWERCASE = Pattern.compile(".*[a-z]+.*");
-
- public static final Pattern ALPHA_UPPERCASE = Pattern.compile(".*[A-Z]+.*");
-
- public static final Pattern FIRST_DIGIT = Pattern.compile("\\d.*");
-
- public static final Pattern LAST_DIGIT = Pattern.compile(".*\\d");
-
- public static final Pattern ALPHANUMERIC = Pattern.compile(".*\\w.*");
-
- public static final Pattern FIRST_ALPHANUMERIC = Pattern.compile("\\w.*");
-
- public static final Pattern LAST_ALPHANUMERIC = Pattern.compile(".*\\w");
-
- public static final Pattern NON_ALPHANUMERIC = Pattern.compile(".*\\W.*");
-
- public static final Pattern FIRST_NON_ALPHANUMERIC = Pattern.compile("\\W.*");
-
- public static final Pattern LAST_NON_ALPHANUMERIC = Pattern.compile(".*\\W");
-
- private PolicyPattern() {
- // private constructor for static utility class
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.java b/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.java
deleted file mode 100644
index 77b959b..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondConverter.java
+++ /dev/null
@@ -1,64 +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.core.misc.search;
-
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.cxf.jaxrs.ext.search.SearchBean;
-import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.search.AbstractFiqlSearchConditionBuilder;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-
-/**
- * Converts FIQL expressions to Syncope's {@link SearchCond}.
- */
-public final class SearchCondConverter {
-
- /**
- * Parses a FIQL expression into Syncope's <tt>SearchCond</tt>, using CXF's <tt>FiqlParser</tt>.
- *
- * @param fiqlExpression FIQL string
- * @param realms optional realm to provide to {@link SearchCondVisitor}
- * @return {@link SearchCond} instance for given FIQL expression
- * @see FiqlParser
- */
- public static SearchCond convert(final String fiqlExpression, final String... realms) {
- FiqlParser<SearchBean> fiqlParser = new FiqlParser<>(
- SearchBean.class, AbstractFiqlSearchConditionBuilder.CONTEXTUAL_PROPERTIES);
-
- try {
- SearchCondVisitor searchCondVisitor = new SearchCondVisitor();
- if (realms != null && realms.length > 0) {
- searchCondVisitor.setRealm(realms[0]);
- }
- searchCondVisitor.visit(fiqlParser.parse(fiqlExpression));
- return searchCondVisitor.getQuery();
- } catch (Exception e) {
- SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression);
- sce.getElements().add(fiqlExpression);
- sce.getElements().add(ExceptionUtils.getRootCauseMessage(e));
- throw sce;
- }
- }
-
- private SearchCondConverter() {
- // empty constructor for static utility class
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
deleted file mode 100644
index 2e281cf..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
+++ /dev/null
@@ -1,222 +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.core.misc.search;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.cxf.jaxrs.ext.search.ConditionType;
-import org.apache.cxf.jaxrs.ext.search.SearchBean;
-import org.apache.cxf.jaxrs.ext.search.SearchCondition;
-import org.apache.cxf.jaxrs.ext.search.SearchUtils;
-import org.apache.cxf.jaxrs.ext.search.visitor.AbstractSearchConditionVisitor;
-import org.apache.syncope.common.lib.EntityTOUtils;
-import org.apache.syncope.common.lib.search.SpecialAttr;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
-import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
-import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
-import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
-import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
-import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
-import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
-
-/**
- * Converts CXF's <tt>SearchCondition</tt> into internal <tt>SearchCond</tt>.
- */
-public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean, SearchCond> {
-
- private String realm;
-
- private SearchCond searchCond;
-
- public SearchCondVisitor() {
- super(null);
- }
-
- public void setRealm(final String realm) {
- this.realm = realm;
- }
-
- private AttributeCond createAttributeCond(final String schema) {
- AttributeCond attributeCond = EntityTOUtils.ANY_FIELDS.contains(schema)
- ? new AnyCond()
- : new AttributeCond();
- attributeCond.setSchema(schema);
- return attributeCond;
- }
-
- private SearchCond visitPrimitive(final SearchCondition<SearchBean> sc) {
- String name = getRealPropertyName(sc.getStatement().getProperty());
- SpecialAttr specialAttrName = SpecialAttr.fromString(name);
-
- String value = SearchUtils.toSqlWildcardString(sc.getStatement().getValue().toString(), false).
- replaceAll("\\\\_", "_");
- SpecialAttr specialAttrValue = SpecialAttr.fromString(value);
-
- AttributeCond attributeCond = createAttributeCond(name);
- attributeCond.setExpression(value);
-
- SearchCond leaf;
- switch (sc.getConditionType()) {
- case EQUALS:
- case NOT_EQUALS:
- if (specialAttrName == null) {
- if (specialAttrValue != null && specialAttrValue == SpecialAttr.NULL) {
- attributeCond.setType(AttributeCond.Type.ISNULL);
- attributeCond.setExpression(null);
- } else if (value.indexOf('%') == -1) {
- attributeCond.setType(AttributeCond.Type.EQ);
- } else {
- attributeCond.setType(AttributeCond.Type.LIKE);
- }
-
- leaf = SearchCond.getLeafCond(attributeCond);
- } else {
- switch (specialAttrName) {
- case TYPE:
- AnyTypeCond typeCond = new AnyTypeCond();
- typeCond.setAnyTypeName(value);
- leaf = SearchCond.getLeafCond(typeCond);
- break;
-
- case RESOURCES:
- ResourceCond resourceCond = new ResourceCond();
- resourceCond.setResourceName(value);
- leaf = SearchCond.getLeafCond(resourceCond);
- break;
-
- case GROUPS:
- MembershipCond groupCond = new MembershipCond();
- groupCond.setGroupKey(Long.valueOf(value));
- leaf = SearchCond.getLeafCond(groupCond);
- break;
-
- case RELATIONSHIPS:
- RelationshipCond relationshipCond = new RelationshipCond();
- relationshipCond.setAnyObjectKey(Long.valueOf(value));
- leaf = SearchCond.getLeafCond(relationshipCond);
- break;
-
- case RELATIONSHIP_TYPES:
- RelationshipTypeCond relationshipTypeCond = new RelationshipTypeCond();
- relationshipTypeCond.setRelationshipTypeKey(value);
- leaf = SearchCond.getLeafCond(relationshipTypeCond);
- break;
-
- case ROLES:
- RoleCond roleCond = new RoleCond();
- roleCond.setRoleKey(value);
- leaf = SearchCond.getLeafCond(roleCond);
- break;
-
- case ASSIGNABLE:
- AssignableCond assignableCond = new AssignableCond();
- assignableCond.setRealmFullPath(realm);
- leaf = SearchCond.getLeafCond(assignableCond);
- break;
-
- default:
- throw new IllegalArgumentException(
- String.format("Special attr name %s is not supported", specialAttrName));
- }
- }
- if (sc.getConditionType() == ConditionType.NOT_EQUALS) {
- if (leaf.getAttributeCond() != null
- && leaf.getAttributeCond().getType() == AttributeCond.Type.ISNULL) {
-
- leaf.getAttributeCond().setType(AttributeCond.Type.ISNOTNULL);
- } else if (leaf.getAnyCond() != null
- && leaf.getAnyCond().getType() == AnyCond.Type.ISNULL) {
-
- leaf.getAnyCond().setType(AttributeCond.Type.ISNOTNULL);
- } else {
- leaf = SearchCond.getNotLeafCond(leaf);
- }
- }
- break;
-
- case GREATER_OR_EQUALS:
- attributeCond.setType(AttributeCond.Type.GE);
- leaf = SearchCond.getLeafCond(attributeCond);
- break;
-
- case GREATER_THAN:
- attributeCond.setType(AttributeCond.Type.GT);
- leaf = SearchCond.getLeafCond(attributeCond);
- break;
-
- case LESS_OR_EQUALS:
- attributeCond.setType(AttributeCond.Type.LE);
- leaf = SearchCond.getLeafCond(attributeCond);
- break;
-
- case LESS_THAN:
- attributeCond.setType(AttributeCond.Type.LT);
- leaf = SearchCond.getLeafCond(attributeCond);
- break;
-
- default:
- throw new IllegalArgumentException(
- String.format("Condition type %s is not supported", sc.getConditionType().name()));
- }
-
- return leaf;
- }
-
- private SearchCond visitCompount(final SearchCondition<SearchBean> sc) {
- List<SearchCond> searchConds = new ArrayList<>();
- for (SearchCondition<SearchBean> searchCondition : sc.getSearchConditions()) {
- searchConds.add(searchCondition.getStatement() == null
- ? visitCompount(searchCondition)
- : visitPrimitive(searchCondition));
- }
-
- SearchCond compound;
- switch (sc.getConditionType()) {
- case AND:
- compound = SearchCond.getAndCond(searchConds);
- break;
-
- case OR:
- compound = SearchCond.getOrCond(searchConds);
- break;
-
- default:
- throw new IllegalArgumentException(
- String.format("Condition type %s is not supported", sc.getConditionType().name()));
- }
-
- return compound;
- }
-
- @Override
- public void visit(final SearchCondition<SearchBean> sc) {
- searchCond = sc.getStatement() == null
- ? visitCompount(sc)
- : visitPrimitive(sc);
- }
-
- @Override
- public SearchCond getQuery() {
- return searchCond;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
deleted file mode 100644
index e7b9fc0..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthContextUtils.java
+++ /dev/null
@@ -1,126 +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.core.misc.security;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.MapUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.core.misc.EntitlementsHolder;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-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;
-import org.springframework.security.core.userdetails.User;
-
-public final class AuthContextUtils {
-
- public interface Executable<T> {
-
- T exec();
- }
-
- public static String getUsername() {
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- return authentication == null ? SyncopeConstants.UNAUTHENTICATED : authentication.getName();
- }
-
- public static void updateUsername(final String newUsername) {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
-
- UsernamePasswordAuthenticationToken newAuth = new UsernamePasswordAuthenticationToken(
- new User(newUsername, "FAKE_PASSWORD", auth.getAuthorities()),
- auth.getCredentials(), auth.getAuthorities());
- newAuth.setDetails(auth.getDetails());
- SecurityContextHolder.getContext().setAuthentication(newAuth);
- }
-
- public static Map<String, Set<String>> getAuthorizations() {
- Map<String, Set<String>> result = null;
-
- SecurityContext ctx = SecurityContextHolder.getContext();
- if (ctx != null && ctx.getAuthentication() != null && ctx.getAuthentication().getAuthorities() != null) {
- result = new HashMap<>();
- for (GrantedAuthority authority : ctx.getAuthentication().getAuthorities()) {
- if (authority instanceof SyncopeGrantedAuthority) {
- result.put(
- SyncopeGrantedAuthority.class.cast(authority).getAuthority(),
- SyncopeGrantedAuthority.class.cast(authority).getRealms());
- }
- }
- }
-
- return MapUtils.emptyIfNull(result);
- }
-
- public static String getDomain() {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
-
- String domainKey = auth != null && auth.getDetails() instanceof SyncopeAuthenticationDetails
- ? SyncopeAuthenticationDetails.class.cast(auth.getDetails()).getDomain()
- : null;
- if (StringUtils.isBlank(domainKey)) {
- domainKey = SyncopeConstants.MASTER_DOMAIN;
- }
-
- return domainKey;
- }
-
- private static void setFakeAuth(final String domain) {
- List<GrantedAuthority> authorities = CollectionUtils.collect(EntitlementsHolder.getInstance().getValues(),
- new Transformer<String, GrantedAuthority>() {
-
- @Override
- public GrantedAuthority transform(final String entitlement) {
- return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
- }
- }, new ArrayList<GrantedAuthority>());
-
- UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
- new User(ApplicationContextProvider.getBeanFactory().getBean("adminUser", String.class),
- "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
- auth.setDetails(new SyncopeAuthenticationDetails(domain));
- SecurityContextHolder.getContext().setAuthentication(auth);
- }
-
- public static <T> T execWithAuthContext(final String domainKey, final Executable<T> executable) {
- SecurityContext ctx = SecurityContextHolder.getContext();
- setFakeAuth(domainKey);
- try {
- return executable.exec();
- } finally {
- SecurityContextHolder.clearContext();
- SecurityContextHolder.setContext(ctx);
- }
- }
-
- /**
- * Private default constructor, for static-only classes.
- */
- private AuthContextUtils() {
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
deleted file mode 100644
index 7e880b4..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/AuthDataAccessor.java
+++ /dev/null
@@ -1,318 +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.core.misc.security;
-
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.Resource;
-import org.apache.commons.collections4.Closure;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.SetUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.EntitlementsHolder;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.misc.utils.RealmUtils;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.ConfDAO;
-import org.apache.syncope.core.persistence.api.dao.DomainDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Domain;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.Role;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
-import org.identityconnectors.framework.common.objects.Uid;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.authentication.AuthenticationServiceException;
-import org.springframework.security.authentication.DisabledException;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * Domain-sensible (via {@code @Transactional} access to authentication / authorization data.
- *
- * @see SyncopeAuthenticationProvider
- * @see SyncopeAuthenticationDetails
- */
-public class AuthDataAccessor {
-
- protected static final Logger LOG = LoggerFactory.getLogger(AuthDataAccessor.class);
-
- protected static final Encryptor ENCRYPTOR = Encryptor.getInstance();
-
- @Resource(name = "adminUser")
- protected String adminUser;
-
- @Resource(name = "anonymousUser")
- protected String anonymousUser;
-
- @Autowired
- protected DomainDAO domainDAO;
-
- @Autowired
- protected ConfDAO confDAO;
-
- @Autowired
- protected RealmDAO realmDAO;
-
- @Autowired
- protected UserDAO userDAO;
-
- @Autowired
- protected GroupDAO groupDAO;
-
- @Autowired
- protected AnyTypeDAO anyTypeDAO;
-
- @Autowired
- protected ConnectorFactory connFactory;
-
- @Autowired
- protected AuditManager auditManager;
-
- @Autowired
- protected MappingUtils mappingUtils;
-
- @Transactional(readOnly = true)
- public Domain findDomain(final String key) {
- Domain domain = domainDAO.find(key);
- if (domain == null) {
- throw new AuthenticationServiceException("Could not find domain " + key);
- }
- return domain;
- }
-
- /**
- * Attempts to authenticate the given credentials against internal storage and pass-through resources (if
- * configured): the first succeeding causes global success.
- *
- * @param authentication given credentials
- * @return {@code null} if no matching user was found, authentication result otherwise
- */
- @Transactional(noRollbackFor = DisabledException.class)
- public Pair<Long, Boolean> authenticate(final Authentication authentication) {
- Long key = null;
- Boolean authenticated = null;
-
- User user = userDAO.find(authentication.getName());
- if (user != null) {
- key = user.getKey();
- authenticated = false;
-
- if (user.isSuspended() != null && user.isSuspended()) {
- throw new DisabledException("User " + user.getUsername() + " is suspended");
- }
-
- CPlainAttr authStatuses = confDAO.find("authentication.statuses");
- if (authStatuses != null && !authStatuses.getValuesAsStrings().contains(user.getStatus())) {
- throw new DisabledException("User " + user.getUsername() + " not allowed to authenticate");
- }
-
- boolean userModified = false;
- authenticated = authenticate(user, authentication.getCredentials().toString());
- if (authenticated) {
- if (confDAO.find("log.lastlogindate", Boolean.toString(true)).getValues().get(0).getBooleanValue()) {
- user.setLastLoginDate(new Date());
- userModified = true;
- }
-
- if (user.getFailedLogins() != 0) {
- user.setFailedLogins(0);
- userModified = true;
- }
-
- } else {
- user.setFailedLogins(user.getFailedLogins() + 1);
- userModified = true;
- }
-
- if (userModified) {
- userDAO.save(user);
- }
- }
-
- return ImmutablePair.of(key, authenticated);
- }
-
- protected boolean authenticate(final User user, final String password) {
- boolean authenticated = ENCRYPTOR.verify(password, user.getCipherAlgorithm(), user.getPassword());
- LOG.debug("{} authenticated on internal storage: {}", user.getUsername(), authenticated);
-
- for (Iterator<? extends ExternalResource> itor = getPassthroughResources(user).iterator();
- itor.hasNext() && !authenticated;) {
-
- ExternalResource resource = itor.next();
- String connObjectKey = null;
- try {
- connObjectKey = mappingUtils.getConnObjectKeyValue(user, resource.getProvision(anyTypeDAO.findUser()));
- Uid uid = connFactory.getConnector(resource).authenticate(connObjectKey, password, null);
- if (uid != null) {
- authenticated = true;
- }
- } catch (Exception e) {
- LOG.debug("Could not authenticate {} on {}", user.getUsername(), resource.getKey(), e);
- }
- LOG.debug("{} authenticated on {} as {}: {}",
- user.getUsername(), resource.getKey(), connObjectKey, authenticated);
- }
-
- return authenticated;
- }
-
- protected Set<? extends ExternalResource> getPassthroughResources(final User user) {
- Set<? extends ExternalResource> result = null;
-
- // 1. look for assigned resources, pick the ones whose account policy has authentication resources
- for (ExternalResource resource : userDAO.findAllResources(user)) {
- if (resource.getAccountPolicy() != null && !resource.getAccountPolicy().getResources().isEmpty()) {
- if (result == null) {
- result = resource.getAccountPolicy().getResources();
- } else {
- result.retainAll(resource.getAccountPolicy().getResources());
- }
- }
- }
-
- // 2. look for realms, pick the ones whose account policy has authentication resources
- for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
- if (realm.getAccountPolicy() != null && !realm.getAccountPolicy().getResources().isEmpty()) {
- if (result == null) {
- result = realm.getAccountPolicy().getResources();
- } else {
- result.retainAll(realm.getAccountPolicy().getResources());
- }
- }
- }
-
- return SetUtils.emptyIfNull(result);
- }
-
- @Transactional(readOnly = true)
- public void audit(
- final AuditElements.EventCategoryType type,
- final String category,
- final String subcategory,
- final String event,
- final AuditElements.Result result,
- final Object before,
- final Object output,
- final Object... input) {
-
- auditManager.audit(type, category, subcategory, event, result, before, output, input);
- }
-
- @Transactional
- public Set<SyncopeGrantedAuthority> load(final String username) {
- final Set<SyncopeGrantedAuthority> authorities = new HashSet<>();
- if (anonymousUser.equals(username)) {
- authorities.add(new SyncopeGrantedAuthority(StandardEntitlement.ANONYMOUS));
- } else if (adminUser.equals(username)) {
- CollectionUtils.collect(
- EntitlementsHolder.getInstance().getValues(),
- new Transformer<String, SyncopeGrantedAuthority>() {
-
- @Override
- public SyncopeGrantedAuthority transform(final String entitlement) {
- return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
- }
- }, authorities);
- } else {
- User user = userDAO.find(username);
- if (user == null) {
- throw new UsernameNotFoundException("Could not find any user with id " + username);
- }
-
- if (user.isMustChangePassword()) {
- authorities.add(new SyncopeGrantedAuthority(StandardEntitlement.MUST_CHANGE_PASSWORD));
- } else {
- final Map<String, Set<String>> entForRealms = new HashMap<>();
-
- // Give entitlements as assigned by roles (with realms, where applicable) - assigned either
- // statically and dynamically
- for (final Role role : userDAO.findAllRoles(user)) {
- IterableUtils.forEach(role.getEntitlements(), new Closure<String>() {
-
- @Override
- public void execute(final String entitlement) {
- Set<String> realms = entForRealms.get(entitlement);
- if (realms == null) {
- realms = new HashSet<>();
- entForRealms.put(entitlement, realms);
- }
-
- CollectionUtils.collect(role.getRealms(), new Transformer<Realm, String>() {
-
- @Override
- public String transform(final Realm realm) {
- return realm.getFullPath();
- }
- }, realms);
- }
- });
- }
-
- // Give group entitlements for owned groups
- for (Group group : groupDAO.findOwnedByUser(user.getKey())) {
- for (String entitlement : Arrays.asList(
- StandardEntitlement.GROUP_READ,
- StandardEntitlement.GROUP_UPDATE,
- StandardEntitlement.GROUP_DELETE)) {
-
- Set<String> realms = entForRealms.get(entitlement);
- if (realms == null) {
- realms = new HashSet<>();
- entForRealms.put(entitlement, realms);
- }
-
- realms.add(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey()));
- }
- }
-
- // Finally normalize realms for each given entitlement and generate authorities
- for (Map.Entry<String, Set<String>> entry : entForRealms.entrySet()) {
- SyncopeGrantedAuthority authority = new SyncopeGrantedAuthority(entry.getKey());
- authority.addRealms(RealmUtils.normalize(entry.getValue()));
- authorities.add(authority);
- }
- }
- }
-
- return authorities;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/DefaultPasswordGenerator.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/DefaultPasswordGenerator.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/DefaultPasswordGenerator.java
deleted file mode 100644
index 9652f73..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/DefaultPasswordGenerator.java
+++ /dev/null
@@ -1,334 +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.core.misc.security;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
-import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.misc.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.misc.policy.PolicyPattern;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.springframework.beans.factory.annotation.Autowired;
-
-/**
- * Generate random passwords according to given policies.
- * When no minimum and / or maximum length are specified, default values are set.
- *
- * <strong>WARNING</strong>: This class only takes {@link DefaultPasswordRuleConf} into account.
- */
-public class DefaultPasswordGenerator implements PasswordGenerator {
-
- private static final char[] SPECIAL_CHARS = { '!', 'ÂŁ', '%', '&', '(', ')', '?', '#', '$' };
-
- private static final int VERY_MIN_LENGTH = 0;
-
- private static final int VERY_MAX_LENGTH = 64;
-
- private static final int MIN_LENGTH_IF_ZERO = 6;
-
- @Autowired
- private UserDAO userDAO;
-
- @Autowired
- private RealmDAO realmDAO;
-
- @Override
- public String generate(final User user) throws InvalidPasswordRuleConf {
- List<PasswordRuleConf> ruleConfs = new ArrayList<>();
-
- for (Realm ancestor : realmDAO.findAncestors(user.getRealm())) {
- if (ancestor.getPasswordPolicy() != null) {
- ruleConfs.addAll(ancestor.getPasswordPolicy().getRuleConfs());
- }
- }
-
- for (ExternalResource resource : userDAO.findAllResources(user)) {
- if (resource.getPasswordPolicy() != null) {
- ruleConfs.addAll(resource.getPasswordPolicy().getRuleConfs());
- }
- }
-
- return generate(ruleConfs);
- }
-
- @Override
- public String generate(final List<PasswordRuleConf> ruleConfs) throws InvalidPasswordRuleConf {
- List<DefaultPasswordRuleConf> defaultRuleConfs = new ArrayList<>();
- for (PasswordRuleConf ruleConf : ruleConfs) {
- if (ruleConf instanceof DefaultPasswordRuleConf) {
- defaultRuleConfs.add((DefaultPasswordRuleConf) ruleConf);
- }
- }
-
- DefaultPasswordRuleConf ruleConf = merge(defaultRuleConfs);
- check(ruleConf);
- return generate(ruleConf);
- }
-
- private DefaultPasswordRuleConf merge(final List<DefaultPasswordRuleConf> defaultRuleConfs) {
- DefaultPasswordRuleConf result = new DefaultPasswordRuleConf();
- result.setMinLength(VERY_MIN_LENGTH);
- result.setMaxLength(VERY_MAX_LENGTH);
-
- for (DefaultPasswordRuleConf ruleConf : defaultRuleConfs) {
- if (ruleConf.getMinLength() > result.getMinLength()) {
- result.setMinLength(ruleConf.getMinLength());
- }
-
- if ((ruleConf.getMaxLength() != 0) && ((ruleConf.getMaxLength() < result.getMaxLength()))) {
- result.setMaxLength(ruleConf.getMaxLength());
- }
- result.getPrefixesNotPermitted().addAll(ruleConf.getPrefixesNotPermitted());
- result.getSuffixesNotPermitted().addAll(ruleConf.getSuffixesNotPermitted());
-
- if (!result.isNonAlphanumericRequired()) {
- result.setNonAlphanumericRequired(ruleConf.isNonAlphanumericRequired());
- }
-
- if (!result.isAlphanumericRequired()) {
- result.setAlphanumericRequired(ruleConf.isAlphanumericRequired());
- }
- if (!result.isDigitRequired()) {
- result.setDigitRequired(ruleConf.isDigitRequired());
- }
-
- if (!result.isLowercaseRequired()) {
- result.setLowercaseRequired(ruleConf.isLowercaseRequired());
- }
- if (!result.isUppercaseRequired()) {
- result.setUppercaseRequired(ruleConf.isUppercaseRequired());
- }
- if (!result.isMustStartWithDigit()) {
- result.setMustStartWithDigit(ruleConf.isMustStartWithDigit());
- }
- if (!result.isMustntStartWithDigit()) {
- result.setMustntStartWithDigit(ruleConf.isMustntStartWithDigit());
- }
- if (!result.isMustEndWithDigit()) {
- result.setMustEndWithDigit(ruleConf.isMustEndWithDigit());
- }
- if (result.isMustntEndWithDigit()) {
- result.setMustntEndWithDigit(ruleConf.isMustntEndWithDigit());
- }
- if (!result.isMustStartWithAlpha()) {
- result.setMustStartWithAlpha(ruleConf.isMustStartWithAlpha());
- }
- if (!result.isMustntStartWithAlpha()) {
- result.setMustntStartWithAlpha(ruleConf.isMustntStartWithAlpha());
- }
- if (!result.isMustStartWithNonAlpha()) {
- result.setMustStartWithNonAlpha(ruleConf.isMustStartWithNonAlpha());
- }
- if (!result.isMustntStartWithNonAlpha()) {
- result.setMustntStartWithNonAlpha(ruleConf.isMustntStartWithNonAlpha());
- }
- if (!result.isMustEndWithNonAlpha()) {
- result.setMustEndWithNonAlpha(ruleConf.isMustEndWithNonAlpha());
- }
- if (!result.isMustntEndWithNonAlpha()) {
- result.setMustntEndWithNonAlpha(ruleConf.isMustntEndWithNonAlpha());
- }
- if (!result.isMustEndWithAlpha()) {
- result.setMustEndWithAlpha(ruleConf.isMustEndWithAlpha());
- }
- if (!result.isMustntEndWithAlpha()) {
- result.setMustntEndWithAlpha(ruleConf.isMustntEndWithAlpha());
- }
- if (!result.isUsernameAllowed()) {
- result.setUsernameAllowed(ruleConf.isUsernameAllowed());
- }
- }
-
- if (result.getMinLength() == 0) {
- result.setMinLength(
- result.getMaxLength() < MIN_LENGTH_IF_ZERO ? result.getMaxLength() : MIN_LENGTH_IF_ZERO);
- }
-
- return result;
- }
-
- private void check(final DefaultPasswordRuleConf defaultPasswordRuleConf)
- throws InvalidPasswordRuleConf {
-
- if (defaultPasswordRuleConf.isMustEndWithAlpha() && defaultPasswordRuleConf.isMustntEndWithAlpha()) {
- throw new InvalidPasswordRuleConf(
- "mustEndWithAlpha and mustntEndWithAlpha are both true");
- }
- if (defaultPasswordRuleConf.isMustEndWithAlpha() && defaultPasswordRuleConf.isMustEndWithDigit()) {
- throw new InvalidPasswordRuleConf(
- "mustEndWithAlpha and mustEndWithDigit are both true");
- }
- if (defaultPasswordRuleConf.isMustEndWithDigit() && defaultPasswordRuleConf.isMustntEndWithDigit()) {
- throw new InvalidPasswordRuleConf(
- "mustEndWithDigit and mustntEndWithDigit are both true");
- }
- if (defaultPasswordRuleConf.isMustEndWithNonAlpha() && defaultPasswordRuleConf.isMustntEndWithNonAlpha()) {
- throw new InvalidPasswordRuleConf(
- "mustEndWithNonAlpha and mustntEndWithNonAlpha are both true");
- }
- if (defaultPasswordRuleConf.isMustStartWithAlpha() && defaultPasswordRuleConf.isMustntStartWithAlpha()) {
- throw new InvalidPasswordRuleConf(
- "mustStartWithAlpha and mustntStartWithAlpha are both true");
- }
- if (defaultPasswordRuleConf.isMustStartWithAlpha() && defaultPasswordRuleConf.isMustStartWithDigit()) {
- throw new InvalidPasswordRuleConf(
- "mustStartWithAlpha and mustStartWithDigit are both true");
- }
- if (defaultPasswordRuleConf.isMustStartWithDigit() && defaultPasswordRuleConf.isMustntStartWithDigit()) {
- throw new InvalidPasswordRuleConf(
- "mustStartWithDigit and mustntStartWithDigit are both true");
- }
- if (defaultPasswordRuleConf.isMustStartWithNonAlpha() && defaultPasswordRuleConf.isMustntStartWithNonAlpha()) {
- throw new InvalidPasswordRuleConf(
- "mustStartWithNonAlpha and mustntStartWithNonAlpha are both true");
- }
- if (defaultPasswordRuleConf.getMinLength() > defaultPasswordRuleConf.getMaxLength()) {
- throw new InvalidPasswordRuleConf(
- "Minimun length (" + defaultPasswordRuleConf.getMinLength() + ")"
- + "is greater than maximum length (" + defaultPasswordRuleConf.getMaxLength() + ")");
- }
- }
-
- private String generate(final DefaultPasswordRuleConf ruleConf) {
- String[] generatedPassword = new String[ruleConf.getMinLength()];
-
- for (int i = 0; i < generatedPassword.length; i++) {
- generatedPassword[i] = StringUtils.EMPTY;
- }
-
- checkStartChar(generatedPassword, ruleConf);
-
- checkEndChar(generatedPassword, ruleConf);
-
- checkRequired(generatedPassword, ruleConf);
-
- for (int firstEmptyChar = firstEmptyChar(generatedPassword);
- firstEmptyChar < generatedPassword.length - 1; firstEmptyChar++) {
-
- generatedPassword[firstEmptyChar] = SecureRandomUtils.generateRandomLetter();
- }
-
- checkPrefixAndSuffix(generatedPassword, ruleConf);
-
- return StringUtils.join(generatedPassword);
- }
-
- private void checkStartChar(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
- if (ruleConf.isMustStartWithAlpha()) {
- generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
- }
- if (ruleConf.isMustStartWithNonAlpha() || ruleConf.isMustStartWithDigit()) {
- generatedPassword[0] = SecureRandomUtils.generateRandomNumber();
- }
- if (ruleConf.isMustntStartWithAlpha()) {
- generatedPassword[0] = SecureRandomUtils.generateRandomNumber();
- }
- if (ruleConf.isMustntStartWithDigit()) {
- generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
- }
- if (ruleConf.isMustntStartWithNonAlpha()) {
- generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
- }
-
- if (StringUtils.EMPTY.equals(generatedPassword[0])) {
- generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
- }
- }
-
- private void checkEndChar(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
- if (ruleConf.isMustEndWithAlpha()) {
- generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
- }
- if (ruleConf.isMustEndWithNonAlpha() || ruleConf.isMustEndWithDigit()) {
- generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomNumber();
- }
-
- if (ruleConf.isMustntEndWithAlpha()) {
- generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomNumber();
- }
- if (ruleConf.isMustntEndWithDigit()) {
- generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
- }
- if (ruleConf.isMustntEndWithNonAlpha()) {
- generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
- }
-
- if (StringUtils.EMPTY.equals(generatedPassword[ruleConf.getMinLength() - 1])) {
- generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
- }
- }
-
- private int firstEmptyChar(final String[] generatedPStrings) {
- int index = 0;
- while (!generatedPStrings[index].isEmpty()) {
- index++;
- }
- return index;
- }
-
- private void checkRequired(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
- if (ruleConf.isDigitRequired()
- && !PolicyPattern.DIGIT.matcher(StringUtils.join(generatedPassword)).matches()) {
-
- generatedPassword[firstEmptyChar(generatedPassword)] = SecureRandomUtils.generateRandomNumber();
- }
-
- if (ruleConf.isUppercaseRequired()
- && !PolicyPattern.ALPHA_UPPERCASE.matcher(StringUtils.join(generatedPassword)).matches()) {
-
- generatedPassword[firstEmptyChar(generatedPassword)] =
- SecureRandomUtils.generateRandomLetter().toUpperCase();
- }
-
- if (ruleConf.isLowercaseRequired()
- && !PolicyPattern.ALPHA_LOWERCASE.matcher(StringUtils.join(generatedPassword)).matches()) {
-
- generatedPassword[firstEmptyChar(generatedPassword)] =
- SecureRandomUtils.generateRandomLetter().toLowerCase();
- }
-
- if (ruleConf.isNonAlphanumericRequired()
- && !PolicyPattern.NON_ALPHANUMERIC.matcher(StringUtils.join(generatedPassword)).matches()) {
-
- generatedPassword[firstEmptyChar(generatedPassword)] =
- SecureRandomUtils.generateRandomSpecialCharacter(SPECIAL_CHARS);
- }
- }
-
- private void checkPrefixAndSuffix(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
- for (String prefix : ruleConf.getPrefixesNotPermitted()) {
- if (StringUtils.join(generatedPassword).startsWith(prefix)) {
- checkStartChar(generatedPassword, ruleConf);
- }
- }
-
- for (String suffix : ruleConf.getSuffixesNotPermitted()) {
- if (StringUtils.join(generatedPassword).endsWith(suffix)) {
- checkEndChar(generatedPassword, ruleConf);
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/DelegatedAdministrationException.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/DelegatedAdministrationException.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/DelegatedAdministrationException.java
deleted file mode 100644
index 13a449f..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/DelegatedAdministrationException.java
+++ /dev/null
@@ -1,33 +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.core.misc.security;
-
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-
-public class DelegatedAdministrationException extends RuntimeException {
-
- private static final long serialVersionUID = 7540587364235915081L;
-
- public DelegatedAdministrationException(final AnyTypeKind type, final Long key) {
- super("Missing entitlement or realm administration for "
- + (key == null
- ? "new " + type
- : type + " " + key));
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/Encryptor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/Encryptor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/Encryptor.java
deleted file mode 100644
index 4c55513..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/Encryptor.java
+++ /dev/null
@@ -1,256 +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.core.misc.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<>();
-
- 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 SECRET_KEY;
-
- private static Integer SALT_ITERATIONS;
-
- private static Integer SALT_SIZE_BYTES;
-
- 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);
-
- SECRET_KEY = props.getProperty("secretKey");
- SALT_ITERATIONS = Integer.valueOf(props.getProperty("digester.saltIterations"));
- SALT_SIZE_BYTES = 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 (SECRET_KEY == null) {
- SECRET_KEY = DEFAULT_SECRET_KEY;
- LOG.debug("secretKey not found, reverting to default");
- }
- if (SALT_ITERATIONS == null) {
- SALT_ITERATIONS = DEFAULT_SALT_ITERATIONS;
- LOG.debug("digester.saltIterations not found, reverting to default");
- }
- if (SALT_SIZE_BYTES == null) {
- SALT_SIZE_BYTES = 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(SECRET_KEY);
- }
-
- 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_CHARSET), 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_CHARSET);
-
- 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_CHARSET);
-
- final Cipher cipher = Cipher.getInstance(CipherAlgorithm.AES.getAlgorithm());
- cipher.init(Cipher.DECRYPT_MODE, keySpec);
-
- value = new String(cipher.doFinal(Base64.decode(encoded)), SyncopeConstants.DEFAULT_CHARSET);
- }
-
- 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(SALT_ITERATIONS);
- digester.setSaltSizeBytes(SALT_SIZE_BYTES);
- 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/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/MustChangePasswordFilter.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/MustChangePasswordFilter.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/MustChangePasswordFilter.java
deleted file mode 100644
index c52d355..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/MustChangePasswordFilter.java
+++ /dev/null
@@ -1,80 +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.core.misc.security;
-
-import java.io.IOException;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper;
-
-public class MustChangePasswordFilter implements Filter {
-
- private static final String[] ALLOWED = new String[] {
- "/users/self", "/users/self/changePassword"
- };
-
- @Override
- public void init(final FilterConfig filterConfig) throws ServletException {
- // not used
- }
-
- @Override
- public void destroy() {
- // not used
- }
-
- @Override
- public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
- throws IOException, ServletException {
-
- if (request instanceof SecurityContextHolderAwareRequestWrapper) {
- boolean isMustChangePassword = IterableUtils.matchesAny(
- SecurityContextHolder.getContext().getAuthentication().getAuthorities(),
- new Predicate<GrantedAuthority>() {
-
- @Override
- public boolean evaluate(final GrantedAuthority authority) {
- return StandardEntitlement.MUST_CHANGE_PASSWORD.equals(authority.getAuthority());
- }
- });
-
- SecurityContextHolderAwareRequestWrapper wrapper =
- SecurityContextHolderAwareRequestWrapper.class.cast(request);
- if (isMustChangePassword && "GET".equalsIgnoreCase(wrapper.getMethod())
- && !ArrayUtils.contains(ALLOWED, wrapper.getPathInfo())) {
-
- throw new AccessDeniedException("Please change your password first");
- }
- }
-
- chain.doFilter(request, response);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
deleted file mode 100644
index 936dae5..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/PasswordGenerator.java
+++ /dev/null
@@ -1,32 +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.core.misc.security;
-
-import java.util.List;
-import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.core.misc.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-
-public interface PasswordGenerator {
-
- String generate(User user) throws InvalidPasswordRuleConf;
-
- String generate(List<PasswordRuleConf> ruleConfs) throws InvalidPasswordRuleConf;
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SecureRandomUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SecureRandomUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SecureRandomUtils.java
deleted file mode 100644
index f41207b..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SecureRandomUtils.java
+++ /dev/null
@@ -1,48 +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.core.misc.security;
-
-import java.security.SecureRandom;
-
-import org.apache.commons.lang3.RandomStringUtils;
-
-public final class SecureRandomUtils {
-
- 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(final char[] characters) {
- return RandomStringUtils.random(1, 0, 0, false, false, characters, RANDOM);
- }
-
- private SecureRandomUtils() {
- // private constructor for static utility class
- }
-}
[04/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserPushResultHandlerImpl.java
new file mode 100644
index 0000000..a589416
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserPushResultHandlerImpl.java
@@ -0,0 +1,96 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.syncpull.UserPushResultHandler;
+
+public class UserPushResultHandlerImpl extends AbstractPushResultHandler implements UserPushResultHandler {
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.USER);
+ }
+
+ @Override
+ protected void provision(final Any<?> any, final Boolean enabled) {
+ AnyTO before = getAnyTO(any.getKey());
+
+ List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getUserCreateTasks(
+ before.getKey(),
+ null,
+ enabled,
+ propByRes,
+ before.getVirAttrs(),
+ noPropResources));
+ }
+
+ @Override
+ protected String getName(final Any<?> any) {
+ return User.class.cast(any).getUsername();
+ }
+
+ @Override
+ protected Any<?> getAny(final long key) {
+ try {
+ return userDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final long key) {
+ return userDataBinder.getUserTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final long key) {
+ UserPatch patch = new UserPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<Long> update(final AnyPatch patch) {
+ WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
+ return new WorkflowResult<>(
+ update.getResult().getLeft().getKey(), update.getPropByRes(), update.getPerformedTasks());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserSyncResultHandlerImpl.java
new file mode 100644
index 0000000..92dd5eb
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/UserSyncResultHandlerImpl.java
@@ -0,0 +1,133 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.syncpull.UserSyncResultHandler;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+
+public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler implements UserSyncResultHandler {
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.USER);
+ }
+
+ @Override
+ protected String getName(final AnyTO anyTO) {
+ return UserTO.class.cast(anyTO).getUsername();
+ }
+
+ @Override
+ protected ProvisioningManager<?, ?> getProvisioningManager() {
+ return userProvisioningManager;
+ }
+
+ @Override
+ protected Any<?> getAny(final long key) {
+ try {
+ return userDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final long key) {
+ return userDataBinder.getUserTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final long key) {
+ UserPatch patch = new UserPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<Long> update(final AnyPatch patch) {
+ WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
+ return new WorkflowResult<>(
+ update.getResult().getLeft().getKey(), update.getPropByRes(), update.getPerformedTasks());
+ }
+
+ @Override
+ protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningReport result) {
+ UserTO userTO = UserTO.class.cast(anyTO);
+
+ Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
+ Map.Entry<Long, List<PropagationStatus>> created =
+ userProvisioningManager.create(userTO, true, true, enabled,
+ Collections.singleton(profile.getTask().getResource().getKey()), true);
+
+ result.setKey(created.getKey());
+ result.setName(getName(anyTO));
+
+ return getAnyTO(created.getKey());
+ }
+
+ @Override
+ protected AnyTO doUpdate(
+ final AnyTO before,
+ final AnyPatch anyPatch,
+ final SyncDelta delta,
+ final ProvisioningReport result) {
+
+ UserPatch userPatch = UserPatch.class.cast(anyPatch);
+ Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
+
+ Map.Entry<Long, List<PropagationStatus>> updated = userProvisioningManager.update(
+ userPatch,
+ result,
+ enabled,
+ Collections.singleton(profile.getTask().getResource().getKey()),
+ true);
+
+ return getAnyTO(updated.getKey());
+ }
+
+ @Override
+ protected void doDelete(final AnyTypeKind kind, final Long key) {
+ try {
+ userProvisioningManager.delete(
+ key, Collections.<String>singleton(profile.getTask().getResource().getKey()), true);
+ } catch (Exception e) {
+ // A propagation failure doesn't imply a synchronization failure.
+ // The propagation exception status will be reported into the propagation task execution.
+ LOG.error("Could not propagate user " + key, e);
+ }
+
+ uwfAdapter.delete(key);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
new file mode 100644
index 0000000..703bc49
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/ConnObjectUtils.java
@@ -0,0 +1,269 @@
+/*
+ * 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.core.provisioning.java.utils;
+
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.AnyOperations;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.policy.PasswordRuleConf;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.spring.security.PasswordGenerator;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.common.security.GuardedByteArray;
+import org.identityconnectors.common.security.GuardedString;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class ConnObjectUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ConnObjectUtils.class);
+
+ private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
+ @Autowired
+ private TemplateUtils templateUtils;
+
+ @Autowired
+ private RealmDAO realmDAO;
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Autowired
+ private ExternalResourceDAO resourceDAO;
+
+ @Autowired
+ private PasswordGenerator passwordGenerator;
+
+ @Autowired
+ private MappingManager mappingManager;
+
+ /**
+ * Extract password value from passed value (if instance of GuardedString or GuardedByteArray).
+ *
+ * @param pwd received from the underlying connector
+ * @return password value
+ */
+ public static String getPassword(final Object pwd) {
+ final StringBuilder result = new StringBuilder();
+
+ if (pwd instanceof GuardedString) {
+ ((GuardedString) pwd).access(new GuardedString.Accessor() {
+
+ @Override
+ public void access(final char[] clearChars) {
+ result.append(clearChars);
+ }
+ });
+ } else if (pwd instanceof GuardedByteArray) {
+ ((GuardedByteArray) pwd).access(new GuardedByteArray.Accessor() {
+
+ @Override
+ public void access(final byte[] clearBytes) {
+ result.append(new String(clearBytes));
+ }
+ });
+ } else if (pwd instanceof String) {
+ result.append((String) pwd);
+ } else {
+ result.append(pwd.toString());
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Build a UserTO / GroupTO / AnyObjectTO out of connector object attributes and schema mapping.
+ *
+ * @param obj connector object
+ * @param syncTask synchronization task
+ * @param provision provision information
+ * @param anyUtils utils
+ * @param <T> any object
+ * @return UserTO for the user to be created
+ */
+ @Transactional(readOnly = true)
+ public <T extends AnyTO> T getAnyTO(
+ final ConnectorObject obj, final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
+
+ T anyTO = getAnyTOFromConnObject(obj, syncTask, provision, anyUtils);
+
+ // (for users) if password was not set above, generate
+ if (anyTO instanceof UserTO && StringUtils.isBlank(((UserTO) anyTO).getPassword())) {
+ final UserTO userTO = (UserTO) anyTO;
+
+ List<PasswordRuleConf> ruleConfs = new ArrayList<>();
+
+ Realm realm = realmDAO.find(userTO.getRealm());
+ if (realm != null) {
+ for (Realm ancestor : realmDAO.findAncestors(realm)) {
+ if (ancestor.getPasswordPolicy() != null) {
+ ruleConfs.addAll(ancestor.getPasswordPolicy().getRuleConfs());
+ }
+ }
+ }
+
+ for (String resName : userTO.getResources()) {
+ ExternalResource resource = resourceDAO.find(resName);
+ if (resource != null && resource.getPasswordPolicy() != null) {
+ ruleConfs.addAll(resource.getPasswordPolicy().getRuleConfs());
+ }
+ }
+
+ String password;
+ try {
+ password = passwordGenerator.generate(ruleConfs);
+ } catch (InvalidPasswordRuleConf e) {
+ LOG.error("Could not generate policy-compliant random password for {}", userTO, e);
+
+ password = SecureRandomUtils.generateRandomPassword(16);
+ }
+ userTO.setPassword(password);
+ }
+
+ return anyTO;
+ }
+
+ /**
+ * Build {@link AnyPatch} out of connector object attributes and schema mapping.
+ *
+ * @param key any object to be updated
+ * @param obj connector object
+ * @param original any object to get diff from
+ * @param syncTask synchronization task
+ * @param provision provision information
+ * @param anyUtils utils
+ * @param <T> any object
+ * @return modifications for the any object to be updated
+ */
+ @SuppressWarnings("unchecked")
+ @Transactional(readOnly = true)
+ public <T extends AnyPatch> T getAnyPatch(final Long key, final ConnectorObject obj,
+ final AnyTO original, final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
+
+ AnyTO updated = getAnyTOFromConnObject(obj, syncTask, provision, anyUtils);
+ updated.setKey(key);
+
+ if (null != anyUtils.getAnyTypeKind()) {
+ switch (anyUtils.getAnyTypeKind()) {
+ case USER:
+ // update password if and only if password is really changed
+ User user = userDAO.authFind(key);
+ if (StringUtils.isBlank(((UserTO) updated).getPassword())
+ || ENCRYPTOR.verify(((UserTO) updated).getPassword(),
+ user.getCipherAlgorithm(), user.getPassword())) {
+
+ ((UserTO) updated).setPassword(null);
+ }
+ return (T) AnyOperations.diff(((UserTO) updated), ((UserTO) original), true);
+
+ case GROUP:
+ return (T) AnyOperations.diff(((GroupTO) updated), ((GroupTO) original), true);
+
+ case ANY_OBJECT:
+ return (T) AnyOperations.diff(((AnyObjectTO) updated), ((AnyObjectTO) original), true);
+
+ default:
+ }
+ }
+
+ return null;
+ }
+
+ private <T extends AnyTO> T getAnyTOFromConnObject(final ConnectorObject obj,
+ final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
+
+ T anyTO = anyUtils.newAnyTO();
+ anyTO.setType(provision.getAnyType().getKey());
+
+ // 1. fill with data from connector object
+ anyTO.setRealm(syncTask.getDestinatioRealm().getFullPath());
+ for (MappingItem item : MappingManagerImpl.getSyncMappingItems(provision)) {
+ mappingManager.setIntValues(item, obj.getAttributeByName(item.getExtAttrName()), anyTO, anyUtils);
+ }
+
+ // 2. add data from defined template (if any)
+ templateUtils.apply(anyTO, syncTask.getTemplate(provision.getAnyType()));
+
+ return anyTO;
+ }
+
+ /**
+ * Get connector object TO from a connector object.
+ *
+ * @param connObject connector object.
+ * @return connector object TO.
+ */
+ public ConnObjectTO getConnObjectTO(final ConnectorObject connObject) {
+ final ConnObjectTO connObjectTO = new ConnObjectTO();
+
+ if (connObject != null) {
+ for (Attribute attr : connObject.getAttributes()) {
+ AttrTO attrTO = new AttrTO();
+ attrTO.setSchema(attr.getName());
+
+ if (attr.getValue() != null) {
+ for (Object value : attr.getValue()) {
+ if (value != null) {
+ if (value instanceof GuardedString || value instanceof GuardedByteArray) {
+ attrTO.getValues().add(getPassword(value));
+ } else if (value instanceof byte[]) {
+ attrTO.getValues().add(Base64.encode((byte[]) value));
+ } else {
+ attrTO.getValues().add(value.toString());
+ }
+ }
+ }
+ }
+
+ connObjectTO.getPlainAttrs().add(attrTO);
+ }
+ }
+
+ return connObjectTO;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
new file mode 100644
index 0000000..31342ec
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
@@ -0,0 +1,224 @@
+/*
+ * 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.core.provisioning.java.utils;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RelationshipTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class TemplateUtils {
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Autowired
+ private GroupDAO groupDAO;
+
+ private AttrTO evaluateAttr(final AnyTO anyTO, final AttrTO template) {
+ AttrTO result = new AttrTO();
+ result.setSchema(template.getSchema());
+
+ if (template.getValues() != null && !template.getValues().isEmpty()) {
+ for (String value : template.getValues()) {
+ String evaluated = JexlUtils.evaluate(value, anyTO);
+ if (StringUtils.isNotBlank(evaluated)) {
+ result.getValues().add(evaluated);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private void fill(final AnyTO anyTO, final AnyTO template) {
+ if (template.getRealm() != null) {
+ anyTO.setRealm(template.getRealm());
+ }
+
+ Map<String, AttrTO> currentAttrMap = anyTO.getPlainAttrMap();
+ for (AttrTO templatePlainAttr : template.getPlainAttrs()) {
+ if (!templatePlainAttr.getValues().isEmpty()
+ && (!currentAttrMap.containsKey(templatePlainAttr.getSchema())
+ || currentAttrMap.get(templatePlainAttr.getSchema()).getValues().isEmpty())) {
+
+ anyTO.getPlainAttrs().add(evaluateAttr(anyTO, templatePlainAttr));
+ }
+ }
+
+ currentAttrMap = anyTO.getDerAttrMap();
+ for (AttrTO templateDerAttr : template.getDerAttrs()) {
+ if (!currentAttrMap.containsKey(templateDerAttr.getSchema())) {
+ anyTO.getDerAttrs().add(templateDerAttr);
+ }
+ }
+
+ currentAttrMap = anyTO.getVirAttrMap();
+ for (AttrTO templateVirAttr : template.getVirAttrs()) {
+ if (!templateVirAttr.getValues().isEmpty()
+ && (!currentAttrMap.containsKey(templateVirAttr.getSchema())
+ || currentAttrMap.get(templateVirAttr.getSchema()).getValues().isEmpty())) {
+
+ anyTO.getVirAttrs().add(evaluateAttr(anyTO, templateVirAttr));
+ }
+ }
+
+ for (String resource : template.getResources()) {
+ anyTO.getResources().add(resource);
+ }
+
+ anyTO.getAuxClasses().addAll(template.getAuxClasses());
+ }
+
+ private void fillRelationships(final Map<Pair<String, Long>, RelationshipTO> anyRelMap,
+ final List<RelationshipTO> anyRels, final List<RelationshipTO> templateRels) {
+
+ for (RelationshipTO memb : templateRels) {
+ if (!anyRelMap.containsKey(Pair.of(memb.getRightType(), memb.getRightKey()))) {
+ anyRels.add(memb);
+ }
+ }
+ }
+
+ private void fillMemberships(final Map<Long, MembershipTO> anyMembMap,
+ final List<MembershipTO> anyMembs, final List<MembershipTO> templateMembs) {
+
+ for (MembershipTO memb : templateMembs) {
+ if (!anyMembMap.containsKey(memb.getRightKey())) {
+ anyMembs.add(memb);
+ }
+ }
+ }
+
+ @Transactional(readOnly = true)
+ public <T extends AnyTO> void apply(final T anyTO, final AnyTemplate anyTemplate) {
+ if (anyTemplate != null) {
+ AnyTO template = anyTemplate.get();
+ fill(anyTO, template);
+
+ if (template instanceof AnyObjectTO) {
+ fillRelationships(((AnyObjectTO) anyTO).getRelationshipMap(),
+ ((AnyObjectTO) anyTO).getRelationships(), ((AnyObjectTO) template).getRelationships());
+ fillMemberships(((AnyObjectTO) anyTO).getMembershipMap(),
+ ((AnyObjectTO) anyTO).getMemberships(), ((AnyObjectTO) template).getMemberships());
+ } else if (template instanceof UserTO) {
+ if (StringUtils.isNotBlank(((UserTO) template).getUsername())) {
+ String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), anyTO);
+ if (StringUtils.isNotBlank(evaluated)) {
+ ((UserTO) anyTO).setUsername(evaluated);
+ }
+ }
+
+ if (StringUtils.isNotBlank(((UserTO) template).getPassword())) {
+ String evaluated = JexlUtils.evaluate(((UserTO) template).getPassword(), anyTO);
+ if (StringUtils.isNotBlank(evaluated)) {
+ ((UserTO) anyTO).setPassword(evaluated);
+ }
+ }
+
+ fillRelationships(((UserTO) anyTO).getRelationshipMap(),
+ ((UserTO) anyTO).getRelationships(), ((UserTO) template).getRelationships());
+ fillMemberships(((UserTO) anyTO).getMembershipMap(),
+ ((UserTO) anyTO).getMemberships(), ((UserTO) template).getMemberships());
+ } else if (template instanceof GroupTO) {
+ if (StringUtils.isNotBlank(((GroupTO) template).getName())) {
+ String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), anyTO);
+ if (StringUtils.isNotBlank(evaluated)) {
+ ((GroupTO) anyTO).setName(evaluated);
+ }
+ }
+
+ if (((GroupTO) template).getUserOwner() != null) {
+ final User userOwner = userDAO.find(((GroupTO) template).getUserOwner());
+ if (userOwner != null) {
+ ((GroupTO) anyTO).setUserOwner(userOwner.getKey());
+ }
+ }
+ if (((GroupTO) template).getGroupOwner() != null) {
+ final Group groupOwner = groupDAO.find(((GroupTO) template).getGroupOwner());
+ if (groupOwner != null) {
+ ((GroupTO) anyTO).setGroupOwner(groupOwner.getKey());
+ }
+ }
+ }
+ }
+ }
+
+ public void check(final Map<String, AnyTO> templates, final ClientExceptionType clientExceptionType) {
+ SyncopeClientException sce = SyncopeClientException.build(clientExceptionType);
+
+ for (Map.Entry<String, AnyTO> entry : templates.entrySet()) {
+ for (AttrTO attrTO : entry.getValue().getPlainAttrs()) {
+ if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
+ sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
+ }
+ }
+
+ for (AttrTO attrTO : entry.getValue().getVirAttrs()) {
+ if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
+ sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
+ }
+ }
+
+ if (entry.getValue() instanceof UserTO) {
+ UserTO template = (UserTO) entry.getValue();
+ if (StringUtils.isNotBlank(template.getUsername())
+ && !JexlUtils.isExpressionValid(template.getUsername())) {
+
+ sce.getElements().add("Invalid JEXL: " + template.getUsername());
+ }
+ if (StringUtils.isNotBlank(template.getPassword())
+ && !JexlUtils.isExpressionValid(template.getPassword())) {
+
+ sce.getElements().add("Invalid JEXL: " + template.getPassword());
+ }
+ } else if (entry.getValue() instanceof GroupTO) {
+ GroupTO template = (GroupTO) entry.getValue();
+ if (StringUtils.isNotBlank(template.getName())
+ && !JexlUtils.isExpressionValid(template.getName())) {
+
+ sce.getElements().add("Invalid JEXL: " + template.getName());
+ }
+ }
+ }
+
+ if (!sce.isEmpty()) {
+ throw sce;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
index 1193e16..e26f238 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java
@@ -27,7 +27,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
"classpath:persistenceTest.xml",
"classpath:provisioningContext.xml",
"classpath:workflowContext.xml",
- "classpath:utilsContext.xml",
"classpath:provisioningTest.xml"
})
public abstract class AbstractTest {
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
index 205aa2f..1b2e060 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ConnectorManagerTest.java
@@ -24,7 +24,7 @@ import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java
index fe55f8e..b87a6a9 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java
@@ -35,7 +35,7 @@ import org.apache.commons.lang3.SerializationUtils;
import org.apache.syncope.common.lib.to.AttrTO;
import org.apache.syncope.common.lib.to.MembershipTO;
import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
import org.apache.syncope.core.persistence.api.dao.MailTemplateDAO;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java
index 91486ab..820b8d2 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MappingTest.java
@@ -21,7 +21,6 @@ package org.apache.syncope.core.provisioning.java;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import org.apache.syncope.core.misc.utils.MappingUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
@@ -58,12 +57,12 @@ public class MappingTest extends AbstractTest {
User user = userDAO.find("rossini");
assertNotNull(user);
- Name name = MappingUtils.evaluateNAME(user, provision, user.getUsername());
+ Name name = MappingManagerImpl.evaluateNAME(user, provision, user.getUsername());
assertEquals("uid=rossini,ou=people,o=isp", name.getNameValue());
provision.getMapping().setConnObjectLink("'uid=' + username + ',o=' + realm + ',ou=people,o=isp'");
- name = MappingUtils.evaluateNAME(user, provision, user.getUsername());
+ name = MappingManagerImpl.evaluateNAME(user, provision, user.getUsername());
assertEquals("uid=rossini,o=even,ou=people,o=isp", name.getNameValue());
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java
index 1ae087a..d0bc946 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AddDomainFilter.java
@@ -24,7 +24,7 @@ import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
/**
* Adds the domain header to all responses.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
index 42cbfda..12e1d28 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
@@ -45,7 +45,7 @@ import org.apache.syncope.common.lib.to.ErrorTO;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.EntityViolationType;
import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
import org.apache.syncope.core.persistence.api.dao.DuplicateException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java
index f767c19..e6c5c39 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java
@@ -20,7 +20,7 @@ package org.apache.syncope.core.rest.cxf;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
import org.identityconnectors.common.l10n.CurrentLocale;
import org.identityconnectors.framework.impl.api.local.ThreadClassLoaderManager;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
index eec8927..453f074 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
@@ -42,7 +42,7 @@ import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.rest.api.service.JAXRSService;
import org.apache.syncope.common.rest.api.Preference;
import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.apache.syncope.core.misc.search.SearchCondVisitor;
+import org.apache.syncope.core.persistence.api.search.SearchCondVisitor;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/pom.xml
----------------------------------------------------------------------
diff --git a/core/spring/pom.xml b/core/spring/pom.xml
new file mode 100644
index 0000000..c912488
--- /dev/null
+++ b/core/spring/pom.xml
@@ -0,0 +1,103 @@
+<?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-core</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Core Spring</name>
+ <description>Apache Syncope Core Misc</description>
+ <groupId>org.apache.syncope.core</groupId>
+ <artifactId>syncope-core-spring</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</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.springframework.security</groupId>
+ <artifactId>spring-security-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-tx</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.core</groupId>
+ <artifactId>syncope-core-provisioning-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.common</groupId>
+ <artifactId>syncope-common-rest-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- TEST -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/ApplicationContextProvider.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/ApplicationContextProvider.java b/core/spring/src/main/java/org/apache/syncope/core/spring/ApplicationContextProvider.java
new file mode 100644
index 0000000..a1ad7f1
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/ApplicationContextProvider.java
@@ -0,0 +1,57 @@
+/*
+ * 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.core.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;
+
+ private static DefaultListableBeanFactory BEAN_FACTORY;
+
+ public static ConfigurableApplicationContext getApplicationContext() {
+ return CTX;
+ }
+
+ public static DefaultListableBeanFactory getBeanFactory() {
+ return BEAN_FACTORY == null
+ ? CTX == null
+ ? null
+ : (DefaultListableBeanFactory) CTX.getBeanFactory()
+ : BEAN_FACTORY;
+ }
+
+ public static void setBeanFactory(final DefaultListableBeanFactory beanFactory) {
+ BEAN_FACTORY = beanFactory;
+ }
+
+ /**
+ * Wiring the ApplicationContext into a static method.
+ *
+ * @param ctx Spring application context
+ */
+ @Override
+ public void setApplicationContext(final ApplicationContext ctx) {
+ CTX = (ConfigurableApplicationContext) ctx;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/BeanUtils.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/BeanUtils.java b/core/spring/src/main/java/org/apache/syncope/core/spring/BeanUtils.java
new file mode 100644
index 0000000..980b022
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/BeanUtils.java
@@ -0,0 +1,193 @@
+/*
+ * 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.core.spring;
+
+import static org.springframework.beans.BeanUtils.getPropertyDescriptor;
+import static org.springframework.beans.BeanUtils.getPropertyDescriptors;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
+
+/**
+ * Overrides Spring's BeanUtils not using collection setters but instead getters + addAll() / putAll(),
+ * in a JAXB friendly way.
+ *
+ * Refer to <a href="https://issues.apache.org/jira/browse/SYNCOPE-246">SYNCOPE-246</a> for more information.
+ *
+ * @see org.springframework.beans.BeanUtils
+ */
+public final class BeanUtils {
+
+ private BeanUtils() {
+ // Empty private constructor for static utility classes
+ }
+
+ /**
+ * Copy the property values of the given source bean into the target bean.
+ * <p>
+ * Note: The source and target classes do not have to match or even be derived
+ * from each other, as long as the properties match. Any bean properties that the
+ * source bean exposes but the target bean does not will silently be ignored.
+ * </p><p>
+ * This is just a convenience method. For more complex transfer needs,
+ * consider using a full BeanWrapper.
+ * </p>
+ *
+ * @param source the source bean
+ * @param target the target bean
+ * @see org.springframework.beans.BeanWrapper
+ */
+ public static void copyProperties(final Object source, final Object target) {
+ copyProperties(source, target, null, (String[]) null);
+ }
+
+ /**
+ * Copy the property values of the given source bean into the given target bean,
+ * only setting properties defined in the given "editable" class (or interface).
+ * <p>
+ * Note: The source and target classes do not have to match or even be derived
+ * from each other, as long as the properties match. Any bean properties that the
+ * source bean exposes but the target bean does not will silently be ignored.
+ * </p><p>
+ * This is just a convenience method. For more complex transfer needs,
+ * consider using a full BeanWrapper.
+ * </p>
+ *
+ * @param source the source bean
+ * @param target the target bean
+ * @param editable the class (or interface) to restrict property setting to
+ * @see org.springframework.beans.BeanWrapper
+ */
+ public static void copyProperties(final Object source, final Object target, final Class<?> editable) {
+ copyProperties(source, target, editable, (String[]) null);
+ }
+
+ /**
+ * Copy the property values of the given source bean into the given target bean,
+ * ignoring the given "ignoreProperties".
+ * <p>
+ * Note: The source and target classes do not have to match or even be derived
+ * from each other, as long as the properties match. Any bean properties that the
+ * source bean exposes but the target bean does not will silently be ignored.
+ * </p><p>
+ * This is just a convenience method. For more complex transfer needs,
+ * consider using a full BeanWrapper.
+ * </p>
+ *
+ * @param source the source bean
+ * @param target the target bean
+ * @param ignoreProperties array of property names to ignore
+ * @see org.springframework.beans.BeanWrapper
+ */
+ public static void copyProperties(final Object source, final Object target, final String... ignoreProperties) {
+ copyProperties(source, target, null, ignoreProperties);
+ }
+
+ /**
+ * Copy the property values of the given source bean into the given target bean.
+ * <p>
+ * Note: The source and target classes do not have to match or even be derived
+ * from each other, as long as the properties match. Any bean properties that the
+ * source bean exposes but the target bean does not will silently be ignored.
+ * </p>
+ *
+ * @param source the source bean
+ * @param target the target bean
+ * @param editable the class (or interface) to restrict property setting to
+ * @param ignoreProperties array of property names to ignore
+ * @see org.springframework.beans.BeanWrapper
+ */
+ @SuppressWarnings("unchecked")
+ private static void copyProperties(
+ final Object source, final Object target, final Class<?> editable, final String... ignoreProperties) {
+
+ Assert.notNull(source, "Source must not be null");
+ Assert.notNull(target, "Target must not be null");
+
+ Class<?> actualEditable = target.getClass();
+ if (editable != null) {
+ if (!editable.isInstance(target)) {
+ throw new IllegalArgumentException("Target class [" + target.getClass().getName()
+ + "] not assignable to Editable class [" + editable.getName() + "]");
+ }
+ actualEditable = editable;
+ }
+ PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
+ List<String> ignoreList = (ignoreProperties == null)
+ ? Collections.<String>emptyList() : Arrays.asList(ignoreProperties);
+
+ for (PropertyDescriptor targetPd : targetPds) {
+ if (ignoreProperties == null || (!ignoreList.contains(targetPd.getName()))) {
+ PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
+ if (sourcePd != null) {
+ Method readMethod = sourcePd.getReadMethod();
+ if (readMethod != null) {
+ Method writeMethod = targetPd.getWriteMethod();
+
+ try {
+ // Diverts from Spring's BeanUtils: if no write method is found and property is collection,
+ // try to use addAll() / putAll().
+ if (writeMethod == null) {
+ Object value = readMethod.invoke(source);
+ Method targetReadMethod = targetPd.getReadMethod();
+ if (targetReadMethod != null) {
+ if (!Modifier.isPublic(targetReadMethod.getDeclaringClass().getModifiers())) {
+ targetReadMethod.setAccessible(true);
+ }
+ Object destValue = targetReadMethod.invoke(target);
+
+ if (value instanceof Collection && destValue instanceof Collection) {
+ ((Collection) destValue).clear();
+ ((Collection) destValue).addAll((Collection) value);
+ } else if (value instanceof Map && destValue instanceof Map) {
+ ((Map) destValue).clear();
+ ((Map) destValue).putAll((Map) value);
+ }
+ }
+ } else if (ClassUtils.isAssignable(
+ writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
+
+ if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
+ readMethod.setAccessible(true);
+ }
+ Object value = readMethod.invoke(source);
+ if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
+ writeMethod.setAccessible(true);
+ }
+ writeMethod.invoke(target, value);
+ }
+ } catch (Throwable ex) {
+ throw new FatalBeanException(
+ "Could not copy property '" + targetPd.getName() + "' from source to target", ex);
+ }
+ }
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/DefaultRolesPrefixPostProcessor.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/DefaultRolesPrefixPostProcessor.java b/core/spring/src/main/java/org/apache/syncope/core/spring/DefaultRolesPrefixPostProcessor.java
new file mode 100644
index 0000000..2e197ea
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/DefaultRolesPrefixPostProcessor.java
@@ -0,0 +1,65 @@
+/*
+ * 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.core.spring;
+
+import javax.servlet.ServletException;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.core.PriorityOrdered;
+import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
+import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
+import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
+
+/**
+ * Removes the limitation of having Spring security roles to be prefixed with 'ROLE_'.
+ */
+public class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {
+
+ @Override
+ public Object postProcessAfterInitialization(final Object bean, final String beanName) {
+ if (bean instanceof DefaultMethodSecurityExpressionHandler) {
+ ((DefaultMethodSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
+ }
+ if (bean instanceof DefaultWebSecurityExpressionHandler) {
+ ((DefaultWebSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
+ }
+ if (bean instanceof SecurityContextHolderAwareRequestFilter) {
+ SecurityContextHolderAwareRequestFilter filter = (SecurityContextHolderAwareRequestFilter) bean;
+ filter.setRolePrefix(StringUtils.EMPTY);
+ try {
+ filter.afterPropertiesSet();
+ } catch (ServletException e) {
+ throw new FatalBeanException(e.getMessage(), e);
+ }
+ }
+
+ return bean;
+ }
+
+ @Override
+ public Object postProcessBeforeInitialization(final Object bean, final String beanName) {
+ return bean;
+ }
+
+ @Override
+ public int getOrder() {
+ return PriorityOrdered.HIGHEST_PRECEDENCE;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/ResourceWithFallbackLoader.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/ResourceWithFallbackLoader.java b/core/spring/src/main/java/org/apache/syncope/core/spring/ResourceWithFallbackLoader.java
new file mode 100644
index 0000000..846b575
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/ResourceWithFallbackLoader.java
@@ -0,0 +1,82 @@
+/*
+ * 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.core.spring;
+
+import java.io.IOException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.ResourcePatternResolver;
+
+public class ResourceWithFallbackLoader implements ResourceLoaderAware, ResourcePatternResolver {
+
+ private ResourcePatternResolver resolver;
+
+ private String primary;
+
+ private String fallback;
+
+ @Override
+ public void setResourceLoader(final ResourceLoader resourceLoader) {
+ this.resolver = (ResourcePatternResolver) resourceLoader;
+ }
+
+ public void setPrimary(final String primary) {
+ this.primary = primary;
+ }
+
+ public void setFallback(final String fallback) {
+ this.fallback = fallback;
+ }
+
+ @Override
+ public Resource getResource(final String location) {
+ Resource resource = resolver.getResource(primary + location);
+ if (!resource.exists()) {
+ resource = resolver.getResource(fallback + location);
+ }
+
+ return resource;
+ }
+
+ public Resource getResource() {
+ return getResource(StringUtils.EMPTY);
+ }
+
+ @Override
+ public Resource[] getResources(final String locationPattern) throws IOException {
+ Resource[] resources = resolver.getResources(primary + locationPattern);
+ if (ArrayUtils.isEmpty(resources)) {
+ resources = resolver.getResources(fallback + locationPattern);
+ }
+
+ return resources;
+ }
+
+ public Resource[] getResources() throws IOException {
+ return getResources(StringUtils.EMPTY);
+ }
+
+ @Override
+ public ClassLoader getClassLoader() {
+ return resolver.getClassLoader();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
new file mode 100644
index 0000000..9bc03f7
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthContextUtils.java
@@ -0,0 +1,126 @@
+/*
+ * 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.core.spring.security;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+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;
+import org.springframework.security.core.userdetails.User;
+
+public final class AuthContextUtils {
+
+ public interface Executable<T> {
+
+ T exec();
+ }
+
+ public static String getUsername() {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ return authentication == null ? SyncopeConstants.UNAUTHENTICATED : authentication.getName();
+ }
+
+ public static void updateUsername(final String newUsername) {
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+
+ UsernamePasswordAuthenticationToken newAuth = new UsernamePasswordAuthenticationToken(
+ new User(newUsername, "FAKE_PASSWORD", auth.getAuthorities()),
+ auth.getCredentials(), auth.getAuthorities());
+ newAuth.setDetails(auth.getDetails());
+ SecurityContextHolder.getContext().setAuthentication(newAuth);
+ }
+
+ public static Map<String, Set<String>> getAuthorizations() {
+ Map<String, Set<String>> result = null;
+
+ SecurityContext ctx = SecurityContextHolder.getContext();
+ if (ctx != null && ctx.getAuthentication() != null && ctx.getAuthentication().getAuthorities() != null) {
+ result = new HashMap<>();
+ for (GrantedAuthority authority : ctx.getAuthentication().getAuthorities()) {
+ if (authority instanceof SyncopeGrantedAuthority) {
+ result.put(
+ SyncopeGrantedAuthority.class.cast(authority).getAuthority(),
+ SyncopeGrantedAuthority.class.cast(authority).getRealms());
+ }
+ }
+ }
+
+ return MapUtils.emptyIfNull(result);
+ }
+
+ public static String getDomain() {
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+
+ String domainKey = auth != null && auth.getDetails() instanceof SyncopeAuthenticationDetails
+ ? SyncopeAuthenticationDetails.class.cast(auth.getDetails()).getDomain()
+ : null;
+ if (StringUtils.isBlank(domainKey)) {
+ domainKey = SyncopeConstants.MASTER_DOMAIN;
+ }
+
+ return domainKey;
+ }
+
+ private static void setFakeAuth(final String domain) {
+ List<GrantedAuthority> authorities = CollectionUtils.collect(EntitlementsHolder.getInstance().getValues(),
+ new Transformer<String, GrantedAuthority>() {
+
+ @Override
+ public GrantedAuthority transform(final String entitlement) {
+ return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
+ }
+ }, new ArrayList<GrantedAuthority>());
+
+ UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
+ new User(ApplicationContextProvider.getBeanFactory().getBean("adminUser", String.class),
+ "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
+ auth.setDetails(new SyncopeAuthenticationDetails(domain));
+ SecurityContextHolder.getContext().setAuthentication(auth);
+ }
+
+ public static <T> T execWithAuthContext(final String domainKey, final Executable<T> executable) {
+ SecurityContext ctx = SecurityContextHolder.getContext();
+ setFakeAuth(domainKey);
+ try {
+ return executable.exec();
+ } finally {
+ SecurityContextHolder.clearContext();
+ SecurityContextHolder.setContext(ctx);
+ }
+ }
+
+ /**
+ * Private default constructor, for static-only classes.
+ */
+ private AuthContextUtils() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
new file mode 100644
index 0000000..146eea3
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/AuthDataAccessor.java
@@ -0,0 +1,319 @@
+/*
+ * 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.core.spring.security;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Resource;
+import org.apache.commons.collections4.Closure;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.SetUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ConfDAO;
+import org.apache.syncope.core.persistence.api.dao.DomainDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.Role;
+import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.AuditManager;
+import org.apache.syncope.core.provisioning.api.ConnectorFactory;
+import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.identityconnectors.framework.common.objects.Uid;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.authentication.DisabledException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Domain-sensible (via {@code @Transactional} access to authentication / authorization data.
+ *
+ * @see SyncopeAuthenticationProvider
+ * @see SyncopeAuthenticationDetails
+ */
+public class AuthDataAccessor {
+
+ protected static final Logger LOG = LoggerFactory.getLogger(AuthDataAccessor.class);
+
+ protected static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
+ @Resource(name = "adminUser")
+ protected String adminUser;
+
+ @Resource(name = "anonymousUser")
+ protected String anonymousUser;
+
+ @Autowired
+ protected DomainDAO domainDAO;
+
+ @Autowired
+ protected ConfDAO confDAO;
+
+ @Autowired
+ protected RealmDAO realmDAO;
+
+ @Autowired
+ protected UserDAO userDAO;
+
+ @Autowired
+ protected GroupDAO groupDAO;
+
+ @Autowired
+ protected AnyTypeDAO anyTypeDAO;
+
+ @Autowired
+ protected ConnectorFactory connFactory;
+
+ @Autowired
+ protected AuditManager auditManager;
+
+ @Autowired
+ protected MappingManager mappingManager;
+
+ @Transactional(readOnly = true)
+ public Domain findDomain(final String key) {
+ Domain domain = domainDAO.find(key);
+ if (domain == null) {
+ throw new AuthenticationServiceException("Could not find domain " + key);
+ }
+ return domain;
+ }
+
+ /**
+ * Attempts to authenticate the given credentials against internal storage and pass-through resources (if
+ * configured): the first succeeding causes global success.
+ *
+ * @param authentication given credentials
+ * @return {@code null} if no matching user was found, authentication result otherwise
+ */
+ @Transactional(noRollbackFor = DisabledException.class)
+ public Pair<Long, Boolean> authenticate(final Authentication authentication) {
+ Long key = null;
+ Boolean authenticated = null;
+
+ User user = userDAO.find(authentication.getName());
+ if (user != null) {
+ key = user.getKey();
+ authenticated = false;
+
+ if (user.isSuspended() != null && user.isSuspended()) {
+ throw new DisabledException("User " + user.getUsername() + " is suspended");
+ }
+
+ CPlainAttr authStatuses = confDAO.find("authentication.statuses");
+ if (authStatuses != null && !authStatuses.getValuesAsStrings().contains(user.getStatus())) {
+ throw new DisabledException("User " + user.getUsername() + " not allowed to authenticate");
+ }
+
+ boolean userModified = false;
+ authenticated = authenticate(user, authentication.getCredentials().toString());
+ if (authenticated) {
+ if (confDAO.find("log.lastlogindate", Boolean.toString(true)).getValues().get(0).getBooleanValue()) {
+ user.setLastLoginDate(new Date());
+ userModified = true;
+ }
+
+ if (user.getFailedLogins() != 0) {
+ user.setFailedLogins(0);
+ userModified = true;
+ }
+
+ } else {
+ user.setFailedLogins(user.getFailedLogins() + 1);
+ userModified = true;
+ }
+
+ if (userModified) {
+ userDAO.save(user);
+ }
+ }
+
+ return ImmutablePair.of(key, authenticated);
+ }
+
+ protected boolean authenticate(final User user, final String password) {
+ boolean authenticated = ENCRYPTOR.verify(password, user.getCipherAlgorithm(), user.getPassword());
+ LOG.debug("{} authenticated on internal storage: {}", user.getUsername(), authenticated);
+
+ for (Iterator<? extends ExternalResource> itor = getPassthroughResources(user).iterator();
+ itor.hasNext() && !authenticated;) {
+
+ ExternalResource resource = itor.next();
+ String connObjectKey = null;
+ try {
+ connObjectKey = mappingManager.getConnObjectKeyValue(
+ user, resource.getProvision(anyTypeDAO.findUser()));
+ Uid uid = connFactory.getConnector(resource).authenticate(connObjectKey, password, null);
+ if (uid != null) {
+ authenticated = true;
+ }
+ } catch (Exception e) {
+ LOG.debug("Could not authenticate {} on {}", user.getUsername(), resource.getKey(), e);
+ }
+ LOG.debug("{} authenticated on {} as {}: {}",
+ user.getUsername(), resource.getKey(), connObjectKey, authenticated);
+ }
+
+ return authenticated;
+ }
+
+ protected Set<? extends ExternalResource> getPassthroughResources(final User user) {
+ Set<? extends ExternalResource> result = null;
+
+ // 1. look for assigned resources, pick the ones whose account policy has authentication resources
+ for (ExternalResource resource : userDAO.findAllResources(user)) {
+ if (resource.getAccountPolicy() != null && !resource.getAccountPolicy().getResources().isEmpty()) {
+ if (result == null) {
+ result = resource.getAccountPolicy().getResources();
+ } else {
+ result.retainAll(resource.getAccountPolicy().getResources());
+ }
+ }
+ }
+
+ // 2. look for realms, pick the ones whose account policy has authentication resources
+ for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
+ if (realm.getAccountPolicy() != null && !realm.getAccountPolicy().getResources().isEmpty()) {
+ if (result == null) {
+ result = realm.getAccountPolicy().getResources();
+ } else {
+ result.retainAll(realm.getAccountPolicy().getResources());
+ }
+ }
+ }
+
+ return SetUtils.emptyIfNull(result);
+ }
+
+ @Transactional(readOnly = true)
+ public void audit(
+ final AuditElements.EventCategoryType type,
+ final String category,
+ final String subcategory,
+ final String event,
+ final AuditElements.Result result,
+ final Object before,
+ final Object output,
+ final Object... input) {
+
+ auditManager.audit(type, category, subcategory, event, result, before, output, input);
+ }
+
+ @Transactional
+ public Set<SyncopeGrantedAuthority> load(final String username) {
+ final Set<SyncopeGrantedAuthority> authorities = new HashSet<>();
+ if (anonymousUser.equals(username)) {
+ authorities.add(new SyncopeGrantedAuthority(StandardEntitlement.ANONYMOUS));
+ } else if (adminUser.equals(username)) {
+ CollectionUtils.collect(
+ EntitlementsHolder.getInstance().getValues(),
+ new Transformer<String, SyncopeGrantedAuthority>() {
+
+ @Override
+ public SyncopeGrantedAuthority transform(final String entitlement) {
+ return new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM);
+ }
+ }, authorities);
+ } else {
+ User user = userDAO.find(username);
+ if (user == null) {
+ throw new UsernameNotFoundException("Could not find any user with id " + username);
+ }
+
+ if (user.isMustChangePassword()) {
+ authorities.add(new SyncopeGrantedAuthority(StandardEntitlement.MUST_CHANGE_PASSWORD));
+ } else {
+ final Map<String, Set<String>> entForRealms = new HashMap<>();
+
+ // Give entitlements as assigned by roles (with realms, where applicable) - assigned either
+ // statically and dynamically
+ for (final Role role : userDAO.findAllRoles(user)) {
+ IterableUtils.forEach(role.getEntitlements(), new Closure<String>() {
+
+ @Override
+ public void execute(final String entitlement) {
+ Set<String> realms = entForRealms.get(entitlement);
+ if (realms == null) {
+ realms = new HashSet<>();
+ entForRealms.put(entitlement, realms);
+ }
+
+ CollectionUtils.collect(role.getRealms(), new Transformer<Realm, String>() {
+
+ @Override
+ public String transform(final Realm realm) {
+ return realm.getFullPath();
+ }
+ }, realms);
+ }
+ });
+ }
+
+ // Give group entitlements for owned groups
+ for (Group group : groupDAO.findOwnedByUser(user.getKey())) {
+ for (String entitlement : Arrays.asList(
+ StandardEntitlement.GROUP_READ,
+ StandardEntitlement.GROUP_UPDATE,
+ StandardEntitlement.GROUP_DELETE)) {
+
+ Set<String> realms = entForRealms.get(entitlement);
+ if (realms == null) {
+ realms = new HashSet<>();
+ entForRealms.put(entitlement, realms);
+ }
+
+ realms.add(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey()));
+ }
+ }
+
+ // Finally normalize realms for each given entitlement and generate authorities
+ for (Map.Entry<String, Set<String>> entry : entForRealms.entrySet()) {
+ SyncopeGrantedAuthority authority = new SyncopeGrantedAuthority(entry.getKey());
+ authority.addRealms(RealmUtils.normalize(entry.getValue()));
+ authorities.add(authority);
+ }
+ }
+ }
+
+ return authorities;
+ }
+}
[12/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
index ae07439..6c00347 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
@@ -50,7 +50,7 @@ import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
import org.apache.syncope.core.persistence.api.entity.task.AnyTemplateSyncTask;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncActions;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeBuilder;
import org.junit.Test;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index 0787b63..02f9529 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -1015,7 +1015,7 @@ under the License.
template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[{"schema":"virtualReadOnly","readonly":true,"values":[""]}],"resources":["resource-ldap"],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynGroups":[],"plainAttrs":[]}'/>
<AnyTemplateSyncTask id="2" syncTask_id="11" anyType_name="GROUP"
template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"plainAttrs":[{"schema":"show","readonly":false,"values":["true"]}]}'/>
- <SyncTask_actionsClassNames SyncTask_id="11" actionClassName="org.apache.syncope.core.provisioning.java.sync.LDAPMembershipSyncActions"/>
+ <SyncTask_actionsClassNames SyncTask_id="11" actionClassName="org.apache.syncope.core.provisioning.java.syncpull.LDAPMembershipSyncActions"/>
<Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="12" name="VirAttrCache test" resource_name="resource-csv"
destinationRealm_id="1" performCreate="0" performUpdate="1" performDelete="0" syncStatus="0" syncMode="FULL_RECONCILIATION"
unmatchingRule="PROVISION" matchingRule="UPDATE" active="1"/>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml b/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
index c7e7a9b..506c068 100644
--- a/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
+++ b/core/persistence-jpa/src/test/resources/domains/TwoDomain.xml
@@ -28,11 +28,11 @@ under the License.
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
- <bean id="TwoContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="TwoContentXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${content.directory}/domains/TwoContent.xml"/>
<property name="fallback" value="classpath:domains/TwoContent.xml"/>
</bean>
- <bean id="TwoProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="TwoProperties" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${content.directory}/domains/Two.properties"/>
<property name="fallback" value="classpath:domains/Two.properties"/>
</bean>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/resources/persistenceTest.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/persistenceTest.xml b/core/persistence-jpa/src/test/resources/persistenceTest.xml
index 2874cac..b4d7125 100644
--- a/core/persistence-jpa/src/test/resources/persistenceTest.xml
+++ b/core/persistence-jpa/src/test/resources/persistenceTest.xml
@@ -37,7 +37,7 @@ under the License.
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
- <bean class="org.apache.syncope.core.misc.spring.ApplicationContextProvider"/>
+ <bean class="org.apache.syncope.core.spring.ApplicationContextProvider"/>
<bean id="adminUser" class="java.lang.String">
<constructor-arg value="${adminUser}"/>
@@ -46,10 +46,9 @@ under the License.
<constructor-arg value="${anonymousUser}"/>
</bean>
- <context:component-scan base-package="org.apache.syncope.core.misc.policy"/>
- <context:component-scan base-package="org.apache.syncope.core.misc.security"/>
+ <context:component-scan base-package="org.apache.syncope.core.spring.security"/>
- <bean class="org.apache.syncope.core.misc.security.DefaultPasswordGenerator"/>
+ <bean class="org.apache.syncope.core.spring.security.DefaultPasswordGenerator"/>
<import resource="persistenceContext.xml"/>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 35a4958..2dd6e3f 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -79,7 +79,7 @@ under the License.
<modules>
<module>persistence-api</module>
<module>persistence-jpa</module>
- <module>misc</module>
+ <module>spring</module>
<module>provisioning-api</module>
<module>provisioning-java</module>
<module>workflow-api</module>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/pom.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-api/pom.xml b/core/provisioning-api/pom.xml
index 8bc9432..856a932 100644
--- a/core/provisioning-api/pom.xml
+++ b/core/provisioning-api/pom.xml
@@ -39,6 +39,19 @@ under the License.
<dependencies>
<dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.module</groupId>
+ <artifactId>jackson-module-afterburner</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
</dependency>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.java
new file mode 100644
index 0000000..58b0303
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditManager.java
@@ -0,0 +1,35 @@
+/*
+ * 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.core.provisioning.api;
+
+import org.apache.syncope.common.lib.types.AuditElements;
+
+public interface AuditManager {
+
+ void audit(
+ AuditElements.EventCategoryType type,
+ String category,
+ String subcategory,
+ String event,
+ AuditElements.Result result,
+ Object before,
+ Object output,
+ Object... input);
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnPoolConfUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnPoolConfUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnPoolConfUtils.java
deleted file mode 100644
index 55216ae..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnPoolConfUtils.java
+++ /dev/null
@@ -1,69 +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.core.provisioning.api;
-
-import org.apache.syncope.common.lib.to.ConnPoolConfTO;
-import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
-import org.identityconnectors.common.pooling.ObjectPoolConfiguration;
-
-public final class ConnPoolConfUtils {
-
- 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 ConnPoolConfUtils() {
- // empty constructor for static utility class
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java
index 7aed2ca..b637508 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java
@@ -34,7 +34,7 @@ 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;
-import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder;
+import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
/**
* Entry point for making requests on underlying connector bundles.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java
new file mode 100644
index 0000000..d67362f
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/EntitlementsHolder.java
@@ -0,0 +1,72 @@
+/*
+ * 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.core.provisioning.api;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.syncope.common.lib.types.AnyEntitlement;
+
+public final class EntitlementsHolder {
+
+ private static final Object MONITOR = new Object();
+
+ private static EntitlementsHolder INSTANCE;
+
+ public static EntitlementsHolder getInstance() {
+ synchronized (MONITOR) {
+ if (INSTANCE == null) {
+ INSTANCE = new EntitlementsHolder();
+ }
+ }
+ return INSTANCE;
+ }
+
+ private final Set<String> values = Collections.synchronizedSet(new HashSet<String>());
+
+ private EntitlementsHolder() {
+ // private constructor for singleton
+ }
+
+ public void init(final Collection<String> values) {
+ this.values.addAll(values);
+ }
+
+ public String getFor(final String anyTypeKey, final AnyEntitlement operation) {
+ return anyTypeKey + "_" + operation.name();
+ }
+
+ public void addFor(final String anyType) {
+ for (AnyEntitlement operation : AnyEntitlement.values()) {
+ this.values.add(getFor(anyType, operation));
+ }
+ }
+
+ public void removeFor(final String anyType) {
+ for (AnyEntitlement operation : AnyEntitlement.values()) {
+ this.values.remove(getFor(anyType, operation));
+ }
+ }
+
+ public Set<String> getValues() {
+ return Collections.unmodifiableSet(values);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
new file mode 100644
index 0000000..4600f9a
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java
@@ -0,0 +1,78 @@
+/*
+ * 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.core.provisioning.api;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.identityconnectors.framework.common.objects.Attribute;
+
+public interface MappingManager {
+
+ /**
+ * Get connObjectKey internal value.
+ *
+ * @param any any object
+ * @param provision provision information
+ * @return connObjectKey internal value
+ */
+ String getConnObjectKeyValue(Any<?> any, Provision provision);
+
+ /**
+ * Get attribute values for the given {@link MappingItem} and any objects.
+ *
+ * @param provision provision information
+ * @param mappingItem mapping item
+ * @param anys any objects
+ * @return attribute values.
+ */
+ List<PlainAttrValue> getIntValues(Provision provision, MappingItem mappingItem, List<Any<?>> anys);
+
+ /**
+ * Prepare attributes for sending to a connector instance.
+ *
+ * @param any given any object
+ * @param password clear-text password
+ * @param changePwd whether password should be included for propagation attributes or not
+ * @param enable whether any object must be enabled or not
+ * @param provision provision information
+ * @return connObjectLink + prepared attributes
+ */
+ Pair<String, Set<Attribute>> prepareAttrs(
+ Any<?> any, String password, boolean changePwd, Boolean enable, Provision provision);
+
+ /**
+ * Set attribute values, according to the given {@link MappingItem}, to any object from attribute received from
+ * connector.
+ *
+ * @param <T> any object
+ * @param mappingItem mapping item
+ * @param attr attribute received from connector
+ * @param anyTO any object
+ * @param anyUtils any utils
+ */
+ <T extends AnyTO> void setIntValues(MappingItem mappingItem, Attribute attr, T anyTO, AnyUtils anyUtils);
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/URIUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/URIUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/URIUtils.java
deleted file mode 100644
index 91fd0c2..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/URIUtils.java
+++ /dev/null
@@ -1,61 +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.core.provisioning.api;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-
-public final class URIUtils {
-
- private URIUtils() {
- // empty constructor for static utility class
- }
-
- /**
- * Build a valid URI out of the given location.
- * Only "file", "connid" and "connids" schemes are allowed.
- * For "file", invalid characters are handled via intermediate transformation into URL.
- *
- * @param location the candidate location for URI
- * @return valid URI for the given location
- * @throws MalformedURLException if the intermediate URL is not valid
- * @throws URISyntaxException if the given location does not correspond to a valid URI
- */
- public static URI buildForConnId(final String location) throws MalformedURLException, URISyntaxException {
- final String candidate = location.trim();
-
- if (!candidate.startsWith("file:")
- && !candidate.startsWith("connid:") && !candidate.startsWith("connids:")) {
-
- throw new IllegalArgumentException(candidate + " is not a valid URI for file or connid(s) schemes");
- }
-
- URI uri;
- if (candidate.startsWith("file:")) {
- uri = new File(new URL(candidate).getFile()).getAbsoluteFile().toURI();
- } else {
- uri = new URI(candidate);
- }
-
- return uri;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
index 1f9b7ef..cf198fe 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java
@@ -26,7 +26,7 @@ import org.apache.syncope.common.lib.patch.StatusPatch;
import org.apache.syncope.common.lib.patch.UserPatch;
import org.apache.syncope.common.lib.to.PropagationStatus;
import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
public interface UserProvisioningManager extends ProvisioningManager<UserTO, UserPatch> {
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeDeserializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeDeserializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeDeserializer.java
new file mode 100644
index 0000000..5c563c9
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeDeserializer.java
@@ -0,0 +1,83 @@
+/*
+ * 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.core.provisioning.api.serialization;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.common.security.GuardedString;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.identityconnectors.framework.common.objects.Name;
+import org.identityconnectors.framework.common.objects.Uid;
+
+class AttributeDeserializer extends JsonDeserializer<Attribute> {
+
+ @Override
+ public Attribute deserialize(final JsonParser jp, final DeserializationContext ctx)
+ throws IOException {
+
+ ObjectNode tree = jp.readValueAsTree();
+
+ String name = tree.get("name").asText();
+
+ List<Object> values = new ArrayList<Object>();
+ for (Iterator<JsonNode> itor = tree.get("value").iterator(); itor.hasNext();) {
+ JsonNode node = itor.next();
+ if (node.isNull()) {
+ values.add(null);
+ } else if (node.isObject()) {
+ values.add(((ObjectNode) node).traverse(jp.getCodec()).readValueAs(GuardedString.class));
+ } else if (node.isBoolean()) {
+ values.add(node.asBoolean());
+ } else if (node.isDouble()) {
+ values.add(node.asDouble());
+ } else if (node.isLong()) {
+ values.add(node.asLong());
+ } else if (node.isInt()) {
+ values.add(node.asInt());
+ } else {
+ String text = node.asText();
+ if (text.startsWith(AttributeSerializer.BYTE_ARRAY_PREFIX)
+ && text.endsWith(AttributeSerializer.BYTE_ARRAY_SUFFIX)) {
+
+ values.add(Base64.decode(StringUtils.substringBetween(
+ text, AttributeSerializer.BYTE_ARRAY_PREFIX, AttributeSerializer.BYTE_ARRAY_SUFFIX)));
+ } else {
+ values.add(text);
+ }
+ }
+ }
+
+ return Uid.NAME.equals(name)
+ ? new Uid(values.isEmpty() || values.get(0) == null ? null : values.get(0).toString())
+ : Name.NAME.equals(name)
+ ? new Name(values.isEmpty() || values.get(0) == null ? null : values.get(0).toString())
+ : AttributeBuilder.build(name, values);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeSerializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeSerializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeSerializer.java
new file mode 100644
index 0000000..f8b0fbf
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/AttributeSerializer.java
@@ -0,0 +1,73 @@
+/*
+ * 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.core.provisioning.api.serialization;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import java.io.IOException;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.common.security.GuardedString;
+import org.identityconnectors.framework.common.objects.Attribute;
+
+class AttributeSerializer extends JsonSerializer<Attribute> {
+
+ public static final String BYTE_ARRAY_PREFIX = "<binary>";
+
+ public static final String BYTE_ARRAY_SUFFIX = "</binary>";
+
+ @Override
+ public void serialize(final Attribute source, final JsonGenerator jgen, final SerializerProvider sp)
+ throws IOException {
+
+ jgen.writeStartObject();
+
+ jgen.writeStringField("name", source.getName());
+
+ jgen.writeFieldName("value");
+ if (source.getValue() == null) {
+ jgen.writeNull();
+ } else {
+ jgen.writeStartArray();
+ for (Object value : source.getValue()) {
+ if (value == null) {
+ jgen.writeNull();
+ } else if (value instanceof GuardedString) {
+ jgen.writeObject(value);
+ } else if (value instanceof Integer) {
+ jgen.writeNumber((Integer) value);
+ } else if (value instanceof Long) {
+ jgen.writeNumber((Long) value);
+ } else if (value instanceof Double) {
+ jgen.writeNumber((Double) value);
+ } else if (value instanceof Boolean) {
+ jgen.writeBoolean((Boolean) value);
+ } else if (value instanceof byte[]) {
+ jgen.writeString(BYTE_ARRAY_PREFIX + Base64.encode((byte[]) value) + BYTE_ARRAY_SUFFIX);
+ } else {
+ jgen.writeString(value.toString());
+ }
+ }
+ jgen.writeEndArray();
+ }
+
+ jgen.writeEndObject();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringDeserializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringDeserializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringDeserializer.java
new file mode 100644
index 0000000..a75319e
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringDeserializer.java
@@ -0,0 +1,93 @@
+/*
+ * 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.core.provisioning.api.serialization;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.common.security.EncryptorFactory;
+import org.identityconnectors.common.security.GuardedString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class GuardedStringDeserializer extends JsonDeserializer<GuardedString> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GuardedStringDeserializer.class);
+
+ @Override
+ public GuardedString deserialize(final JsonParser jp, final DeserializationContext ctx)
+ throws IOException {
+
+ ObjectNode tree = jp.readValueAsTree();
+
+ boolean readOnly = false;
+ if (tree.has("readOnly")) {
+ readOnly = tree.get("readOnly").asBoolean();
+ }
+ boolean disposed = false;
+ if (tree.has("disposed")) {
+ disposed = tree.get("disposed").asBoolean();
+ }
+ byte[] encryptedBytes = null;
+ if (tree.has("encryptedBytes")) {
+ encryptedBytes = Base64.decode(tree.get("encryptedBytes").asText());
+ }
+ String base64SHA1Hash = null;
+ if (tree.has("base64SHA1Hash")) {
+ base64SHA1Hash = tree.get("base64SHA1Hash").asText();
+ }
+
+ final byte[] clearBytes = EncryptorFactory.getInstance().getDefaultEncryptor().decrypt(encryptedBytes);
+
+ GuardedString dest = new GuardedString(new String(clearBytes).toCharArray());
+
+ try {
+ Field field = GuardedString.class.getDeclaredField("readOnly");
+ field.setAccessible(true);
+ field.setBoolean(dest, readOnly);
+ } catch (Exception e) {
+ LOG.error("Could not set field value to {}", readOnly, e);
+ }
+
+ try {
+ Field field = GuardedString.class.getDeclaredField("disposed");
+ field.setAccessible(true);
+ field.setBoolean(dest, disposed);
+ } catch (Exception e) {
+ LOG.error("Could not set field value to {}", disposed, e);
+ }
+
+ if (base64SHA1Hash != null) {
+ try {
+ Field field = GuardedString.class.getDeclaredField("base64SHA1Hash");
+ field.setAccessible(true);
+ field.set(dest, base64SHA1Hash);
+ } catch (Exception e) {
+ LOG.error("Could not set field value to {}", base64SHA1Hash, e);
+ }
+ }
+
+ return dest;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringSerializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringSerializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringSerializer.java
new file mode 100644
index 0000000..49cc87d
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/GuardedStringSerializer.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.core.provisioning.api.serialization;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.common.security.EncryptorFactory;
+import org.identityconnectors.common.security.GuardedString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class GuardedStringSerializer extends JsonSerializer<GuardedString> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GuardedStringSerializer.class);
+
+ @Override
+ public void serialize(final GuardedString source, final JsonGenerator jgen, final SerializerProvider sp)
+ throws IOException {
+
+ jgen.writeStartObject();
+
+ boolean readOnly = false;
+ try {
+ Field field = GuardedString.class.getDeclaredField("readOnly");
+ field.setAccessible(true);
+ readOnly = field.getBoolean(source);
+ } catch (Exception e) {
+ LOG.error("Could not get field value", e);
+ }
+ jgen.writeBooleanField("readOnly", readOnly);
+
+ boolean disposed = false;
+ try {
+ Field field = GuardedString.class.getDeclaredField("disposed");
+ field.setAccessible(true);
+ disposed = field.getBoolean(source);
+ } catch (Exception e) {
+ LOG.error("Could not get field value", e);
+ }
+ jgen.writeBooleanField("disposed", disposed);
+
+ final StringBuilder cleartext = new StringBuilder();
+ source.access(new GuardedString.Accessor() {
+
+ @Override
+ public void access(final char[] clearChars) {
+ cleartext.append(clearChars);
+ }
+ });
+ byte[] encryptedBytes =
+ EncryptorFactory.getInstance().getDefaultEncryptor().encrypt(cleartext.toString().getBytes());
+ jgen.writeStringField("encryptedBytes", Base64.encode(encryptedBytes));
+
+ String base64SHA1Hash = null;
+ try {
+ Field field = GuardedString.class.getDeclaredField("base64SHA1Hash");
+ field.setAccessible(true);
+ base64SHA1Hash = field.get(source).toString();
+ } catch (Exception e) {
+ LOG.error("Could not get field value", e);
+ }
+ if (base64SHA1Hash != null) {
+ jgen.writeStringField("base64SHA1Hash", base64SHA1Hash);
+ }
+
+ jgen.writeEndObject();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java
new file mode 100644
index 0000000..25e4316
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java
@@ -0,0 +1,80 @@
+/*
+ * 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.core.provisioning.api.serialization;
+
+import com.fasterxml.jackson.core.Version;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
+import org.identityconnectors.common.security.GuardedString;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.SyncToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper class for serialization and deserialization of configuration objects (POJOs) in JSON.
+ */
+public final class POJOHelper {
+
+ private static final Logger LOG = LoggerFactory.getLogger(POJOHelper.class);
+
+ private static final ObjectMapper MAPPER;
+
+ static {
+ SimpleModule pojoModule = new SimpleModule("POJOModule", new Version(1, 0, 0, null, null, null));
+ pojoModule.addSerializer(GuardedString.class, new GuardedStringSerializer());
+ pojoModule.addSerializer(Attribute.class, new AttributeSerializer());
+ pojoModule.addSerializer(SyncToken.class, new SyncTokenSerializer());
+ pojoModule.addDeserializer(GuardedString.class, new GuardedStringDeserializer());
+ pojoModule.addDeserializer(Attribute.class, new AttributeDeserializer());
+ pojoModule.addDeserializer(SyncToken.class, new SyncTokenDeserializer());
+
+ MAPPER = new ObjectMapper();
+ MAPPER.registerModule(pojoModule);
+ MAPPER.registerModule(new AfterburnerModule());
+ }
+
+ public static String serialize(final Object object) {
+ String result = null;
+
+ try {
+ result = MAPPER.writeValueAsString(object);
+ } catch (Exception e) {
+ LOG.error("During serialization", e);
+ }
+
+ return result;
+ }
+
+ public static <T extends Object> T deserialize(final String serialized, final Class<T> reference) {
+ T result = null;
+
+ try {
+ result = MAPPER.readValue(serialized, reference);
+ } catch (Exception e) {
+ LOG.error("During deserialization", e);
+ }
+
+ return result;
+ }
+
+ private POJOHelper() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenDeserializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenDeserializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenDeserializer.java
new file mode 100644
index 0000000..3f8dc4d
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenDeserializer.java
@@ -0,0 +1,66 @@
+/*
+ * 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.core.provisioning.api.serialization;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.framework.common.objects.SyncToken;
+
+class SyncTokenDeserializer extends JsonDeserializer<SyncToken> {
+
+ @Override
+ public SyncToken deserialize(final JsonParser jp, final DeserializationContext ctx)
+ throws IOException {
+
+ ObjectNode tree = jp.readValueAsTree();
+
+ Object value = null;
+ if (tree.has("value")) {
+ JsonNode node = tree.get("value");
+ value = node.isNull()
+ ? null
+ : node.isBoolean()
+ ? node.asBoolean()
+ : node.isDouble()
+ ? node.asDouble()
+ : node.isLong()
+ ? node.asLong()
+ : node.isInt()
+ ? node.asInt()
+ : node.asText();
+
+ if (value instanceof String) {
+ String base64 = (String) value;
+ try {
+ value = Base64.decode(base64);
+ } catch (RuntimeException e) {
+ value = base64;
+ }
+ }
+ }
+
+ return new SyncToken(value);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenSerializer.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenSerializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenSerializer.java
new file mode 100644
index 0000000..f9d2ee5
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/SyncTokenSerializer.java
@@ -0,0 +1,57 @@
+/*
+ * 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.core.provisioning.api.serialization;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import java.io.IOException;
+import org.identityconnectors.common.Base64;
+import org.identityconnectors.framework.common.objects.SyncToken;
+
+class SyncTokenSerializer extends JsonSerializer<SyncToken> {
+
+ @Override
+ public void serialize(final SyncToken source, final JsonGenerator jgen, final SerializerProvider sp)
+ throws IOException {
+
+ jgen.writeStartObject();
+
+ jgen.writeFieldName("value");
+
+ if (source.getValue() == null) {
+ jgen.writeNull();
+ } else if (source.getValue() instanceof Boolean) {
+ jgen.writeBoolean((Boolean) source.getValue());
+ } else if (source.getValue() instanceof Double) {
+ jgen.writeNumber((Double) source.getValue());
+ } else if (source.getValue() instanceof Long) {
+ jgen.writeNumber((Long) source.getValue());
+ } else if (source.getValue() instanceof Integer) {
+ jgen.writeNumber((Integer) source.getValue());
+ } else if (source.getValue() instanceof byte[]) {
+ jgen.writeString(Base64.encode((byte[]) source.getValue()));
+ } else {
+ jgen.writeString(source.getValue().toString());
+ }
+
+ jgen.writeEndObject();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectPushResultHandler.java
deleted file mode 100644
index 6691db3..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectPushResultHandler.java
+++ /dev/null
@@ -1,23 +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.core.provisioning.api.sync;
-
-public interface AnyObjectPushResultHandler extends SyncopePushResultHandler {
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectSyncResultHandler.java
deleted file mode 100644
index e0ad1d8..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/AnyObjectSyncResultHandler.java
+++ /dev/null
@@ -1,23 +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.core.provisioning.api.sync;
-
-public interface AnyObjectSyncResultHandler extends SyncopeSyncResultHandler {
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupPushResultHandler.java
deleted file mode 100644
index d22d4e7..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupPushResultHandler.java
+++ /dev/null
@@ -1,23 +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.core.provisioning.api.sync;
-
-public interface GroupPushResultHandler extends SyncopePushResultHandler {
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupSyncResultHandler.java
deleted file mode 100644
index 907c29c..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/GroupSyncResultHandler.java
+++ /dev/null
@@ -1,26 +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.core.provisioning.api.sync;
-
-import java.util.Map;
-
-public interface GroupSyncResultHandler extends SyncopeSyncResultHandler {
-
- Map<Long, String> getGroupOwnerMap();
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/IgnoreProvisionException.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/IgnoreProvisionException.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/IgnoreProvisionException.java
deleted file mode 100644
index 8bc9da5..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/IgnoreProvisionException.java
+++ /dev/null
@@ -1,29 +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.core.provisioning.api.sync;
-
-/**
- * Raised by {@link SyncActions} or {@link PushActions} methods when the given any object is to be ignored for
- * synchronization / push.
- */
-public class IgnoreProvisionException extends RuntimeException {
-
- private static final long serialVersionUID = -8803817097998786364L;
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningActions.java
deleted file mode 100644
index 02e6979..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningActions.java
+++ /dev/null
@@ -1,40 +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.core.provisioning.api.sync;
-
-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 ProvisioningProfile<?, ?> profile) throws JobExecutionException;
-
- /**
- * Action to be executed after the synchronization task completion.
- *
- * @param profile sync profile
- * @throws JobExecutionException in case of generic failure
- */
- void afterAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException;
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningProfile.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningProfile.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningProfile.java
deleted file mode 100644
index 2e6e055..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningProfile.java
+++ /dev/null
@@ -1,81 +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.core.provisioning.api.sync;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.apache.syncope.common.lib.types.ConflictResolutionAction;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.provisioning.api.Connector;
-
-public class ProvisioningProfile<T extends ProvisioningTask, A extends ProvisioningActions> {
-
- /**
- * Syncing connector.
- */
- private final Connector connector;
-
- private final T task;
-
- private final List<ProvisioningReport> results = new ArrayList<>();
-
- private boolean dryRun;
-
- private ConflictResolutionAction resAct;
-
- private final List<A> actions = new ArrayList<>();
-
- public ProvisioningProfile(final Connector connector, final T task) {
- this.connector = connector;
- this.task = task;
- }
-
- public Connector getConnector() {
- return connector;
- }
-
- public T getTask() {
- return task;
- }
-
- public Collection<ProvisioningReport> 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;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningReport.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningReport.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningReport.java
deleted file mode 100644
index 9e3c28a..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ProvisioningReport.java
+++ /dev/null
@@ -1,140 +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.core.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.ResourceOperation;
-import org.apache.syncope.common.lib.types.TraceLevel;
-
-public class ProvisioningReport {
-
- public enum Status {
-
- SUCCESS,
- IGNORE,
- FAILURE
-
- }
-
- private String message;
-
- private Status status;
-
- private String anyType;
-
- private ResourceOperation operation;
-
- private Long key;
-
- 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 getKey() {
- return key;
- }
-
- public void setKey(final Long key) {
- this.key = key;
- }
-
- public Status getStatus() {
- return status;
- }
-
- public void setStatus(final Status status) {
- this.status = status;
- }
-
- public String getAnyType() {
- return anyType;
- }
-
- public void setAnyType(final String anyType) {
- this.anyType = anyType;
- }
-
- 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, key, name, message);
- } else {
- // All
- return String.format("%s %s (id/name): %d/%s %s", operation, status, key, 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<ProvisioningReport> results, final TraceLevel level) {
- StringBuilder sb = new StringBuilder();
- for (ProvisioningReport result : results) {
- sb.append(result.getReportString(level)).append('\n');
- }
- return sb.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
deleted file mode 100644
index c6d75ae..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
+++ /dev/null
@@ -1,163 +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.core.provisioning.api.sync;
-
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.quartz.JobExecutionException;
-
-/**
- * Interface for actions to be performed during push.
- * All methods can throw {@link IgnoreProvisionException} to make the current any ignored by the push process.
- */
-public interface PushActions extends ProvisioningActions {
-
- /**
- * Action to be executed before to assign (link & provision) a synchronized any object to the resource.
- *
- * @param <A> concrete any object
- * @param profile profile of the push being executed.
- * @param any any object to be created.
- * @return any.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends Any<?>> A beforeAssign(
- ProvisioningProfile<?, ?> profile,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before to provision a synchronized any object to the resource.
- *
- * @param <A> concrete any object
- * @param profile profile of the push being executed.
- * @param any any object to be created.
- * @return any.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends Any<?>> A beforeProvision(
- ProvisioningProfile<?, ?> profile,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before to update a synchronized any object on the resource.
- *
- * @param <A> concrete any object
- * @param profile profile of the push being executed.
- * @param any any object to be updated.
- * @return any.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends Any<?>> A beforeUpdate(
- ProvisioningProfile<?, ?> profile,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before to link a synchronized any object to the resource.
- *
- * @param <A> concrete any object
- * @param profile profile of the push being executed.
- * @param any any object to be created.
- * @return any.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends Any<?>> A beforeLink(
- ProvisioningProfile<?, ?> profile,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before to unlink a synchronized any object from the resource.
- *
- * @param <A> concrete any object
- * @param profile profile of the push being executed.
- * @param any any object to be created.
- * @return any.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends Any<?>> A beforeUnlink(
- ProvisioningProfile<?, ?> profile,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before to unassign a synchronized any object from the resource.
- *
- * @param <A> concrete any object
- * @param profile profile of the push being executed.
- * @param any any object to be created.
- * @return any.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends Any<?>> A beforeUnassign(
- ProvisioningProfile<?, ?> profile,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before to unassign a synchronized any object from the resource.
- *
- * @param <A> concrete any object
- * @param profile profile of the push being executed.
- * @param any any object to be created.
- * @return any.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends Any<?>> A beforeDeprovision(
- ProvisioningProfile<?, ?> profile,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before delete a synchronized any object locally and from the resource.
- *
- * @param <A> concrete any object
- * @param profile profile of the push being executed.
- * @param any any object to be created.
- * @return any.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends Any<?>> A beforeDelete(
- ProvisioningProfile<?, ?> profile,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed after any object push goes on error.
- *
- * @param <A> concrete any object
- * @param profile profile of the push being executed.
- * @param any synchronized any object.
- * @param result operation result.
- * @param error error being reported
- * @throws JobExecutionException in case of generic failure
- */
- <A extends Any<?>> void onError(
- ProvisioningProfile<?, ?> profile,
- A any,
- ProvisioningReport result,
- Exception error) throws JobExecutionException;
-
- /**
- * Action to be executed after each local any object push.
- *
- * @param <A> concrete any object
- * @param profile profile of the push being executed.
- * @param any synchronized any object.
- * @param result operation result.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends Any<?>> void after(
- ProvisioningProfile<?, ?> profile,
- A any,
- ProvisioningReport result) throws JobExecutionException;
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ReconciliationFilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ReconciliationFilterBuilder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ReconciliationFilterBuilder.java
deleted file mode 100644
index 874215b..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/ReconciliationFilterBuilder.java
+++ /dev/null
@@ -1,30 +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.core.provisioning.api.sync;
-
-import org.identityconnectors.framework.common.objects.filter.Filter;
-
-/**
- * Interface to be implemented for performing filtered reconciliation of a
- * {@link org.apache.syncope.core.persistence.api.entity.task.SyncTask}.
- */
-public interface ReconciliationFilterBuilder {
-
- Filter build();
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
deleted file mode 100644
index 2440a1a..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
+++ /dev/null
@@ -1,203 +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.core.provisioning.api.sync;
-
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.quartz.JobExecutionException;
-
-/**
- * Interface for actions to be performed during synchronization.
- * All methods can throw {@link IgnoreProvisionException} to make the current any object ignored by the synchronization
- * process.
- */
-public interface SyncActions extends ProvisioningActions {
-
- /**
- * Action to be executed before to create a synchronized user / group locally.
- * User/group is created locally upon synchronization in case of the un-matching rule
- * {@link org.apache.syncope.common.lib.types.UnmatchingRule#PROVISION} (default un-matching rule) is applied.
- *
- * @param <A> concrete any object
- * @param profile profile of the synchronization being executed.
- * @param delta retrieved synchronization information
- * @param any any object
- * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends AnyTO> SyncDelta beforeProvision(
- ProvisioningProfile<?, ?> profile,
- SyncDelta delta,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before creating (and linking to the resource) a synchronized user / group locally.
- * User/group is created locally and linked to the synchronized resource upon synchronization in case of the
- * un-matching rule {@link org.apache.syncope.common.lib.types.UnmatchingRule#ASSIGN} is applied.
- *
- * @param <A> concrete any object
- * @param profile profile of the synchronization being executed.
- * @param delta retrieved synchronization information
- * @param any any object
- * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends AnyTO> SyncDelta beforeAssign(
- ProvisioningProfile<?, ?> profile,
- SyncDelta delta,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before unlinking resource from the synchronized user / group and de-provisioning.
- * User/group is unlinked and de-provisioned from the synchronized resource upon synchronization in case of the
- * matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#UNASSIGN} is applied.
- *
- * @param <A> concrete any object
- * @param profile profile of the synchronization being executed.
- * @param delta retrieved synchronization information
- * @param any any object
- * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends AnyTO> SyncDelta beforeUnassign(
- ProvisioningProfile<?, ?> profile,
- SyncDelta delta,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before de-provisioning action only.
- * User/group is de-provisioned (without unlinking) from the synchronized resource upon synchronization in case of
- * the matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#DEPROVISION} is applied.
- *
- * @param <A> concrete any object
- * @param profile profile of the synchronization being executed.
- * @param delta retrieved synchronization information
- * @param any any object
- * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends AnyTO> SyncDelta beforeDeprovision(
- ProvisioningProfile<?, ?> profile,
- SyncDelta delta,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before unlinking resource from the synchronized user / group.
- * User/group is unlinked (without de-provisioning) from the synchronized resource upon synchronization in case of
- * the matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#UNLINK} is applied.
- *
- * @param <A> concrete any object
- * @param profile profile of the synchronization being executed.
- * @param delta retrieved synchronization information
- * @param any any object
- * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends AnyTO> SyncDelta beforeUnlink(
- ProvisioningProfile<?, ?> profile,
- SyncDelta delta,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before linking resource to the synchronized user / group.
- * User/group is linked (without updating) to the synchronized resource upon synchronization in case of
- * the matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#LINK} is applied.
- *
- * @param <A> concrete any object
- * @param profile profile of the synchronization being executed.
- * @param delta retrieved synchronization information
- * @param any any object
- * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends AnyTO> SyncDelta beforeLink(
- ProvisioningProfile<?, ?> profile,
- SyncDelta delta,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed before to update a synchronized user / group locally.
- * User/group is updated upon synchronization in case of the matching rule
- * {@link org.apache.syncope.common.lib.types.MatchingRule#UPDATE} (default matching rule) is applied.
- *
- * @param <M> concrete any object
- * @param <P> any object modifications
- * @param profile profile of the synchronization being executed.
- * @param delta retrieved synchronization information
- * @param any any object
- * @param anyPatch modification
- * @return synchronization information used for logging and to be passed to the 'after' method.
- * @throws JobExecutionException in case of generic failure.
- */
- <M extends AnyTO, P extends AnyPatch> SyncDelta beforeUpdate(
- ProvisioningProfile<?, ?> profile,
- SyncDelta delta,
- M any,
- P anyPatch)
- throws JobExecutionException;
-
- /**
- * Action to be executed before to delete a synchronized user / group locally.
- *
- * @param <A> concrete any object
- * @param profile profile of the synchronization being executed.
- * @param delta retrieved synchronization information
- * @param any any object to be deleted
- * @return synchronization information used for logging and to be passed to the 'after' method.
- * @throws JobExecutionException in case of generic failure
- */
- <A extends AnyTO> SyncDelta beforeDelete(
- ProvisioningProfile<?, ?> profile,
- SyncDelta delta,
- A any) throws JobExecutionException;
-
- /**
- * Action to be executed when user / group synchronization goes on error.
- *
- * @param profile profile of the synchronization being executed.
- * @param delta retrieved synchronization information (may be modified by
- * 'beforeProvision/beforeUpdate/beforeDelete')
- * @param result global synchronization results at the current synchronization step
- * @param error error being reported
- * @throws JobExecutionException in case of generic failure
- */
- void onError(
- ProvisioningProfile<?, ?> profile,
- SyncDelta delta,
- ProvisioningReport result,
- Exception error) throws JobExecutionException;
-
- /**
- * Action to be executed after each local user / group synchronization.
- *
- * @param <A> concrete any object
- * @param profile profile of the synchronization being executed.
- * @param delta retrieved synchronization information (may be modified by beforeProvision / beforeUpdate /
- * beforeDelete)
- * @param any any object
- * @param result global synchronization results at the current synchronization step
- * @throws JobExecutionException in case of generic failure
- */
- <A extends AnyTO> void after(
- ProvisioningProfile<?, ?> profile,
- SyncDelta delta,
- A any,
- ProvisioningReport result) throws JobExecutionException;
-}
[11/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncCorrelationRule.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncCorrelationRule.java
deleted file mode 100644
index 52dfdb4..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncCorrelationRule.java
+++ /dev/null
@@ -1,36 +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.core.provisioning.api.sync;
-
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-
-/**
- * Interface for correlation rule to be evaluated during SyncJob execution.
- */
-public interface SyncCorrelationRule {
-
- /**
- * Return a search condition.
- *
- * @param connObj connector object.
- * @return search condition.
- */
- SearchCond getSearchCond(ConnectorObject connObj);
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopePushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopePushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopePushResultHandler.java
deleted file mode 100644
index e77af9a..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopePushResultHandler.java
+++ /dev/null
@@ -1,26 +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.core.provisioning.api.sync;
-
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-
-public interface SyncopePushResultHandler extends SyncopeResultHandler<PushTask, PushActions> {
-
- boolean handle(long anyKey);
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeResultHandler.java
deleted file mode 100644
index 86e7cf0..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeResultHandler.java
+++ /dev/null
@@ -1,29 +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.core.provisioning.api.sync;
-
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-
-public interface SyncopeResultHandler<T extends ProvisioningTask, A extends ProvisioningActions> {
-
- ProvisioningProfile<T, A> getProfile();
-
- void setProfile(ProvisioningProfile<T, A> profile);
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeSyncResultHandler.java
deleted file mode 100644
index 9eb8dc0..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncopeSyncResultHandler.java
+++ /dev/null
@@ -1,29 +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.core.provisioning.api.sync;
-
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
-
-public interface SyncopeSyncResultHandler extends SyncopeResultHandler<SyncTask, SyncActions>, SyncResultsHandler {
-
- @Override
- boolean handle(SyncDelta delta);
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserPushResultHandler.java
deleted file mode 100644
index 6f0a3fc..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserPushResultHandler.java
+++ /dev/null
@@ -1,23 +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.core.provisioning.api.sync;
-
-public interface UserPushResultHandler extends SyncopePushResultHandler {
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserSyncResultHandler.java
deleted file mode 100644
index 9db1269..0000000
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/UserSyncResultHandler.java
+++ /dev/null
@@ -1,23 +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.core.provisioning.api.sync;
-
-public interface UserSyncResultHandler extends SyncopeSyncResultHandler {
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectPushResultHandler.java
new file mode 100644
index 0000000..4198b53
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectPushResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.core.provisioning.api.syncpull;
+
+public interface AnyObjectPushResultHandler extends SyncopePushResultHandler {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectSyncResultHandler.java
new file mode 100644
index 0000000..dba6377
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/AnyObjectSyncResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.core.provisioning.api.syncpull;
+
+public interface AnyObjectSyncResultHandler extends SyncopeSyncResultHandler {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupPushResultHandler.java
new file mode 100644
index 0000000..457c78e
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupPushResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.core.provisioning.api.syncpull;
+
+public interface GroupPushResultHandler extends SyncopePushResultHandler {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupSyncResultHandler.java
new file mode 100644
index 0000000..19c8b8f
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/GroupSyncResultHandler.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.core.provisioning.api.syncpull;
+
+import java.util.Map;
+
+public interface GroupSyncResultHandler extends SyncopeSyncResultHandler {
+
+ Map<Long, String> getGroupOwnerMap();
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/IgnoreProvisionException.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/IgnoreProvisionException.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/IgnoreProvisionException.java
new file mode 100644
index 0000000..cdd885a
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/IgnoreProvisionException.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.core.provisioning.api.syncpull;
+
+/**
+ * Raised by {@link SyncActions} or {@link PushActions} methods when the given any object is to be ignored for
+ * synchronization / push.
+ */
+public class IgnoreProvisionException extends RuntimeException {
+
+ private static final long serialVersionUID = -8803817097998786364L;
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningActions.java
new file mode 100644
index 0000000..7479c96
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningActions.java
@@ -0,0 +1,40 @@
+/*
+ * 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.core.provisioning.api.syncpull;
+
+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 ProvisioningProfile<?, ?> profile) throws JobExecutionException;
+
+ /**
+ * Action to be executed after the synchronization task completion.
+ *
+ * @param profile sync profile
+ * @throws JobExecutionException in case of generic failure
+ */
+ void afterAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException;
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningProfile.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningProfile.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningProfile.java
new file mode 100644
index 0000000..08ab034
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningProfile.java
@@ -0,0 +1,81 @@
+/*
+ * 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.core.provisioning.api.syncpull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.syncope.common.lib.types.ConflictResolutionAction;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.provisioning.api.Connector;
+
+public class ProvisioningProfile<T extends ProvisioningTask, A extends ProvisioningActions> {
+
+ /**
+ * Syncing connector.
+ */
+ private final Connector connector;
+
+ private final T task;
+
+ private final List<ProvisioningReport> results = new ArrayList<>();
+
+ private boolean dryRun;
+
+ private ConflictResolutionAction resAct;
+
+ private final List<A> actions = new ArrayList<>();
+
+ public ProvisioningProfile(final Connector connector, final T task) {
+ this.connector = connector;
+ this.task = task;
+ }
+
+ public Connector getConnector() {
+ return connector;
+ }
+
+ public T getTask() {
+ return task;
+ }
+
+ public Collection<ProvisioningReport> 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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningReport.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningReport.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningReport.java
new file mode 100644
index 0000000..1e82796d
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ProvisioningReport.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.core.provisioning.api.syncpull;
+
+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.ResourceOperation;
+import org.apache.syncope.common.lib.types.TraceLevel;
+
+public class ProvisioningReport {
+
+ public enum Status {
+
+ SUCCESS,
+ IGNORE,
+ FAILURE
+
+ }
+
+ private String message;
+
+ private Status status;
+
+ private String anyType;
+
+ private ResourceOperation operation;
+
+ private Long key;
+
+ 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 getKey() {
+ return key;
+ }
+
+ public void setKey(final Long key) {
+ this.key = key;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public void setStatus(final Status status) {
+ this.status = status;
+ }
+
+ public String getAnyType() {
+ return anyType;
+ }
+
+ public void setAnyType(final String anyType) {
+ this.anyType = anyType;
+ }
+
+ 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, key, name, message);
+ } else {
+ // All
+ return String.format("%s %s (id/name): %d/%s %s", operation, status, key, 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<ProvisioningReport> results, final TraceLevel level) {
+ StringBuilder sb = new StringBuilder();
+ for (ProvisioningReport result : results) {
+ sb.append(result.getReportString(level)).append('\n');
+ }
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/PushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/PushActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/PushActions.java
new file mode 100644
index 0000000..75e5a5f
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/PushActions.java
@@ -0,0 +1,163 @@
+/*
+ * 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.core.provisioning.api.syncpull;
+
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.quartz.JobExecutionException;
+
+/**
+ * Interface for actions to be performed during push.
+ * All methods can throw {@link IgnoreProvisionException} to make the current any ignored by the push process.
+ */
+public interface PushActions extends ProvisioningActions {
+
+ /**
+ * Action to be executed before to assign (link & provision) a synchronized any object to the resource.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the push being executed.
+ * @param any any object to be created.
+ * @return any.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends Any<?>> A beforeAssign(
+ ProvisioningProfile<?, ?> profile,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to provision a synchronized any object to the resource.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the push being executed.
+ * @param any any object to be created.
+ * @return any.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends Any<?>> A beforeProvision(
+ ProvisioningProfile<?, ?> profile,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to update a synchronized any object on the resource.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the push being executed.
+ * @param any any object to be updated.
+ * @return any.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends Any<?>> A beforeUpdate(
+ ProvisioningProfile<?, ?> profile,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to link a synchronized any object to the resource.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the push being executed.
+ * @param any any object to be created.
+ * @return any.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends Any<?>> A beforeLink(
+ ProvisioningProfile<?, ?> profile,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to unlink a synchronized any object from the resource.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the push being executed.
+ * @param any any object to be created.
+ * @return any.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends Any<?>> A beforeUnlink(
+ ProvisioningProfile<?, ?> profile,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to unassign a synchronized any object from the resource.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the push being executed.
+ * @param any any object to be created.
+ * @return any.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends Any<?>> A beforeUnassign(
+ ProvisioningProfile<?, ?> profile,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to unassign a synchronized any object from the resource.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the push being executed.
+ * @param any any object to be created.
+ * @return any.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends Any<?>> A beforeDeprovision(
+ ProvisioningProfile<?, ?> profile,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before delete a synchronized any object locally and from the resource.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the push being executed.
+ * @param any any object to be created.
+ * @return any.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends Any<?>> A beforeDelete(
+ ProvisioningProfile<?, ?> profile,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed after any object push goes on error.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the push being executed.
+ * @param any synchronized any object.
+ * @param result operation result.
+ * @param error error being reported
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends Any<?>> void onError(
+ ProvisioningProfile<?, ?> profile,
+ A any,
+ ProvisioningReport result,
+ Exception error) throws JobExecutionException;
+
+ /**
+ * Action to be executed after each local any object push.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the push being executed.
+ * @param any synchronized any object.
+ * @param result operation result.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends Any<?>> void after(
+ ProvisioningProfile<?, ?> profile,
+ A any,
+ ProvisioningReport result) throws JobExecutionException;
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ReconciliationFilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ReconciliationFilterBuilder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ReconciliationFilterBuilder.java
new file mode 100644
index 0000000..cc073ce
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/ReconciliationFilterBuilder.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.core.provisioning.api.syncpull;
+
+import org.identityconnectors.framework.common.objects.filter.Filter;
+
+/**
+ * Interface to be implemented for performing filtered reconciliation of a
+ * {@link org.apache.syncope.core.persistence.api.entity.task.SyncTask}.
+ */
+public interface ReconciliationFilterBuilder {
+
+ Filter build();
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncActions.java
new file mode 100644
index 0000000..ae072b7
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncActions.java
@@ -0,0 +1,203 @@
+/*
+ * 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.core.provisioning.api.syncpull;
+
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+
+/**
+ * Interface for actions to be performed during synchronization.
+ * All methods can throw {@link IgnoreProvisionException} to make the current any object ignored by the synchronization
+ * process.
+ */
+public interface SyncActions extends ProvisioningActions {
+
+ /**
+ * Action to be executed before to create a synchronized user / group locally.
+ * User/group is created locally upon synchronization in case of the un-matching rule
+ * {@link org.apache.syncope.common.lib.types.UnmatchingRule#PROVISION} (default un-matching rule) is applied.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param any any object
+ * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends AnyTO> SyncDelta beforeProvision(
+ ProvisioningProfile<?, ?> profile,
+ SyncDelta delta,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before creating (and linking to the resource) a synchronized user / group locally.
+ * User/group is created locally and linked to the synchronized resource upon synchronization in case of the
+ * un-matching rule {@link org.apache.syncope.common.lib.types.UnmatchingRule#ASSIGN} is applied.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param any any object
+ * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends AnyTO> SyncDelta beforeAssign(
+ ProvisioningProfile<?, ?> profile,
+ SyncDelta delta,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before unlinking resource from the synchronized user / group and de-provisioning.
+ * User/group is unlinked and de-provisioned from the synchronized resource upon synchronization in case of the
+ * matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#UNASSIGN} is applied.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param any any object
+ * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends AnyTO> SyncDelta beforeUnassign(
+ ProvisioningProfile<?, ?> profile,
+ SyncDelta delta,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before de-provisioning action only.
+ * User/group is de-provisioned (without unlinking) from the synchronized resource upon synchronization in case of
+ * the matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#DEPROVISION} is applied.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param any any object
+ * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends AnyTO> SyncDelta beforeDeprovision(
+ ProvisioningProfile<?, ?> profile,
+ SyncDelta delta,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before unlinking resource from the synchronized user / group.
+ * User/group is unlinked (without de-provisioning) from the synchronized resource upon synchronization in case of
+ * the matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#UNLINK} is applied.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param any any object
+ * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends AnyTO> SyncDelta beforeUnlink(
+ ProvisioningProfile<?, ?> profile,
+ SyncDelta delta,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before linking resource to the synchronized user / group.
+ * User/group is linked (without updating) to the synchronized resource upon synchronization in case of
+ * the matching rule {@link org.apache.syncope.common.lib.types.MatchingRule#LINK} is applied.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param any any object
+ * @return synchronization information used for user status evaluation and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends AnyTO> SyncDelta beforeLink(
+ ProvisioningProfile<?, ?> profile,
+ SyncDelta delta,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed before to update a synchronized user / group locally.
+ * User/group is updated upon synchronization in case of the matching rule
+ * {@link org.apache.syncope.common.lib.types.MatchingRule#UPDATE} (default matching rule) is applied.
+ *
+ * @param <M> concrete any object
+ * @param <P> any object modifications
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param any any object
+ * @param anyPatch modification
+ * @return synchronization information used for logging and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure.
+ */
+ <M extends AnyTO, P extends AnyPatch> SyncDelta beforeUpdate(
+ ProvisioningProfile<?, ?> profile,
+ SyncDelta delta,
+ M any,
+ P anyPatch)
+ throws JobExecutionException;
+
+ /**
+ * Action to be executed before to delete a synchronized user / group locally.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information
+ * @param any any object to be deleted
+ * @return synchronization information used for logging and to be passed to the 'after' method.
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends AnyTO> SyncDelta beforeDelete(
+ ProvisioningProfile<?, ?> profile,
+ SyncDelta delta,
+ A any) throws JobExecutionException;
+
+ /**
+ * Action to be executed when user / group synchronization goes on error.
+ *
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information (may be modified by
+ * 'beforeProvision/beforeUpdate/beforeDelete')
+ * @param result global synchronization results at the current synchronization step
+ * @param error error being reported
+ * @throws JobExecutionException in case of generic failure
+ */
+ void onError(
+ ProvisioningProfile<?, ?> profile,
+ SyncDelta delta,
+ ProvisioningReport result,
+ Exception error) throws JobExecutionException;
+
+ /**
+ * Action to be executed after each local user / group synchronization.
+ *
+ * @param <A> concrete any object
+ * @param profile profile of the synchronization being executed.
+ * @param delta retrieved synchronization information (may be modified by beforeProvision / beforeUpdate /
+ * beforeDelete)
+ * @param any any object
+ * @param result global synchronization results at the current synchronization step
+ * @throws JobExecutionException in case of generic failure
+ */
+ <A extends AnyTO> void after(
+ ProvisioningProfile<?, ?> profile,
+ SyncDelta delta,
+ A any,
+ ProvisioningReport result) throws JobExecutionException;
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncCorrelationRule.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncCorrelationRule.java
new file mode 100644
index 0000000..dff841a
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncCorrelationRule.java
@@ -0,0 +1,36 @@
+/*
+ * 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.core.provisioning.api.syncpull;
+
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+
+/**
+ * Interface for correlation rule to be evaluated during SyncJob execution.
+ */
+public interface SyncCorrelationRule {
+
+ /**
+ * Return a search condition.
+ *
+ * @param connObj connector object.
+ * @return search condition.
+ */
+ SearchCond getSearchCond(ConnectorObject connObj);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopePushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopePushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopePushResultHandler.java
new file mode 100644
index 0000000..deb6e9b
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopePushResultHandler.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.core.provisioning.api.syncpull;
+
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+
+public interface SyncopePushResultHandler extends SyncopeResultHandler<PushTask, PushActions> {
+
+ boolean handle(long anyKey);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeResultHandler.java
new file mode 100644
index 0000000..c078ef2
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/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.core.provisioning.api.syncpull;
+
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+
+public interface SyncopeResultHandler<T extends ProvisioningTask, A extends ProvisioningActions> {
+
+ ProvisioningProfile<T, A> getProfile();
+
+ void setProfile(ProvisioningProfile<T, A> profile);
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeSyncResultHandler.java
new file mode 100644
index 0000000..5c293830
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/SyncopeSyncResultHandler.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.core.provisioning.api.syncpull;
+
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.identityconnectors.framework.common.objects.SyncResultsHandler;
+
+public interface SyncopeSyncResultHandler extends SyncopeResultHandler<SyncTask, SyncActions>, SyncResultsHandler {
+
+ @Override
+ boolean handle(SyncDelta delta);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserPushResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserPushResultHandler.java
new file mode 100644
index 0000000..8a0459a
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserPushResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.core.provisioning.api.syncpull;
+
+public interface UserPushResultHandler extends SyncopePushResultHandler {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserSyncResultHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserSyncResultHandler.java
new file mode 100644
index 0000000..7f9c827
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/syncpull/UserSyncResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.core.provisioning.api.syncpull;
+
+public interface UserSyncResultHandler extends SyncopeSyncResultHandler {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ConnPoolConfUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ConnPoolConfUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ConnPoolConfUtils.java
new file mode 100644
index 0000000..07f929a
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ConnPoolConfUtils.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.core.provisioning.api.utils;
+
+import org.apache.syncope.common.lib.to.ConnPoolConfTO;
+import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
+import org.identityconnectors.common.pooling.ObjectPoolConfiguration;
+
+public final class ConnPoolConfUtils {
+
+ 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 ConnPoolConfUtils() {
+ // empty constructor for static utility class
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/EntityUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/EntityUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/EntityUtils.java
new file mode 100644
index 0000000..a744372
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/EntityUtils.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.core.provisioning.api.utils;
+
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+
+public final class EntityUtils {
+
+ public static <KEY, E extends Entity<KEY>> Transformer<E, KEY> keyTransformer() {
+ return new Transformer<E, KEY>() {
+
+ @Override
+ public KEY transform(final E input) {
+ return input.getKey();
+ }
+ };
+ }
+
+ /**
+ * Private default constructor, for static-only classes.
+ */
+ private EntityUtils() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ExceptionUtils2.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ExceptionUtils2.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ExceptionUtils2.java
new file mode 100644
index 0000000..4045207
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ExceptionUtils2.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.core.provisioning.api.utils;
+
+import org.apache.commons.lang3.exception.ExceptionUtils;
+
+public final class ExceptionUtils2 {
+
+ /**
+ * Uses commons lang's ExceptionUtils to provide a representation of the full stack trace of the given throwable.
+ *
+ * @param t throwable to build stack trace from
+ * @return a string representation of full stack trace of the given throwable
+ */
+ public static String getFullStackTrace(final Throwable t) {
+ StringBuilder result = new StringBuilder();
+
+ for (Throwable throwable : ExceptionUtils.getThrowableList(t)) {
+ result.append(ExceptionUtils.getMessage(throwable)).append('\n').
+ append(ExceptionUtils.getStackTrace(throwable)).append("\n\n");
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Private default constructor, for static-only classes.
+ */
+ private ExceptionUtils2() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/FormatUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/FormatUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/FormatUtils.java
new file mode 100644
index 0000000..e1c7ce5
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/FormatUtils.java
@@ -0,0 +1,121 @@
+/*
+ * 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.core.provisioning.api.utils;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.commons.lang3.time.DateUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+
+/**
+ * Utility class for parsing / formatting date and numbers.
+ */
+public final class FormatUtils {
+
+ private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+
+ @Override
+ protected SimpleDateFormat initialValue() {
+ SimpleDateFormat sdf = new SimpleDateFormat();
+ sdf.applyPattern(SyncopeConstants.DEFAULT_DATE_PATTERN);
+ return sdf;
+ }
+ };
+
+ private static final ThreadLocal<DecimalFormat> DECIMAL_FORMAT = new ThreadLocal<DecimalFormat>() {
+
+ @Override
+ protected DecimalFormat initialValue() {
+ DecimalFormat df = new DecimalFormat();
+ df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));
+ return df;
+ }
+ };
+
+ public static String format(final Date date) {
+ return format(date, true);
+ }
+
+ public static String format(final Date date, final boolean lenient) {
+ return format(date, lenient, null);
+ }
+
+ public static String format(final Date date, final boolean lenient, final String conversionPattern) {
+ SimpleDateFormat sdf = DATE_FORMAT.get();
+ if (conversionPattern != null) {
+ sdf.applyPattern(conversionPattern);
+ }
+ sdf.setLenient(lenient);
+ return sdf.format(date);
+ }
+
+ public static String format(final long number) {
+ return format(number, null);
+ }
+
+ public static String format(final long number, final String conversionPattern) {
+ DecimalFormat df = DECIMAL_FORMAT.get();
+ if (conversionPattern != null) {
+ df.applyPattern(conversionPattern);
+ }
+ return df.format(number);
+ }
+
+ public static String format(final double number) {
+ return format(number, null);
+ }
+
+ public static String format(final double number, final String conversionPattern) {
+ DecimalFormat df = DECIMAL_FORMAT.get();
+ if (conversionPattern != null) {
+ df.applyPattern(conversionPattern);
+ }
+ return df.format(number);
+ }
+
+ public static Date parseDate(final String source) throws ParseException {
+ return DateUtils.parseDate(source, SyncopeConstants.DATE_PATTERNS);
+ }
+
+ public static Date parseDate(final String source, final String conversionPattern) throws ParseException {
+ SimpleDateFormat sdf = DATE_FORMAT.get();
+ sdf.applyPattern(conversionPattern);
+ sdf.setLenient(false);
+ return sdf.parse(source);
+ }
+
+ public static Number parseNumber(final String source, final String conversionPattern) throws ParseException {
+ DecimalFormat df = DECIMAL_FORMAT.get();
+ df.applyPattern(conversionPattern);
+ return df.parse(source);
+ }
+
+ public static void clear() {
+ DATE_FORMAT.remove();
+ DECIMAL_FORMAT.remove();
+ }
+
+ private FormatUtils() {
+ // private empty constructor
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.java
new file mode 100644
index 0000000..47703b0
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/RealmUtils.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.core.provisioning.api.utils;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public final class RealmUtils {
+
+ public static String getGroupOwnerRealm(final String realmPath, final Long groupKey) {
+ return realmPath + "@" + groupKey;
+ }
+
+ public static boolean normalizingAddTo(final Set<String> realms, final String newRealm) {
+ boolean dontAdd = false;
+ Set<String> toRemove = new HashSet<>();
+ for (String realm : realms) {
+ if (newRealm.startsWith(realm)) {
+ dontAdd = true;
+ } else if (realm.startsWith(newRealm)) {
+ toRemove.add(realm);
+ }
+ }
+
+ realms.removeAll(toRemove);
+ if (!dontAdd) {
+ realms.add(newRealm);
+ }
+ return !dontAdd;
+ }
+
+ public static Set<String> normalize(final Collection<String> realms) {
+ Set<String> normalized = new HashSet<>();
+ if (realms != null) {
+ for (String realm : realms) {
+ normalizingAddTo(normalized, realm);
+ }
+ }
+
+ return normalized;
+ }
+
+ private RealmUtils() {
+ // empty constructor for static utility class
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/URIUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/URIUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/URIUtils.java
new file mode 100644
index 0000000..143a14c
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/URIUtils.java
@@ -0,0 +1,61 @@
+/*
+ * 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.core.provisioning.api.utils;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+public final class URIUtils {
+
+ private URIUtils() {
+ // empty constructor for static utility class
+ }
+
+ /**
+ * Build a valid URI out of the given location.
+ * Only "file", "connid" and "connids" schemes are allowed.
+ * For "file", invalid characters are handled via intermediate transformation into URL.
+ *
+ * @param location the candidate location for URI
+ * @return valid URI for the given location
+ * @throws MalformedURLException if the intermediate URL is not valid
+ * @throws URISyntaxException if the given location does not correspond to a valid URI
+ */
+ public static URI buildForConnId(final String location) throws MalformedURLException, URISyntaxException {
+ final String candidate = location.trim();
+
+ if (!candidate.startsWith("file:")
+ && !candidate.startsWith("connid:") && !candidate.startsWith("connids:")) {
+
+ throw new IllegalArgumentException(candidate + " is not a valid URI for file or connid(s) schemes");
+ }
+
+ URI uri;
+ if (candidate.startsWith("file:")) {
+ uri = new File(new URL(candidate).getFile()).getAbsoluteFile().toURI();
+ } else {
+ uri = new URI(candidate);
+ }
+
+ return uri;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/AccountPolicyException.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/AccountPolicyException.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/AccountPolicyException.java
new file mode 100644
index 0000000..22be516
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/AccountPolicyException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.core.provisioning.api.utils.policy;
+
+public class AccountPolicyException extends PolicyException {
+
+ private static final long serialVersionUID = 2779416455067691813L;
+
+ public AccountPolicyException() {
+ super();
+ }
+
+ public AccountPolicyException(final String message) {
+ super(message);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/InvalidPasswordRuleConf.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/InvalidPasswordRuleConf.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/InvalidPasswordRuleConf.java
new file mode 100644
index 0000000..9b79189
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/InvalidPasswordRuleConf.java
@@ -0,0 +1,37 @@
+/*
+ * 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.core.provisioning.api.utils.policy;
+
+/**
+ * Raise when the merge of two or more PasswordRuleconf instances led to an inconsistent condition.
+ *
+ * @see org.apache.syncope.common.lib.policy.PasswordRuleConf
+ */
+public class InvalidPasswordRuleConf extends Exception {
+
+ private static final long serialVersionUID = 4810651743226663580L;
+
+ public InvalidPasswordRuleConf(final String msg) {
+ super(msg);
+ }
+
+ public InvalidPasswordRuleConf(final String msg, final Exception e) {
+ super(msg, e);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PasswordPolicyException.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PasswordPolicyException.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PasswordPolicyException.java
new file mode 100644
index 0000000..2a49a20
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PasswordPolicyException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.core.provisioning.api.utils.policy;
+
+public class PasswordPolicyException extends PolicyException {
+
+ private static final long serialVersionUID = 8072104484395278469L;
+
+ public PasswordPolicyException() {
+ super();
+ }
+
+ public PasswordPolicyException(final String message) {
+ super(message);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyException.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyException.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyException.java
new file mode 100644
index 0000000..f11d202
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.core.provisioning.api.utils.policy;
+
+public class PolicyException extends RuntimeException {
+
+ private static final long serialVersionUID = -6082115004491662910L;
+
+ public PolicyException() {
+ super();
+ }
+
+ public PolicyException(final String message) {
+ super(message);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyPattern.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyPattern.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyPattern.java
new file mode 100644
index 0000000..a853f0e
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/policy/PolicyPattern.java
@@ -0,0 +1,50 @@
+/*
+ * 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.core.provisioning.api.utils.policy;
+
+import java.util.regex.Pattern;
+
+public final class PolicyPattern {
+
+ public static final Pattern DIGIT = Pattern.compile(".*\\d+.*");
+
+ public static final Pattern ALPHA_LOWERCASE = Pattern.compile(".*[a-z]+.*");
+
+ public static final Pattern ALPHA_UPPERCASE = Pattern.compile(".*[A-Z]+.*");
+
+ public static final Pattern FIRST_DIGIT = Pattern.compile("\\d.*");
+
+ public static final Pattern LAST_DIGIT = Pattern.compile(".*\\d");
+
+ public static final Pattern ALPHANUMERIC = Pattern.compile(".*\\w.*");
+
+ public static final Pattern FIRST_ALPHANUMERIC = Pattern.compile("\\w.*");
+
+ public static final Pattern LAST_ALPHANUMERIC = Pattern.compile(".*\\w");
+
+ public static final Pattern NON_ALPHANUMERIC = Pattern.compile(".*\\W.*");
+
+ public static final Pattern FIRST_NON_ALPHANUMERIC = Pattern.compile("\\W.*");
+
+ public static final Pattern LAST_NON_ALPHANUMERIC = Pattern.compile(".*\\W");
+
+ private PolicyPattern() {
+ // private constructor for static utility class
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/pom.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml
index ee6bfc6..7956dad 100644
--- a/core/provisioning-java/pom.xml
+++ b/core/provisioning-java/pom.xml
@@ -45,6 +45,11 @@ under the License.
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-jexl3</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
@@ -61,7 +66,7 @@ under the License.
</dependency>
<dependency>
<groupId>org.apache.syncope.core</groupId>
- <artifactId>syncope-core-misc</artifactId>
+ <artifactId>syncope-core-spring</artifactId>
<version>${project.version}</version>
</dependency>
[06/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractProvisioningJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractProvisioningJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractProvisioningJobDelegate.java
new file mode 100644
index 0000000..bd13365
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractProvisioningJobDelegate.java
@@ -0,0 +1,434 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import java.lang.reflect.ParameterizedType;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.annotation.Resource;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.ConnectorFactory;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.java.job.AbstractSchedTaskJobDelegate;
+import org.apache.syncope.core.provisioning.java.job.TaskJob;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public abstract class AbstractProvisioningJobDelegate<T extends ProvisioningTask>
+ extends AbstractSchedTaskJobDelegate {
+
+ @Resource(name = "adminUser")
+ protected String adminUser;
+
+ /**
+ * ConnInstance loader.
+ */
+ @Autowired
+ protected ConnectorFactory connFactory;
+
+ @Autowired
+ protected AnyTypeDAO anyTypeDAO;
+
+ /**
+ * Resource DAO.
+ */
+ @Autowired
+ protected ExternalResourceDAO resourceDAO;
+
+ /**
+ * Policy DAO.
+ */
+ @Autowired
+ protected PolicyDAO policyDAO;
+
+ /**
+ * Create a textual report of the synchronization, based on the trace level.
+ *
+ * @param provResults Sync results
+ * @param syncTraceLevel Sync trace level
+ * @param dryRun dry run?
+ * @return report as string
+ */
+ protected String createReport(final Collection<ProvisioningReport> provResults, final TraceLevel syncTraceLevel,
+ final boolean dryRun) {
+
+ if (syncTraceLevel == TraceLevel.NONE) {
+ return null;
+ }
+
+ StringBuilder report = new StringBuilder();
+
+ if (dryRun) {
+ report.append("==>Dry run only, no modifications were made<==\n\n");
+ }
+
+ List<ProvisioningReport> uSuccCreate = new ArrayList<>();
+ List<ProvisioningReport> uFailCreate = new ArrayList<>();
+ List<ProvisioningReport> uSuccUpdate = new ArrayList<>();
+ List<ProvisioningReport> uFailUpdate = new ArrayList<>();
+ List<ProvisioningReport> uSuccDelete = new ArrayList<>();
+ List<ProvisioningReport> uFailDelete = new ArrayList<>();
+ List<ProvisioningReport> uSuccNone = new ArrayList<>();
+ List<ProvisioningReport> uIgnore = new ArrayList<>();
+ List<ProvisioningReport> gSuccCreate = new ArrayList<>();
+ List<ProvisioningReport> gFailCreate = new ArrayList<>();
+ List<ProvisioningReport> gSuccUpdate = new ArrayList<>();
+ List<ProvisioningReport> gFailUpdate = new ArrayList<>();
+ List<ProvisioningReport> gSuccDelete = new ArrayList<>();
+ List<ProvisioningReport> gFailDelete = new ArrayList<>();
+ List<ProvisioningReport> gSuccNone = new ArrayList<>();
+ List<ProvisioningReport> gIgnore = new ArrayList<>();
+ List<ProvisioningReport> aSuccCreate = new ArrayList<>();
+ List<ProvisioningReport> aFailCreate = new ArrayList<>();
+ List<ProvisioningReport> aSuccUpdate = new ArrayList<>();
+ List<ProvisioningReport> aFailUpdate = new ArrayList<>();
+ List<ProvisioningReport> aSuccDelete = new ArrayList<>();
+ List<ProvisioningReport> aFailDelete = new ArrayList<>();
+ List<ProvisioningReport> aSuccNone = new ArrayList<>();
+ List<ProvisioningReport> aIgnore = new ArrayList<>();
+
+ for (ProvisioningReport provResult : provResults) {
+ AnyType anyType = anyTypeDAO.find(provResult.getAnyType());
+
+ switch (provResult.getStatus()) {
+ case SUCCESS:
+ switch (provResult.getOperation()) {
+ case CREATE:
+ switch (anyType.getKind()) {
+ case USER:
+ uSuccCreate.add(provResult);
+ break;
+
+ case GROUP:
+ gSuccCreate.add(provResult);
+ break;
+
+ case ANY_OBJECT:
+ default:
+ aSuccCreate.add(provResult);
+ }
+ break;
+
+ case UPDATE:
+ switch (anyType.getKind()) {
+ case USER:
+ uSuccUpdate.add(provResult);
+ break;
+
+ case GROUP:
+ gSuccUpdate.add(provResult);
+ break;
+
+ case ANY_OBJECT:
+ default:
+ aSuccUpdate.add(provResult);
+ }
+ break;
+
+ case DELETE:
+ switch (anyType.getKind()) {
+ case USER:
+ uSuccDelete.add(provResult);
+ break;
+
+ case GROUP:
+ gSuccDelete.add(provResult);
+ break;
+
+ case ANY_OBJECT:
+ default:
+ aSuccDelete.add(provResult);
+ }
+ break;
+
+ case NONE:
+ switch (anyType.getKind()) {
+ case USER:
+ uSuccNone.add(provResult);
+ break;
+
+ case GROUP:
+ gSuccNone.add(provResult);
+ break;
+
+ case ANY_OBJECT:
+ default:
+ aSuccNone.add(provResult);
+ }
+ break;
+
+ default:
+ }
+ break;
+
+ case FAILURE:
+ switch (provResult.getOperation()) {
+ case CREATE:
+ switch (anyType.getKind()) {
+ case USER:
+ uFailCreate.add(provResult);
+ break;
+
+ case GROUP:
+ gFailCreate.add(provResult);
+ break;
+
+ case ANY_OBJECT:
+ default:
+ aFailCreate.add(provResult);
+ }
+ break;
+
+ case UPDATE:
+ switch (anyType.getKind()) {
+ case USER:
+ uFailUpdate.add(provResult);
+ break;
+
+ case GROUP:
+ gFailUpdate.add(provResult);
+ break;
+
+ case ANY_OBJECT:
+ default:
+ aFailUpdate.add(provResult);
+ }
+ break;
+
+ case DELETE:
+ switch (anyType.getKind()) {
+ case USER:
+ uFailDelete.add(provResult);
+ break;
+
+ case GROUP:
+ gFailDelete.add(provResult);
+ break;
+
+ case ANY_OBJECT:
+ default:
+ aFailDelete.add(provResult);
+ }
+ break;
+
+ default:
+ }
+ break;
+
+ case IGNORE:
+ switch (anyType.getKind()) {
+ case USER:
+ uIgnore.add(provResult);
+ break;
+
+ case GROUP:
+ gIgnore.add(provResult);
+ break;
+
+ case ANY_OBJECT:
+ default:
+ aIgnore.add(provResult);
+ }
+ break;
+
+ default:
+ }
+ }
+
+ // Summary, also to be included for FAILURE and ALL, so create it anyway.
+ report.append("Users ").
+ append("[created/failures]: ").append(uSuccCreate.size()).append('/').append(uFailCreate.size()).
+ append(' ').
+ append("[updated/failures]: ").append(uSuccUpdate.size()).append('/').append(uFailUpdate.size()).
+ append(' ').
+ append("[deleted/failures]: ").append(uSuccDelete.size()).append('/').append(uFailDelete.size()).
+ append(' ').
+ append("[no operation/ignored]: ").append(uSuccNone.size()).append('/').append(uIgnore.size()).
+ append('\n');
+ report.append("Groups ").
+ append("[created/failures]: ").append(gSuccCreate.size()).append('/').append(gFailCreate.size()).
+ append(' ').
+ append("[updated/failures]: ").append(gSuccUpdate.size()).append('/').append(gFailUpdate.size()).
+ append(' ').
+ append("[deleted/failures]: ").append(gSuccDelete.size()).append('/').append(gFailDelete.size()).
+ append(' ').
+ append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size()).
+ append('\n');
+ report.append("Any objects ").
+ append("[created/failures]: ").append(aSuccCreate.size()).append('/').append(aFailCreate.size()).
+ append(' ').
+ append("[updated/failures]: ").append(aSuccUpdate.size()).append('/').append(aFailUpdate.size()).
+ append(' ').
+ append("[deleted/failures]: ").append(aSuccDelete.size()).append('/').append(aFailDelete.size()).
+ append(' ').
+ append("[no operation/ignored]: ").append(aSuccNone.size()).append('/').append(aIgnore.size());
+
+ // Failures
+ if (syncTraceLevel == TraceLevel.FAILURES || syncTraceLevel == TraceLevel.ALL) {
+ if (!uFailCreate.isEmpty()) {
+ report.append("\n\nUsers failed to create: ");
+ report.append(ProvisioningReport.produceReport(uFailCreate, syncTraceLevel));
+ }
+ if (!uFailUpdate.isEmpty()) {
+ report.append("\nUsers failed to update: ");
+ report.append(ProvisioningReport.produceReport(uFailUpdate, syncTraceLevel));
+ }
+ if (!uFailDelete.isEmpty()) {
+ report.append("\nUsers failed to delete: ");
+ report.append(ProvisioningReport.produceReport(uFailDelete, syncTraceLevel));
+ }
+
+ if (!gFailCreate.isEmpty()) {
+ report.append("\n\nGroups failed to create: ");
+ report.append(ProvisioningReport.produceReport(gFailCreate, syncTraceLevel));
+ }
+ if (!gFailUpdate.isEmpty()) {
+ report.append("\nGroups failed to update: ");
+ report.append(ProvisioningReport.produceReport(gFailUpdate, syncTraceLevel));
+ }
+ if (!gFailDelete.isEmpty()) {
+ report.append("\nGroups failed to delete: ");
+ report.append(ProvisioningReport.produceReport(gFailDelete, syncTraceLevel));
+ }
+
+ if (!aFailCreate.isEmpty()) {
+ report.append("\nAny objects failed to create: ");
+ report.append(ProvisioningReport.produceReport(aFailCreate, syncTraceLevel));
+ }
+ if (!aFailUpdate.isEmpty()) {
+ report.append("\nAny objects failed to update: ");
+ report.append(ProvisioningReport.produceReport(aFailUpdate, syncTraceLevel));
+ }
+ if (!aFailDelete.isEmpty()) {
+ report.append("\nAny objects failed to delete: ");
+ report.append(ProvisioningReport.produceReport(aFailDelete, syncTraceLevel));
+ }
+ }
+
+ // Succeeded, only if on 'ALL' level
+ if (syncTraceLevel == TraceLevel.ALL) {
+ report.append("\n\nUsers created:\n").
+ append(ProvisioningReport.produceReport(uSuccCreate, syncTraceLevel)).
+ append("\nUsers updated:\n").
+ append(ProvisioningReport.produceReport(uSuccUpdate, syncTraceLevel)).
+ append("\nUsers deleted:\n").
+ append(ProvisioningReport.produceReport(uSuccDelete, syncTraceLevel)).
+ append("\nUsers no operation:\n").
+ append(ProvisioningReport.produceReport(uSuccNone, syncTraceLevel)).
+ append("\nUsers ignored:\n").
+ append(ProvisioningReport.produceReport(uIgnore, syncTraceLevel));
+ report.append("\n\nGroups created:\n").
+ append(ProvisioningReport.produceReport(gSuccCreate, syncTraceLevel)).
+ append("\nGroups updated:\n").
+ append(ProvisioningReport.produceReport(gSuccUpdate, syncTraceLevel)).
+ append("\nGroups deleted:\n").
+ append(ProvisioningReport.produceReport(gSuccDelete, syncTraceLevel)).
+ append("\nGroups no operation:\n").
+ append(ProvisioningReport.produceReport(gSuccNone, syncTraceLevel)).
+ append("\nGroups ignored:\n").
+ append(ProvisioningReport.produceReport(gSuccNone, syncTraceLevel));
+ report.append("\n\nAny objects created:\n").
+ append(ProvisioningReport.produceReport(aSuccCreate, syncTraceLevel)).
+ append("\nAny objects updated:\n").
+ append(ProvisioningReport.produceReport(aSuccUpdate, syncTraceLevel)).
+ append("\nAny objects deleted:\n").
+ append(ProvisioningReport.produceReport(aSuccDelete, syncTraceLevel)).
+ append("\nAny objects no operation:\n").
+ append(ProvisioningReport.produceReport(aSuccNone, syncTraceLevel)).
+ append("\nAny objects ignored:\n").
+ append(ProvisioningReport.produceReport(aSuccNone, syncTraceLevel));
+ }
+
+ return report.toString();
+ }
+
+ @Override
+ protected String doExecute(final boolean dryRun) throws JobExecutionException {
+ try {
+ Class<T> clazz = getTaskClassReference();
+ if (!clazz.isAssignableFrom(task.getClass())) {
+ throw new JobExecutionException("Task " + task.getKey() + " isn't a ProvisioningTask");
+ }
+
+ T provisioningTask = clazz.cast(task);
+
+ Connector connector;
+ try {
+ connector = connFactory.getConnector(provisioningTask.getResource());
+ } catch (Exception e) {
+ String msg = String.format("Connector instance bean for resource %s and connInstance %s not found",
+ provisioningTask.getResource(), provisioningTask.getResource().getConnector());
+ throw new JobExecutionException(msg, e);
+ }
+
+ boolean noMapping = true;
+ for (Provision provision : provisioningTask.getResource().getProvisions()) {
+ Mapping mapping = provision.getMapping();
+ if (mapping != null) {
+ noMapping = false;
+ if (mapping.getConnObjectKeyItem() == null) {
+ throw new JobExecutionException(
+ "Invalid ConnObjectKey mapping for provision " + provision);
+ }
+ }
+ }
+ if (noMapping) {
+ return "No mapping configured for both users and groups: aborting...";
+ }
+
+ return doExecuteProvisioning(
+ provisioningTask,
+ connector,
+ dryRun);
+ } catch (Throwable t) {
+ LOG.error("While executing provisioning job {}", getClass().getName(), t);
+ throw t;
+ }
+ }
+
+ protected abstract String doExecuteProvisioning(
+ final T task,
+ final Connector connector,
+ final boolean dryRun) throws JobExecutionException;
+
+ @Override
+ protected boolean hasToBeRegistered(final TaskExec execution) {
+ final ProvisioningTask provTask = (ProvisioningTask) task;
+
+ // True if either failed and failures have to be registered, or if ALL has to be registered.
+ return (TaskJob.Status.valueOf(execution.getStatus()) == TaskJob.Status.FAILURE
+ && provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
+ || provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.SUMMARY.ordinal();
+ }
+
+ @SuppressWarnings("unchecked")
+ private Class<T> getTaskClassReference() {
+ return (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractPushResultHandler.java
new file mode 100644
index 0000000..258e106
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractPushResultHandler.java
@@ -0,0 +1,434 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.commons.collections4.IteratorUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.StringPatchItem;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.syncpull.PushActions;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.TimeoutException;
+import org.apache.syncope.core.provisioning.api.syncpull.IgnoreProvisionException;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncopePushResultHandler;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.Uid;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions>
+ implements SyncopePushResultHandler {
+
+ @Autowired
+ protected MappingManager mappingManager;
+
+ protected abstract String getName(Any<?> any);
+
+ protected void deprovision(final Any<?> any) {
+ AnyTO before = getAnyTO(any.getKey());
+
+ List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getDeleteTasks(
+ any.getType().getKind(),
+ any.getKey(),
+ null,
+ noPropResources));
+ }
+
+ protected void provision(final Any<?> any, final Boolean enabled) {
+ AnyTO before = getAnyTO(any.getKey());
+
+ List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getCreateTasks(
+ any.getType().getKind(),
+ any.getKey(),
+ propByRes,
+ before.getVirAttrs(),
+ noPropResources));
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void link(final Any<?> any, final Boolean unlink) {
+ AnyPatch patch = newPatch(any.getKey());
+ patch.getResources().add(new StringPatchItem.Builder().
+ operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE).
+ value(profile.getTask().getResource().getKey()).build());
+
+ update(patch);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void unassign(final Any<?> any) {
+ AnyPatch patch = newPatch(any.getKey());
+ patch.getResources().add(new StringPatchItem.Builder().
+ operation(PatchOperation.DELETE).
+ value(profile.getTask().getResource().getKey()).build());
+
+ update(patch);
+
+ deprovision(any);
+ }
+
+ protected void assign(final Any<?> any, final Boolean enabled) {
+ AnyPatch patch = newPatch(any.getKey());
+ patch.getResources().add(new StringPatchItem.Builder().
+ operation(PatchOperation.ADD_REPLACE).
+ value(profile.getTask().getResource().getKey()).build());
+
+ update(patch);
+
+ provision(any, enabled);
+ }
+
+ protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
+ ConnectorObject obj = null;
+ try {
+ Uid uid = new Uid(connObjectKey);
+
+ obj = profile.getConnector().getObject(objectClass,
+ uid,
+ MappingManagerImpl.buildOperationOptions(IteratorUtils.<MappingItem>emptyIterator()));
+ } catch (TimeoutException toe) {
+ LOG.debug("Request timeout", toe);
+ throw toe;
+ } catch (RuntimeException ignore) {
+ LOG.debug("While resolving {}", connObjectKey, ignore);
+ }
+
+ return obj;
+ }
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
+ @Override
+ public boolean handle(final long anyKey) {
+ Any<?> any = null;
+ try {
+ any = getAny(anyKey);
+ doHandle(any);
+ return true;
+ } catch (IgnoreProvisionException e) {
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.NONE);
+ result.setAnyType(any == null ? null : any.getType().getKey());
+ result.setStatus(ProvisioningReport.Status.IGNORE);
+ result.setKey(anyKey);
+ profile.getResults().add(result);
+
+ LOG.warn("Ignoring during push", e);
+ return true;
+ } catch (JobExecutionException e) {
+ LOG.error("Push failed", e);
+ return false;
+ }
+ }
+
+ protected final void doHandle(final Any<?> any) throws JobExecutionException {
+ AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+
+ ProvisioningReport result = new ProvisioningReport();
+ profile.getResults().add(result);
+
+ result.setKey(any.getKey());
+ result.setAnyType(any.getType().getKey());
+ result.setName(getName(any));
+
+ Boolean enabled = any instanceof User && profile.getTask().isSyncStatus()
+ ? ((User) any).isSuspended() ? Boolean.FALSE : Boolean.TRUE
+ : null;
+
+ LOG.debug("Propagating {} with key {} towards {}",
+ anyUtils.getAnyTypeKind(), any.getKey(), profile.getTask().getResource());
+
+ Object output = null;
+ Result resultStatus = null;
+ String operation = null;
+
+ // Try to read remote object BEFORE any actual operation
+ Provision provision = profile.getTask().getResource().getProvision(any.getType());
+ String connObjecKey = mappingManager.getConnObjectKeyValue(any, provision);
+
+ ConnectorObject beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass());
+
+ Boolean status = profile.getTask().isSyncStatus() ? enabled : null;
+
+ if (profile.isDryRun()) {
+ if (beforeObj == null) {
+ result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+ } else {
+ result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+ }
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ } else {
+ try {
+ if (beforeObj == null) {
+ operation = UnmatchingRule.toEventName(profile.getTask().getUnmatchingRule());
+ result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+
+ switch (profile.getTask().getUnmatchingRule()) {
+ case ASSIGN:
+ for (PushActions action : profile.getActions()) {
+ action.beforeAssign(this.getProfile(), any);
+ }
+
+ if (!profile.getTask().isPerformCreate()) {
+ LOG.debug("PushTask not configured for create");
+ } else {
+ assign(any, status);
+ }
+
+ break;
+
+ case PROVISION:
+ for (PushActions action : profile.getActions()) {
+ action.beforeProvision(this.getProfile(), any);
+ }
+
+ if (!profile.getTask().isPerformCreate()) {
+ LOG.debug("PushTask not configured for create");
+ } else {
+ provision(any, status);
+ }
+
+ break;
+
+ case UNLINK:
+ for (PushActions action : profile.getActions()) {
+ action.beforeUnlink(this.getProfile(), any);
+ }
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PushTask not configured for update");
+ } else {
+ link(any, true);
+ }
+
+ break;
+
+ case IGNORE:
+ LOG.debug("Ignored any: {}", any);
+ break;
+ default:
+ // do nothing
+ }
+ } else {
+ operation = MatchingRule.toEventName(profile.getTask().getMatchingRule());
+ result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+
+ switch (profile.getTask().getMatchingRule()) {
+ case UPDATE:
+ for (PushActions action : profile.getActions()) {
+ action.beforeUpdate(this.getProfile(), any);
+ }
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PushTask not configured for update");
+ } else {
+ update(any, status);
+ }
+
+ break;
+
+ case DEPROVISION:
+ for (PushActions action : profile.getActions()) {
+ action.beforeDeprovision(this.getProfile(), any);
+ }
+
+ if (!profile.getTask().isPerformDelete()) {
+ LOG.debug("PushTask not configured for delete");
+ } else {
+ deprovision(any);
+ }
+
+ break;
+
+ case UNASSIGN:
+ for (PushActions action : profile.getActions()) {
+ action.beforeUnassign(this.getProfile(), any);
+ }
+
+ if (!profile.getTask().isPerformDelete()) {
+ LOG.debug("PushTask not configured for delete");
+ } else {
+ unassign(any);
+ }
+
+ break;
+
+ case LINK:
+ for (PushActions action : profile.getActions()) {
+ action.beforeLink(this.getProfile(), any);
+ }
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PushTask not configured for update");
+ } else {
+ link(any, false);
+ }
+
+ break;
+
+ case UNLINK:
+ for (PushActions action : profile.getActions()) {
+ action.beforeUnlink(this.getProfile(), any);
+ }
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PushTask not configured for update");
+ } else {
+ link(any, true);
+ }
+
+ break;
+
+ case IGNORE:
+ LOG.debug("Ignored any: {}", any);
+ break;
+ default:
+ // do nothing
+ }
+ }
+
+ for (PushActions action : profile.getActions()) {
+ action.after(this.getProfile(), any, result);
+ }
+
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ resultStatus = AuditElements.Result.SUCCESS;
+ output = getRemoteObject(connObjecKey, provision.getObjectClass());
+ } catch (IgnoreProvisionException e) {
+ throw e;
+ } catch (Exception e) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ resultStatus = AuditElements.Result.FAILURE;
+ output = e;
+
+ LOG.warn("Error pushing {} towards {}", any, profile.getTask().getResource(), e);
+
+ for (PushActions action : profile.getActions()) {
+ action.onError(this.getProfile(), any, result, e);
+ }
+
+ throw new JobExecutionException(e);
+ } finally {
+ notificationManager.createTasks(AuditElements.EventCategoryType.PUSH,
+ any.getType().getKind().name().toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ operation,
+ resultStatus,
+ beforeObj,
+ output,
+ any);
+ auditManager.audit(AuditElements.EventCategoryType.PUSH,
+ any.getType().getKind().name().toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ operation,
+ resultStatus,
+ connObjectUtils.getConnObjectTO(beforeObj),
+ output instanceof ConnectorObject
+ ? connObjectUtils.getConnObjectTO((ConnectorObject) output) : output,
+ any);
+ }
+ }
+ }
+
+ private ResourceOperation getResourceOperation(final UnmatchingRule rule) {
+ switch (rule) {
+ case ASSIGN:
+ case PROVISION:
+ return ResourceOperation.CREATE;
+ default:
+ return ResourceOperation.NONE;
+ }
+ }
+
+ private ResourceOperation getResourceOperation(final MatchingRule rule) {
+ switch (rule) {
+ case UPDATE:
+ return ResourceOperation.UPDATE;
+ case DEPROVISION:
+ case UNASSIGN:
+ return ResourceOperation.DELETE;
+ default:
+ return ResourceOperation.NONE;
+ }
+ }
+
+ protected Any<?> update(final Any<?> any, final Boolean enabled) {
+ boolean changepwd;
+ Collection<String> resourceNames;
+ if (any instanceof User) {
+ changepwd = true;
+ resourceNames = userDAO.findAllResourceNames((User) any);
+ } else if (any instanceof AnyObject) {
+ changepwd = false;
+ resourceNames = anyObjectDAO.findAllResourceNames((AnyObject) any);
+ } else {
+ changepwd = false;
+ resourceNames = ((Group) any).getResourceNames();
+ }
+
+ List<String> noPropResources = new ArrayList<>(resourceNames);
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getUpdateTasks(
+ any.getType().getKind(),
+ any.getKey(),
+ changepwd,
+ null,
+ propByRes,
+ null,
+ noPropResources));
+
+ return getAny(any.getKey());
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncResultHandler.java
new file mode 100644
index 0000000..42762f2
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncResultHandler.java
@@ -0,0 +1,797 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.StringPatchItem;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncActions;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
+import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
+import org.apache.syncope.core.provisioning.api.syncpull.IgnoreProvisionException;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncopeSyncResultHandler;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional(rollbackFor = Throwable.class)
+public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHandler<SyncTask, SyncActions>
+ implements SyncopeSyncResultHandler {
+
+ @Autowired
+ protected SyncUtils syncUtilities;
+
+ @Autowired
+ protected VirSchemaDAO virSchemaDAO;
+
+ @Autowired
+ protected VirAttrCache virAttrCache;
+
+ protected abstract String getName(AnyTO anyTO);
+
+ protected abstract ProvisioningManager<?, ?> getProvisioningManager();
+
+ protected abstract AnyTO doCreate(AnyTO anyTO, SyncDelta delta, ProvisioningReport result);
+
+ protected AnyTO doLink(final AnyTO before, final boolean unlink) {
+ AnyPatch patch = newPatch(before.getKey());
+ patch.setKey(before.getKey());
+ patch.getResources().add(new StringPatchItem.Builder().
+ operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE).
+ value(profile.getTask().getResource().getKey()).build());
+
+ return getAnyTO(update(patch).getResult());
+ }
+
+ protected abstract AnyTO doUpdate(AnyTO before, AnyPatch anyPatch, SyncDelta delta, ProvisioningReport result);
+
+ protected void doDeprovision(final AnyTypeKind kind, final Long key, final boolean unlink) {
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
+ taskExecutor.execute(propagationManager.getDeleteTasks(
+ kind,
+ key,
+ propByRes,
+ null));
+
+ if (unlink) {
+ AnyPatch anyObjectPatch = newPatch(key);
+ anyObjectPatch.getResources().add(new StringPatchItem.Builder().
+ operation(PatchOperation.DELETE).
+ value(profile.getTask().getResource().getKey()).build());
+ }
+ }
+
+ protected void doDelete(final AnyTypeKind kind, final Long key) {
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
+ try {
+ taskExecutor.execute(propagationManager.getDeleteTasks(
+ kind,
+ key,
+ propByRes,
+ null));
+ } catch (Exception e) {
+ // A propagation failure doesn't imply a synchronization failure.
+ // The propagation exception status will be reported into the propagation task execution.
+ LOG.error("Could not propagate anyObject " + key, e);
+ }
+
+ getProvisioningManager().delete(key, true);
+ }
+
+ @Override
+ public boolean handle(final SyncDelta delta) {
+ Provision provision = null;
+ try {
+ provision = profile.getTask().getResource().getProvision(delta.getObject().getObjectClass());
+ if (provision == null) {
+ throw new JobExecutionException("No provision found on " + profile.getTask().getResource() + " for "
+ + delta.getObject().getObjectClass());
+ }
+
+ doHandle(delta, provision);
+ return true;
+ } catch (IgnoreProvisionException e) {
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.NONE);
+ result.setAnyType(provision == null
+ ? getAnyUtils().getAnyTypeKind().name() : provision.getAnyType().getKey());
+ result.setStatus(ProvisioningReport.Status.IGNORE);
+ result.setKey(0L);
+ result.setName(delta.getObject().getName().getNameValue());
+ profile.getResults().add(result);
+
+ LOG.warn("Ignoring during synchronization", e);
+ return true;
+ } catch (JobExecutionException e) {
+ LOG.error("Synchronization failed", e);
+ return false;
+ }
+ }
+
+ protected List<ProvisioningReport> assign(
+ final SyncDelta delta, final Provision provision, final AnyUtils anyUtils)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformCreate()) {
+ LOG.debug("SyncTask not configured for create");
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
+
+ anyTO.getResources().add(profile.getTask().getResource().getKey());
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.CREATE);
+ result.setAnyType(provision.getAnyType().getKey());
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setName(getName(anyTO));
+
+ if (profile.isDryRun()) {
+ result.setKey(0L);
+ } else {
+ SyncDelta actionedDelta = delta;
+ for (SyncActions action : profile.getActions()) {
+ actionedDelta = action.beforeAssign(this.getProfile(), actionedDelta, anyTO);
+ }
+
+ create(anyTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
+ }
+
+ return Collections.singletonList(result);
+ }
+
+ protected List<ProvisioningReport> provision(
+ final SyncDelta delta, final Provision provision, final AnyUtils anyUtils)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformCreate()) {
+ LOG.debug("SyncTask not configured for create");
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.CREATE);
+ result.setAnyType(provision.getAnyType().getKey());
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setName(getName(anyTO));
+
+ if (profile.isDryRun()) {
+ result.setKey(0L);
+ } else {
+ SyncDelta actionedDelta = delta;
+ for (SyncActions action : profile.getActions()) {
+ actionedDelta = action.beforeProvision(this.getProfile(), actionedDelta, anyTO);
+ }
+
+ create(anyTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
+ }
+
+ return Collections.singletonList(result);
+ }
+
+ private void create(
+ final AnyTO anyTO,
+ final SyncDelta delta,
+ final String operation,
+ final ProvisioningReport result)
+ throws JobExecutionException {
+
+ Object output;
+ Result resultStatus;
+
+ try {
+ AnyTO actual = doCreate(anyTO, delta, result);
+ result.setName(getName(actual));
+ output = actual;
+ resultStatus = Result.SUCCESS;
+
+ for (SyncActions action : profile.getActions()) {
+ action.after(this.getProfile(), delta, actual, result);
+ }
+ } catch (IgnoreProvisionException e) {
+ throw e;
+ } catch (PropagationException e) {
+ // A propagation failure doesn't imply a synchronization failure.
+ // The propagation exception status will be reported into the propagation task execution.
+ LOG.error("Could not propagate {} {}", anyTO.getType(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+
+ for (SyncActions action : profile.getActions()) {
+ action.onError(this.getProfile(), delta, result, e);
+ }
+ } catch (Exception e) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not create {} {} ", anyTO.getType(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+
+ for (SyncActions action : profile.getActions()) {
+ action.onError(this.getProfile(), delta, result, e);
+ }
+ }
+
+ audit(operation, resultStatus, null, output, delta);
+ }
+
+ protected List<ProvisioningReport> update(final SyncDelta delta, final List<Long> anys,
+ final Provision provision) throws JobExecutionException {
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("SyncTask not configured for update");
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ LOG.debug("About to update {}", anys);
+
+ List<ProvisioningReport> results = new ArrayList<>();
+
+ SyncDelta workingDelta = delta;
+ for (Long key : anys) {
+ LOG.debug("About to update {}", key);
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.UPDATE);
+ result.setAnyType(provision.getAnyType().getKey());
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setKey(key);
+
+ AnyTO before = getAnyTO(key);
+ if (before == null) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
+ } else {
+ result.setName(getName(before));
+ }
+
+ Result resultStatus;
+ Object output;
+ if (!profile.isDryRun()) {
+ if (before == null) {
+ resultStatus = Result.FAILURE;
+ output = null;
+ } else {
+ try {
+ AnyPatch anyPatch = connObjectUtils.getAnyPatch(
+ before.getKey(),
+ workingDelta.getObject(),
+ before,
+ profile.getTask(),
+ provision,
+ getAnyUtils());
+
+ for (SyncActions action : profile.getActions()) {
+ workingDelta = action.beforeUpdate(this.getProfile(), workingDelta, before, anyPatch);
+ }
+
+ AnyTO updated = doUpdate(before, anyPatch, workingDelta, result);
+
+ for (SyncActions action : profile.getActions()) {
+ action.after(this.getProfile(), workingDelta, updated, result);
+ }
+
+ output = updated;
+ resultStatus = Result.SUCCESS;
+ result.setName(getName(updated));
+ LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
+ } catch (IgnoreProvisionException e) {
+ throw e;
+ } catch (PropagationException e) {
+ // A propagation failure doesn't imply a synchronization failure.
+ // The propagation exception status will be reported into the propagation task execution.
+ LOG.error("Could not propagate {} {}",
+ provision.getAnyType().getKey(), workingDelta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+
+ for (SyncActions action : profile.getActions()) {
+ action.onError(this.getProfile(), workingDelta, result, e);
+ }
+ } catch (Exception e) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not update {} {}",
+ provision.getAnyType().getKey(), workingDelta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+
+ for (SyncActions action : profile.getActions()) {
+ action.onError(this.getProfile(), workingDelta, result, e);
+ }
+ }
+ }
+ audit(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, workingDelta);
+ }
+ results.add(result);
+ }
+ return results;
+ }
+
+ protected List<ProvisioningReport> deprovision(
+ final SyncDelta delta,
+ final List<Long> anys,
+ final Provision provision,
+ final boolean unlink)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("SyncTask not configured for update");
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ LOG.debug("About to update {}", anys);
+
+ final List<ProvisioningReport> updResults = new ArrayList<>();
+
+ for (Long key : anys) {
+ LOG.debug("About to unassign resource {}", key);
+
+ Object output;
+ Result resultStatus;
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.DELETE);
+ result.setAnyType(provision.getAnyType().getKey());
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setKey(key);
+
+ AnyTO before = getAnyTO(key);
+
+ if (before == null) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
+ }
+
+ if (!profile.isDryRun()) {
+ if (before == null) {
+ resultStatus = Result.FAILURE;
+ output = null;
+ } else {
+ result.setName(getName(before));
+
+ try {
+ if (unlink) {
+ for (SyncActions action : profile.getActions()) {
+ action.beforeUnassign(this.getProfile(), delta, before);
+ }
+ } else {
+ for (SyncActions action : profile.getActions()) {
+ action.beforeDeprovision(this.getProfile(), delta, before);
+ }
+ }
+
+ doDeprovision(provision.getAnyType().getKind(), key, unlink);
+ output = getAnyTO(key);
+
+ for (SyncActions action : profile.getActions()) {
+ action.after(this.getProfile(), delta, AnyTO.class.cast(output), result);
+ }
+
+ resultStatus = Result.SUCCESS;
+ LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
+ } catch (IgnoreProvisionException e) {
+ throw e;
+ } catch (PropagationException e) {
+ // A propagation failure doesn't imply a synchronization failure.
+ // The propagation exception status will be reported into the propagation task execution.
+ LOG.error("Could not propagate {} {}",
+ provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+
+ for (SyncActions action : profile.getActions()) {
+ action.onError(this.getProfile(), delta, result, e);
+ }
+ } catch (Exception e) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not update {} {}",
+ provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+
+ for (SyncActions action : profile.getActions()) {
+ action.onError(this.getProfile(), delta, result, e);
+ }
+ }
+ }
+ audit(unlink
+ ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
+ : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
+ }
+ updResults.add(result);
+ }
+
+ return updResults;
+ }
+
+ protected List<ProvisioningReport> link(
+ final SyncDelta delta,
+ final List<Long> anys,
+ final Provision provision,
+ final boolean unlink)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("SyncTask not configured for update");
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ LOG.debug("About to update {}", anys);
+
+ final List<ProvisioningReport> updResults = new ArrayList<>();
+
+ for (Long key : anys) {
+ LOG.debug("About to unassign resource {}", key);
+
+ Object output;
+ Result resultStatus;
+
+ ProvisioningReport result = new ProvisioningReport();
+ result.setOperation(ResourceOperation.NONE);
+ result.setAnyType(provision.getAnyType().getKey());
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ result.setKey(key);
+
+ AnyTO before = getAnyTO(key);
+
+ if (before == null) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
+ }
+
+ if (!profile.isDryRun()) {
+ if (before == null) {
+ resultStatus = Result.FAILURE;
+ output = null;
+ } else {
+ result.setName(getName(before));
+
+ try {
+ if (unlink) {
+ for (SyncActions action : profile.getActions()) {
+ action.beforeUnlink(this.getProfile(), delta, before);
+ }
+ } else {
+ for (SyncActions action : profile.getActions()) {
+ action.beforeLink(this.getProfile(), delta, before);
+ }
+ }
+
+ output = doLink(before, unlink);
+
+ for (SyncActions action : profile.getActions()) {
+ action.after(this.getProfile(), delta, AnyTO.class.cast(output), result);
+ }
+
+ resultStatus = Result.SUCCESS;
+ LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
+ } catch (IgnoreProvisionException e) {
+ throw e;
+ } catch (PropagationException e) {
+ // A propagation failure doesn't imply a synchronization failure.
+ // The propagation exception status will be reported into the propagation task execution.
+ LOG.error("Could not propagate {} {}",
+ provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+
+ for (SyncActions action : profile.getActions()) {
+ action.onError(this.getProfile(), delta, result, e);
+ }
+ } catch (Exception e) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not update {} {}",
+ provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+
+ for (SyncActions action : profile.getActions()) {
+ action.onError(this.getProfile(), delta, result, e);
+ }
+ }
+ }
+ audit(unlink ? MatchingRule.toEventName(MatchingRule.UNLINK)
+ : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, delta);
+ }
+ updResults.add(result);
+ }
+
+ return updResults;
+ }
+
+ protected List<ProvisioningReport> delete(
+ final SyncDelta delta,
+ final List<Long> anys,
+ final Provision provision)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformDelete()) {
+ LOG.debug("SyncTask not configured for delete");
+ return Collections.<ProvisioningReport>emptyList();
+ }
+
+ LOG.debug("About to delete {}", anys);
+
+ List<ProvisioningReport> delResults = new ArrayList<>();
+
+ SyncDelta workingDelta = delta;
+ for (Long key : anys) {
+ Object output;
+ Result resultStatus = Result.FAILURE;
+
+ ProvisioningReport result = new ProvisioningReport();
+
+ try {
+ AnyTO before = getAnyTO(key);
+
+ result.setKey(key);
+ result.setName(getName(before));
+ result.setOperation(ResourceOperation.DELETE);
+ result.setAnyType(provision.getAnyType().getKey());
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+
+ if (!profile.isDryRun()) {
+ for (SyncActions action : profile.getActions()) {
+ workingDelta = action.beforeDelete(this.getProfile(), workingDelta, before);
+ }
+
+ try {
+ doDelete(provision.getAnyType().getKind(), key);
+ output = null;
+ resultStatus = Result.SUCCESS;
+
+ for (SyncActions action : profile.getActions()) {
+ action.after(this.getProfile(), workingDelta, before, result);
+ }
+ } catch (IgnoreProvisionException e) {
+ throw e;
+ } catch (Exception e) {
+ result.setStatus(ProvisioningReport.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), key, e);
+ output = e;
+
+ for (SyncActions action : profile.getActions()) {
+ action.onError(this.getProfile(), workingDelta, result, e);
+ }
+ }
+
+ audit(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
+ }
+
+ delResults.add(result);
+ } catch (NotFoundException e) {
+ LOG.error("Could not find {} {}", provision.getAnyType().getKey(), key, e);
+ } catch (DelegatedAdministrationException e) {
+ LOG.error("Not allowed to read {} {}", provision.getAnyType().getKey(), key, e);
+ } catch (Exception e) {
+ LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), key, e);
+ }
+ }
+
+ return delResults;
+ }
+
+ private List<ProvisioningReport> ignore(
+ final SyncDelta delta,
+ final Provision provision,
+ final boolean matching)
+ throws JobExecutionException {
+
+ LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
+
+ final List<ProvisioningReport> ignoreResults = new ArrayList<>();
+ ProvisioningReport result = new ProvisioningReport();
+
+ result.setKey(null);
+ result.setName(delta.getObject().getUid().getUidValue());
+ result.setOperation(ResourceOperation.NONE);
+ result.setAnyType(provision.getAnyType().getKey());
+ result.setStatus(ProvisioningReport.Status.SUCCESS);
+ ignoreResults.add(result);
+
+ if (!profile.isDryRun()) {
+ audit(matching
+ ? MatchingRule.toEventName(MatchingRule.IGNORE)
+ : UnmatchingRule.toEventName(UnmatchingRule.IGNORE), Result.SUCCESS, null, null, delta);
+ }
+
+ return ignoreResults;
+ }
+
+ /**
+ * Look into SyncDelta and take necessary profile.getActions() (create / update / delete) on any object(s).
+ *
+ * @param delta returned by the underlying profile.getConnector()
+ * @param provision provisioning info
+ * @throws JobExecutionException in case of synchronization failure.
+ */
+ protected void doHandle(final SyncDelta delta, final Provision provision) throws JobExecutionException {
+ AnyUtils anyUtils = getAnyUtils();
+
+ LOG.debug("Process {} for {} as {}",
+ delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
+
+ String uid = delta.getPreviousUid() == null
+ ? delta.getUid().getUidValue()
+ : delta.getPreviousUid().getUidValue();
+
+ try {
+ List<Long> anyKeys = syncUtilities.findExisting(uid, delta.getObject(), provision, anyUtils);
+ LOG.debug("Match(es) found for {} as {}: {}",
+ delta.getUid().getUidValue(), delta.getObject().getObjectClass(), anyKeys);
+
+ if (anyKeys.size() > 1) {
+ switch (profile.getResAct()) {
+ case IGNORE:
+ throw new IllegalStateException("More than one match " + anyKeys);
+
+ case FIRSTMATCH:
+ anyKeys = anyKeys.subList(0, 1);
+ break;
+
+ case LASTMATCH:
+ anyKeys = anyKeys.subList(anyKeys.size() - 1, anyKeys.size());
+ break;
+
+ default:
+ // keep anyKeys unmodified
+ }
+ }
+
+ if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
+ if (anyKeys.isEmpty()) {
+ switch (profile.getTask().getUnmatchingRule()) {
+ case ASSIGN:
+ profile.getResults().addAll(assign(delta, provision, anyUtils));
+ break;
+
+ case PROVISION:
+ profile.getResults().addAll(provision(delta, provision, anyUtils));
+ break;
+
+ case IGNORE:
+ profile.getResults().addAll(ignore(delta, provision, false));
+ break;
+
+ default:
+ // do nothing
+ }
+ } else {
+ // update VirAttrCache
+ for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) {
+ Attribute attr = delta.getObject().getAttributeByName(virSchema.getExtAttrName());
+ for (Long anyKey : anyKeys) {
+ if (attr == null) {
+ virAttrCache.expire(
+ provision.getAnyType().getKey(),
+ anyKey,
+ virSchema.getKey());
+ } else {
+ VirAttrCacheValue cacheValue = new VirAttrCacheValue();
+ cacheValue.setValues(attr.getValue());
+ virAttrCache.put(
+ provision.getAnyType().getKey(),
+ anyKey,
+ virSchema.getKey(),
+ cacheValue);
+ }
+ }
+ }
+
+ switch (profile.getTask().getMatchingRule()) {
+ case UPDATE:
+ profile.getResults().addAll(update(delta, anyKeys, provision));
+ break;
+
+ case DEPROVISION:
+ profile.getResults().addAll(deprovision(delta, anyKeys, provision, false));
+ break;
+
+ case UNASSIGN:
+ profile.getResults().addAll(deprovision(delta, anyKeys, provision, true));
+ break;
+
+ case LINK:
+ profile.getResults().addAll(link(delta, anyKeys, provision, false));
+ break;
+
+ case UNLINK:
+ profile.getResults().addAll(link(delta, anyKeys, provision, true));
+ break;
+
+ case IGNORE:
+ profile.getResults().addAll(ignore(delta, provision, true));
+ break;
+
+ default:
+ // do nothing
+ }
+ }
+ } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
+ if (anyKeys.isEmpty()) {
+ LOG.debug("No match found for deletion");
+ } else {
+ profile.getResults().addAll(delete(delta, anyKeys, provision));
+ }
+ }
+ } catch (IllegalStateException | IllegalArgumentException e) {
+ LOG.warn(e.getMessage());
+ }
+ }
+
+ private void audit(
+ final String event,
+ final Result result,
+ final Object before,
+ final Object output,
+ final Object... input) {
+
+ notificationManager.createTasks(AuditElements.EventCategoryType.SYNCHRONIZATION,
+ getAnyUtils().getAnyTypeKind().name().toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ event,
+ result,
+ before,
+ output,
+ input);
+
+ auditManager.audit(AuditElements.EventCategoryType.SYNCHRONIZATION,
+ getAnyUtils().getAnyTypeKind().name().toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ event,
+ result,
+ before,
+ output,
+ input);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncopeResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncopeResultHandler.java
new file mode 100644
index 0000000..bf2cd6e
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AbstractSyncopeResultHandler.java
@@ -0,0 +1,155 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncopeResultHandler;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+import org.apache.syncope.core.provisioning.api.AuditManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
+import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningActions;
+import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
+import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
+import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A extends ProvisioningActions>
+ implements SyncopeResultHandler<T, A> {
+
+ protected static final Logger LOG = LoggerFactory.getLogger(SyncopeResultHandler.class);
+
+ @Autowired
+ protected AnyObjectDAO anyObjectDAO;
+
+ @Autowired
+ protected UserDAO userDAO;
+
+ @Autowired
+ protected GroupDAO groupDAO;
+
+ /**
+ * ConnectorObject utils.
+ */
+ @Autowired
+ protected ConnObjectUtils connObjectUtils;
+
+ /**
+ * Notification Manager.
+ */
+ @Autowired
+ protected NotificationManager notificationManager;
+
+ /**
+ * Audit Manager.
+ */
+ @Autowired
+ protected AuditManager auditManager;
+
+ /**
+ * Propagation manager.
+ */
+ @Autowired
+ protected PropagationManager propagationManager;
+
+ /**
+ * Task executor.
+ */
+ @Autowired
+ protected PropagationTaskExecutor taskExecutor;
+
+ protected AnyObjectWorkflowAdapter awfAdapter;
+
+ /**
+ * User workflow adapter.
+ */
+ @Autowired
+ protected UserWorkflowAdapter uwfAdapter;
+
+ /**
+ * Group workflow adapter.
+ */
+ @Autowired
+ protected GroupWorkflowAdapter gwfAdapter;
+
+ @Autowired
+ protected AnyObjectDataBinder anyObjectDataBinder;
+
+ @Autowired
+ protected UserDataBinder userDataBinder;
+
+ @Autowired
+ protected GroupDataBinder groupDataBinder;
+
+ @Autowired
+ protected AnyObjectProvisioningManager anyObjectProvisioningManager;
+
+ @Autowired
+ protected UserProvisioningManager userProvisioningManager;
+
+ @Autowired
+ protected GroupProvisioningManager groupProvisioningManager;
+
+ @Autowired
+ protected AnyUtilsFactory anyUtilsFactory;
+
+ /**
+ * Sync profile.
+ */
+ protected ProvisioningProfile<T, A> profile;
+
+ protected abstract AnyUtils getAnyUtils();
+
+ protected abstract AnyTO getAnyTO(long key);
+
+ protected abstract Any<?> getAny(long key);
+
+ protected abstract AnyPatch newPatch(final long key);
+
+ protected abstract WorkflowResult<Long> update(AnyPatch patch);
+
+ @Override
+ public void setProfile(final ProvisioningProfile<T, A> profile) {
+ this.profile = profile;
+ }
+
+ @Override
+ public ProvisioningProfile<T, A> getProfile() {
+ return profile;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectPushResultHandlerImpl.java
new file mode 100644
index 0000000..6f83727
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectPushResultHandlerImpl.java
@@ -0,0 +1,70 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.patch.AnyObjectPatch;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.syncpull.AnyObjectPushResultHandler;
+
+public class AnyObjectPushResultHandlerImpl extends AbstractPushResultHandler implements AnyObjectPushResultHandler {
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
+ }
+
+ @Override
+ protected String getName(final Any<?> any) {
+ return StringUtils.EMPTY;
+ }
+
+ @Override
+ protected Any<?> getAny(final long key) {
+ try {
+ return anyObjectDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving anyObject {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final long key) {
+ return anyObjectDataBinder.getAnyObjectTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final long key) {
+ AnyObjectPatch patch = new AnyObjectPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<Long> update(final AnyPatch patch) {
+ return awfAdapter.update((AnyObjectPatch) patch);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectSyncResultHandlerImpl.java
new file mode 100644
index 0000000..a8c6c1b
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/AnyObjectSyncResultHandlerImpl.java
@@ -0,0 +1,112 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.patch.AnyObjectPatch;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.syncpull.AnyObjectSyncResultHandler;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+
+public class AnyObjectSyncResultHandlerImpl extends AbstractSyncResultHandler implements AnyObjectSyncResultHandler {
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
+ }
+
+ @Override
+ protected String getName(final AnyTO anyTO) {
+ return StringUtils.EMPTY;
+ }
+
+ @Override
+ protected ProvisioningManager<?, ?> getProvisioningManager() {
+ return anyObjectProvisioningManager;
+ }
+
+ @Override
+ protected Any<?> getAny(final long key) {
+ try {
+ return anyObjectDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving anyObject {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final long key) {
+ return anyObjectDataBinder.getAnyObjectTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final long key) {
+ AnyObjectPatch patch = new AnyObjectPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<Long> update(final AnyPatch patch) {
+ return awfAdapter.update((AnyObjectPatch) patch);
+ }
+
+ @Override
+ protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningReport result) {
+ AnyObjectTO anyObjectTO = AnyObjectTO.class.cast(anyTO);
+
+ Map.Entry<Long, List<PropagationStatus>> created = anyObjectProvisioningManager.create(
+ anyObjectTO, Collections.singleton(profile.getTask().getResource().getKey()), true);
+
+ result.setKey(created.getKey());
+ result.setName(getName(anyTO));
+
+ return getAnyTO(created.getKey());
+ }
+
+ @Override
+ protected AnyTO doUpdate(
+ final AnyTO before,
+ final AnyPatch anyPatch,
+ final SyncDelta delta,
+ final ProvisioningReport result) {
+
+ AnyObjectPatch anyObjectPatch = AnyObjectPatch.class.cast(anyPatch);
+
+ Map.Entry<Long, List<PropagationStatus>> updated =
+ anyObjectProvisioningManager.update(anyObjectPatch, true);
+
+ AnyObjectTO after = anyObjectDataBinder.getAnyObjectTO(updated.getKey());
+ result.setName(getName(after));
+ return after;
+ }
+}
[13/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
new file mode 100644
index 0000000..ba9255a
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondConverter.java
@@ -0,0 +1,64 @@
+/*
+ * 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.core.persistence.api.search;
+
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.cxf.jaxrs.ext.search.SearchBean;
+import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.search.AbstractFiqlSearchConditionBuilder;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+
+/**
+ * Converts FIQL expressions to Syncope's {@link SearchCond}.
+ */
+public final class SearchCondConverter {
+
+ /**
+ * Parses a FIQL expression into Syncope's <tt>SearchCond</tt>, using CXF's <tt>FiqlParser</tt>.
+ *
+ * @param fiqlExpression FIQL string
+ * @param realms optional realm to provide to {@link SearchCondVisitor}
+ * @return {@link SearchCond} instance for given FIQL expression
+ * @see FiqlParser
+ */
+ public static SearchCond convert(final String fiqlExpression, final String... realms) {
+ FiqlParser<SearchBean> fiqlParser = new FiqlParser<>(
+ SearchBean.class, AbstractFiqlSearchConditionBuilder.CONTEXTUAL_PROPERTIES);
+
+ try {
+ SearchCondVisitor searchCondVisitor = new SearchCondVisitor();
+ if (realms != null && realms.length > 0) {
+ searchCondVisitor.setRealm(realms[0]);
+ }
+ searchCondVisitor.visit(fiqlParser.parse(fiqlExpression));
+ return searchCondVisitor.getQuery();
+ } catch (Exception e) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression);
+ sce.getElements().add(fiqlExpression);
+ sce.getElements().add(ExceptionUtils.getRootCauseMessage(e));
+ throw sce;
+ }
+ }
+
+ private SearchCondConverter() {
+ // empty constructor for static utility class
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
new file mode 100644
index 0000000..79fe904
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/SearchCondVisitor.java
@@ -0,0 +1,222 @@
+/*
+ * 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.core.persistence.api.search;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.cxf.jaxrs.ext.search.ConditionType;
+import org.apache.cxf.jaxrs.ext.search.SearchBean;
+import org.apache.cxf.jaxrs.ext.search.SearchCondition;
+import org.apache.cxf.jaxrs.ext.search.SearchUtils;
+import org.apache.cxf.jaxrs.ext.search.visitor.AbstractSearchConditionVisitor;
+import org.apache.syncope.common.lib.EntityTOUtils;
+import org.apache.syncope.common.lib.search.SpecialAttr;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
+import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
+import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
+
+/**
+ * Converts CXF's <tt>SearchCondition</tt> into internal <tt>SearchCond</tt>.
+ */
+public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean, SearchCond> {
+
+ private String realm;
+
+ private SearchCond searchCond;
+
+ public SearchCondVisitor() {
+ super(null);
+ }
+
+ public void setRealm(final String realm) {
+ this.realm = realm;
+ }
+
+ private AttributeCond createAttributeCond(final String schema) {
+ AttributeCond attributeCond = EntityTOUtils.ANY_FIELDS.contains(schema)
+ ? new AnyCond()
+ : new AttributeCond();
+ attributeCond.setSchema(schema);
+ return attributeCond;
+ }
+
+ private SearchCond visitPrimitive(final SearchCondition<SearchBean> sc) {
+ String name = getRealPropertyName(sc.getStatement().getProperty());
+ SpecialAttr specialAttrName = SpecialAttr.fromString(name);
+
+ String value = SearchUtils.toSqlWildcardString(sc.getStatement().getValue().toString(), false).
+ replaceAll("\\\\_", "_");
+ SpecialAttr specialAttrValue = SpecialAttr.fromString(value);
+
+ AttributeCond attributeCond = createAttributeCond(name);
+ attributeCond.setExpression(value);
+
+ SearchCond leaf;
+ switch (sc.getConditionType()) {
+ case EQUALS:
+ case NOT_EQUALS:
+ if (specialAttrName == null) {
+ if (specialAttrValue != null && specialAttrValue == SpecialAttr.NULL) {
+ attributeCond.setType(AttributeCond.Type.ISNULL);
+ attributeCond.setExpression(null);
+ } else if (value.indexOf('%') == -1) {
+ attributeCond.setType(AttributeCond.Type.EQ);
+ } else {
+ attributeCond.setType(AttributeCond.Type.LIKE);
+ }
+
+ leaf = SearchCond.getLeafCond(attributeCond);
+ } else {
+ switch (specialAttrName) {
+ case TYPE:
+ AnyTypeCond typeCond = new AnyTypeCond();
+ typeCond.setAnyTypeName(value);
+ leaf = SearchCond.getLeafCond(typeCond);
+ break;
+
+ case RESOURCES:
+ ResourceCond resourceCond = new ResourceCond();
+ resourceCond.setResourceName(value);
+ leaf = SearchCond.getLeafCond(resourceCond);
+ break;
+
+ case GROUPS:
+ MembershipCond groupCond = new MembershipCond();
+ groupCond.setGroupKey(Long.valueOf(value));
+ leaf = SearchCond.getLeafCond(groupCond);
+ break;
+
+ case RELATIONSHIPS:
+ RelationshipCond relationshipCond = new RelationshipCond();
+ relationshipCond.setAnyObjectKey(Long.valueOf(value));
+ leaf = SearchCond.getLeafCond(relationshipCond);
+ break;
+
+ case RELATIONSHIP_TYPES:
+ RelationshipTypeCond relationshipTypeCond = new RelationshipTypeCond();
+ relationshipTypeCond.setRelationshipTypeKey(value);
+ leaf = SearchCond.getLeafCond(relationshipTypeCond);
+ break;
+
+ case ROLES:
+ RoleCond roleCond = new RoleCond();
+ roleCond.setRoleKey(value);
+ leaf = SearchCond.getLeafCond(roleCond);
+ break;
+
+ case ASSIGNABLE:
+ AssignableCond assignableCond = new AssignableCond();
+ assignableCond.setRealmFullPath(realm);
+ leaf = SearchCond.getLeafCond(assignableCond);
+ break;
+
+ default:
+ throw new IllegalArgumentException(
+ String.format("Special attr name %s is not supported", specialAttrName));
+ }
+ }
+ if (sc.getConditionType() == ConditionType.NOT_EQUALS) {
+ if (leaf.getAttributeCond() != null
+ && leaf.getAttributeCond().getType() == AttributeCond.Type.ISNULL) {
+
+ leaf.getAttributeCond().setType(AttributeCond.Type.ISNOTNULL);
+ } else if (leaf.getAnyCond() != null
+ && leaf.getAnyCond().getType() == AnyCond.Type.ISNULL) {
+
+ leaf.getAnyCond().setType(AttributeCond.Type.ISNOTNULL);
+ } else {
+ leaf = SearchCond.getNotLeafCond(leaf);
+ }
+ }
+ break;
+
+ case GREATER_OR_EQUALS:
+ attributeCond.setType(AttributeCond.Type.GE);
+ leaf = SearchCond.getLeafCond(attributeCond);
+ break;
+
+ case GREATER_THAN:
+ attributeCond.setType(AttributeCond.Type.GT);
+ leaf = SearchCond.getLeafCond(attributeCond);
+ break;
+
+ case LESS_OR_EQUALS:
+ attributeCond.setType(AttributeCond.Type.LE);
+ leaf = SearchCond.getLeafCond(attributeCond);
+ break;
+
+ case LESS_THAN:
+ attributeCond.setType(AttributeCond.Type.LT);
+ leaf = SearchCond.getLeafCond(attributeCond);
+ break;
+
+ default:
+ throw new IllegalArgumentException(
+ String.format("Condition type %s is not supported", sc.getConditionType().name()));
+ }
+
+ return leaf;
+ }
+
+ private SearchCond visitCompount(final SearchCondition<SearchBean> sc) {
+ List<SearchCond> searchConds = new ArrayList<>();
+ for (SearchCondition<SearchBean> searchCondition : sc.getSearchConditions()) {
+ searchConds.add(searchCondition.getStatement() == null
+ ? visitCompount(searchCondition)
+ : visitPrimitive(searchCondition));
+ }
+
+ SearchCond compound;
+ switch (sc.getConditionType()) {
+ case AND:
+ compound = SearchCond.getAndCond(searchConds);
+ break;
+
+ case OR:
+ compound = SearchCond.getOrCond(searchConds);
+ break;
+
+ default:
+ throw new IllegalArgumentException(
+ String.format("Condition type %s is not supported", sc.getConditionType().name()));
+ }
+
+ return compound;
+ }
+
+ @Override
+ public void visit(final SearchCondition<SearchBean> sc) {
+ searchCond = sc.getStatement() == null
+ ? visitCompount(sc)
+ : visitPrimitive(sc);
+ }
+
+ @Override
+ public SearchCond getQuery() {
+ return searchCond;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
new file mode 100644
index 0000000..05a8cdc
--- /dev/null
+++ b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/SearchCondConverterTest.java
@@ -0,0 +1,226 @@
+/*
+ * 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.core.persistence.api.search;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
+import org.apache.syncope.common.lib.search.GroupFiqlSearchConditionBuilder;
+import org.apache.syncope.common.lib.search.SpecialAttr;
+import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
+import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
+import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
+import org.junit.Test;
+
+public class SearchCondConverterTest {
+
+ @Test
+ public void eq() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("rossini").query();
+ assertEquals("username==rossini", fiqlExpression);
+
+ AnyCond attrCond = new AnyCond(AttributeCond.Type.EQ);
+ attrCond.setSchema("username");
+ attrCond.setExpression("rossini");
+ SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
+ public void like() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("ros*").query();
+ assertEquals("username==ros*", fiqlExpression);
+
+ AttributeCond attrCond = new AnyCond(AttributeCond.Type.LIKE);
+ attrCond.setSchema("username");
+ attrCond.setExpression("ros%");
+ SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
+ public void isNull() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").nullValue().query();
+ assertEquals("loginDate==" + SpecialAttr.NULL, fiqlExpression);
+
+ AttributeCond attrCond = new AttributeCond(AttributeCond.Type.ISNULL);
+ attrCond.setSchema("loginDate");
+ SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
+ public void isNotNull() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").notNullValue().query();
+ assertEquals("loginDate!=" + SpecialAttr.NULL, fiqlExpression);
+
+ AttributeCond attrCond = new AttributeCond(AttributeCond.Type.ISNOTNULL);
+ attrCond.setSchema("loginDate");
+ SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
+ public void relationships() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().inRelationships(1L).query();
+ assertEquals(SpecialAttr.RELATIONSHIPS + "==1", fiqlExpression);
+
+ RelationshipCond relationshipCond = new RelationshipCond();
+ relationshipCond.setAnyObjectKey(1L);
+ SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
+ public void relationshipTypes() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().inRelationshipTypes("type1").query();
+ assertEquals(SpecialAttr.RELATIONSHIP_TYPES + "==type1", fiqlExpression);
+
+ RelationshipTypeCond relationshipCond = new RelationshipTypeCond();
+ relationshipCond.setRelationshipTypeKey("type1");
+ SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+
+ fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").inRelationshipTypes("neighborhood").query();
+ assertEquals(
+ SpecialAttr.RELATIONSHIP_TYPES + "==neighborhood;" + SpecialAttr.TYPE + "==PRINTER",
+ fiqlExpression);
+ }
+
+ @Test
+ public void groups() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().inGroups(1L).query();
+ assertEquals(SpecialAttr.GROUPS + "==1", fiqlExpression);
+
+ MembershipCond groupCond = new MembershipCond();
+ groupCond.setGroupKey(1L);
+ SearchCond simpleCond = SearchCond.getLeafCond(groupCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
+ public void roles() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().inRoles("User reviewer").query();
+ assertEquals(SpecialAttr.ROLES + "==User reviewer", fiqlExpression);
+
+ RoleCond roleCond = new RoleCond();
+ roleCond.setRoleKey("User reviewer");
+ SearchCond simpleCond = SearchCond.getLeafCond(roleCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
+ public void resources() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().hasResources("resource-ldap").query();
+ assertEquals(SpecialAttr.RESOURCES + "==resource-ldap", fiqlExpression);
+
+ ResourceCond resCond = new ResourceCond();
+ resCond.setResourceName("resource-ldap");
+ SearchCond simpleCond = SearchCond.getLeafCond(resCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
+ public void assignable() {
+ String fiqlExpression = new GroupFiqlSearchConditionBuilder().isAssignable().query();
+ assertEquals(SpecialAttr.ASSIGNABLE + "==" + SpecialAttr.NULL, fiqlExpression);
+
+ AssignableCond assignableCond = new AssignableCond();
+ assignableCond.setRealmFullPath("/even/two");
+ SearchCond simpleCond = SearchCond.getLeafCond(assignableCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression, "/even/two"));
+ }
+
+ @Test
+ public void type() {
+ String fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").query();
+ assertEquals(SpecialAttr.TYPE + "==PRINTER", fiqlExpression);
+
+ AnyTypeCond acond = new AnyTypeCond();
+ acond.setAnyTypeName("PRINTER");
+ SearchCond simpleCond = SearchCond.getLeafCond(acond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
+ public void and() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().
+ is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query();
+ assertEquals("fullname==*o*;fullname==*i*", fiqlExpression);
+
+ AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
+ fullnameLeafCond1.setSchema("fullname");
+ fullnameLeafCond1.setExpression("%o%");
+ AttributeCond fullnameLeafCond2 = new AttributeCond(AttributeCond.Type.LIKE);
+ fullnameLeafCond2.setSchema("fullname");
+ fullnameLeafCond2.setExpression("%i%");
+ SearchCond andCond = SearchCond.getAndCond(
+ SearchCond.getLeafCond(fullnameLeafCond1),
+ SearchCond.getLeafCond(fullnameLeafCond2));
+
+ assertEquals(andCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
+ public void or() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().
+ is("fullname").equalTo("*o*", "*i*", "*ini").query();
+ assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
+ fiqlExpression = new UserFiqlSearchConditionBuilder().
+ is("fullname").equalTo("*o*").or("fullname").equalTo("*i*").or("fullname").equalTo("*ini").query();
+ assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
+
+ AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
+ fullnameLeafCond1.setSchema("fullname");
+ fullnameLeafCond1.setExpression("%o%");
+ AttributeCond fullnameLeafCond2 = new AttributeCond(AttributeCond.Type.LIKE);
+ fullnameLeafCond2.setSchema("fullname");
+ fullnameLeafCond2.setExpression("%i%");
+ AttributeCond fullnameLeafCond3 = new AttributeCond(AttributeCond.Type.LIKE);
+ fullnameLeafCond3.setSchema("fullname");
+ fullnameLeafCond3.setExpression("%ini");
+ SearchCond orCond = SearchCond.getOrCond(
+ SearchCond.getLeafCond(fullnameLeafCond1),
+ SearchCond.getOrCond(
+ SearchCond.getLeafCond(fullnameLeafCond2),
+ SearchCond.getLeafCond(fullnameLeafCond3)));
+
+ assertEquals(orCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/pom.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml
index ee900a5..9126d55 100644
--- a/core/persistence-jpa/pom.xml
+++ b/core/persistence-jpa/pom.xml
@@ -83,16 +83,16 @@ under the License.
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
-
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- </dependency>
+
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
-
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-jexl3</artifactId>
+ </dependency>
+
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
@@ -105,7 +105,7 @@ under the License.
</dependency>
<dependency>
<groupId>org.apache.syncope.core</groupId>
- <artifactId>syncope-core-misc</artifactId>
+ <artifactId>syncope-core-spring</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
index 9cf2b32..e37eb50 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
@@ -27,7 +27,7 @@ import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
index c70c7c7..0e7d059 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
@@ -50,8 +50,8 @@ import javax.xml.transform.stream.StreamResult;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.core.misc.utils.FormatUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.content.ContentExporter;
import org.apache.syncope.core.persistence.jpa.entity.JPAReportExec;
import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
index 5d8cfc5..c4c7d90 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentLoader.java
@@ -27,8 +27,8 @@ import javax.sql.DataSource;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.commons.io.IOUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
import org.apache.syncope.core.persistence.api.content.ContentLoader;
import org.apache.syncope.core.persistence.jpa.entity.conf.JPAConf;
import org.springframework.core.io.support.PropertiesLoaderUtils;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
index 3dbf25d..acbde6e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
@@ -19,8 +19,8 @@
package org.apache.syncope.core.persistence.jpa.dao;
import javax.persistence.EntityManager;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.DAO;
import org.apache.syncope.core.persistence.api.entity.Entity;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultAccountRule.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultAccountRule.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultAccountRule.java
index f2156fc..256ffe6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultAccountRule.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultAccountRule.java
@@ -23,7 +23,7 @@ import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.policy.AccountRuleConf;
import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
-import org.apache.syncope.core.misc.policy.AccountPolicyException;
+import org.apache.syncope.core.provisioning.api.utils.policy.AccountPolicyException;
import org.apache.syncope.core.persistence.api.dao.AccountRule;
import org.apache.syncope.core.persistence.api.dao.AccountRuleConfClass;
import org.apache.syncope.core.persistence.api.entity.PlainAttr;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPasswordRule.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPasswordRule.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPasswordRule.java
index 1ce560a..39a02c0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPasswordRule.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/DefaultPasswordRule.java
@@ -22,8 +22,8 @@ import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.core.misc.policy.PasswordPolicyException;
-import org.apache.syncope.core.misc.policy.PolicyPattern;
+import org.apache.syncope.core.provisioning.api.utils.policy.PasswordPolicyException;
+import org.apache.syncope.core.provisioning.api.utils.policy.PolicyPattern;
import org.apache.syncope.core.persistence.api.dao.PasswordRule;
import org.apache.syncope.core.persistence.api.dao.PasswordRuleConfClass;
import org.apache.syncope.core.persistence.api.entity.PlainAttr;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 4513837..f758ad9 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -35,10 +35,10 @@ import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.Transformer;
import org.apache.syncope.common.lib.types.AnyEntitlement;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.EntitlementsHolder;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.entity.AnyType;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index b0b1162..88c6cbf 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -39,8 +39,8 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.core.misc.utils.RealmUtils;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
index ece8d6c..9a6fe41 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java
@@ -38,10 +38,10 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.utils.RealmUtils;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
index 406a378..e8b4816 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java
@@ -22,7 +22,7 @@ import java.util.List;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
import org.apache.syncope.core.persistence.api.dao.RoleDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.entity.Realm;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index 822c02d..62d179f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -41,11 +41,11 @@ import org.apache.syncope.common.lib.policy.PasswordRuleConf;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.EntityViolationType;
import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.policy.AccountPolicyException;
-import org.apache.syncope.core.misc.policy.PasswordPolicyException;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.utils.policy.AccountPolicyException;
+import org.apache.syncope.core.provisioning.api.utils.policy.PasswordPolicyException;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.ImplementationLookup;
import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
import org.apache.syncope.core.persistence.api.dao.AccountRule;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
index e6ead6f..ad38542 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
@@ -27,7 +27,7 @@ import javax.persistence.MappedSuperclass;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.PlainAttr;
import org.apache.syncope.core.persistence.api.entity.Realm;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java
index 754da9f..21f835b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java
@@ -32,13 +32,13 @@ 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.AttrSchemaType;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException;
import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.jpa.validation.entity.PlainAttrValueCheck;
-import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.spring.security.Encryptor;
@MappedSuperclass
@PlainAttrValueCheck
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java
index c63a401..23a3815 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AnnotatedEntityListener.java
@@ -22,7 +22,7 @@ import java.util.Date;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import org.apache.syncope.core.persistence.api.entity.AnnotatedEntity;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java
index 6aaf62d..1fa004b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtilsFactory.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity;
import java.util.HashMap;
import java.util.Map;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.AnyUtils;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
index d59982e..f018670 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnInstance.java
@@ -44,7 +44,7 @@ import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.jpa.validation.entity.ConnInstanceCheck;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
@Entity
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
index 3e9169e..f9bb394 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADomain.java
@@ -24,7 +24,7 @@ import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.spring.security.Encryptor;
import org.apache.syncope.core.persistence.api.entity.Domain;
import org.apache.syncope.core.persistence.jpa.validation.entity.DomainCheck;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReportletConfInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReportletConfInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReportletConfInstance.java
index df08af8..d744976 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReportletConfInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAReportletConfInstance.java
@@ -25,7 +25,7 @@ import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.apache.syncope.common.lib.report.ReportletConf;
import org.apache.syncope.core.persistence.api.entity.Report;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
@Entity
@Table(name = JPAReportletConfInstance.TABLE)
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
index 7444bd3..e1fcbdd 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
@@ -37,7 +37,7 @@ import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
index c5099f3..146b127 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountPolicy.java
@@ -37,7 +37,7 @@ import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Transformer;
import org.apache.syncope.common.lib.policy.AccountRuleConf;
import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountRuleConfInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountRuleConfInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountRuleConfInstance.java
index 782e6b4..d19c06e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountRuleConfInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAAccountRuleConfInstance.java
@@ -24,7 +24,7 @@ import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.apache.syncope.common.lib.policy.AccountRuleConf;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPasswordRuleConfInstance.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPasswordRuleConfInstance.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPasswordRuleConfInstance.java
index 4b39dc8..dcc543a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPasswordRuleConfInstance.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPasswordRuleConfInstance.java
@@ -24,7 +24,7 @@ import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java
index 3bc0009..7b0c1ef 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPAPushPolicy.java
@@ -23,7 +23,7 @@ import javax.persistence.Lob;
import javax.persistence.Table;
import org.apache.syncope.common.lib.types.PolicyType;
import org.apache.syncope.common.lib.policy.PushPolicySpec;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
@Entity
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPASyncPolicy.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPASyncPolicy.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPASyncPolicy.java
index 913ee54..9d2a518 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPASyncPolicy.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/policy/JPASyncPolicy.java
@@ -23,7 +23,7 @@ import javax.persistence.Lob;
import javax.persistence.Table;
import org.apache.syncope.common.lib.policy.SyncPolicySpec;
import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.entity.policy.SyncPolicy;
@Entity
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
index 28febea..ed6f581 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/AbstractAnyTemplate.java
@@ -22,7 +22,7 @@ import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
index 12d5959..5900f68 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
@@ -52,7 +52,7 @@ import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
import org.apache.syncope.core.persistence.api.entity.policy.SyncPolicy;
import org.apache.syncope.core.persistence.jpa.validation.entity.ExternalResourceCheck;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
index 3906dfd..ec50d2c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
@@ -28,7 +28,7 @@ import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
index 94c7d8d..1be6b9b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
@@ -35,7 +35,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.persistence.jpa.validation.entity.PropagationTaskCheck;
import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.identityconnectors.framework.common.objects.Attribute;
/**
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
index c8e6672..d8a1908 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
@@ -57,9 +57,9 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
import org.apache.syncope.core.persistence.jpa.entity.JPASecurityQuestion;
-import org.apache.syncope.core.misc.security.Encryptor;
-import org.apache.syncope.core.misc.security.SecureRandomUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
new file mode 100644
index 0000000..691f5e4
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptor.java
@@ -0,0 +1,70 @@
+/*
+ * 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.core.persistence.jpa.spring;
+
+import java.lang.reflect.Method;
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
+import org.springframework.transaction.interceptor.TransactionAttribute;
+import org.springframework.transaction.interceptor.TransactionAttributeSource;
+import org.springframework.transaction.interceptor.TransactionInterceptor;
+
+/**
+ * Extends the standard {@link TransactionInterceptor} by dynamically setting the appropriate
+ * {@link TransactionAttribute} qualifier according to the authentication domain of the caller - retrieved via
+ * {@link AuthContextUtils#getDomain()}.
+ */
+public class DomainTransactionInterceptor extends TransactionInterceptor {
+
+ private static final long serialVersionUID = 5113728988680448551L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(DomainTransactionInterceptor.class);
+
+ @Override
+ public TransactionAttributeSource getTransactionAttributeSource() {
+ final TransactionAttributeSource origTxAttrSource = super.getTransactionAttributeSource();
+
+ return new TransactionAttributeSource() {
+
+ @Override
+ public TransactionAttribute getTransactionAttribute(final Method method, final Class<?> targetClass) {
+ TransactionAttribute txAttr = origTxAttrSource.getTransactionAttribute(method, targetClass);
+
+ if (txAttr instanceof DefaultTransactionAttribute) {
+ ((DefaultTransactionAttribute) txAttr).setQualifier(AuthContextUtils.getDomain());
+ }
+
+ return txAttr;
+ }
+ };
+ }
+
+ @Override
+ public Object invoke(final MethodInvocation invocation) throws Throwable {
+ try {
+ return super.invoke(invocation);
+ } catch (Throwable e) {
+ LOG.debug("Error during {} invocation", invocation.getMethod(), e);
+ throw e;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java
new file mode 100644
index 0000000..0353497
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainTransactionInterceptorInjector.java
@@ -0,0 +1,38 @@
+/*
+ * 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.core.persistence.jpa.spring;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.transaction.interceptor.TransactionInterceptor;
+
+/**
+ * Replaces Spring's {@link TransactionInterceptor} with {@link DomainTransactionInterceptor}.
+ */
+public class DomainTransactionInterceptorInjector implements BeanFactoryPostProcessor {
+
+ @Override
+ public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ BeanDefinition bd = beanFactory.getBeanDefinition(TransactionInterceptor.class.getName() + "#0");
+ bd.setBeanClassName(DomainTransactionInterceptor.class.getName());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ConnInstanceValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ConnInstanceValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ConnInstanceValidator.java
index 1ce2190..ecb0edb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ConnInstanceValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ConnInstanceValidator.java
@@ -21,8 +21,8 @@ package org.apache.syncope.core.persistence.jpa.validation.entity;
import javax.validation.ConstraintValidatorContext;
import org.apache.syncope.common.lib.types.EntityViolationType;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.provisioning.api.URIUtils;
-import org.apache.syncope.core.provisioning.api.ConnPoolConfUtils;
+import org.apache.syncope.core.provisioning.api.utils.URIUtils;
+import org.apache.syncope.core.provisioning.api.utils.ConnPoolConfUtils;
public class ConnInstanceValidator extends AbstractValidator<ConnInstanceCheck, ConnInstance> {
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
index 0b60c5e..9d86b88 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java
@@ -25,7 +25,7 @@ import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import org.apache.commons.lang3.ClassUtils;
import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.AnnotatedEntity;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.Entity;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
index 941e63c..7b145d4 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
@@ -27,7 +27,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.types.EntityViolationType;
import org.apache.syncope.common.lib.types.IntMappingType;
import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
index 72b421e..da90bd4 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
@@ -25,9 +25,9 @@ import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTask;
import org.apache.syncope.core.persistence.jpa.entity.task.JPASyncTask;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder;
+import org.apache.syncope.core.provisioning.api.syncpull.PushActions;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncActions;
+import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTaskCheck, ProvisioningTask> {
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/resources/domains.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains.xml b/core/persistence-jpa/src/main/resources/domains.xml
index 5d6b5ab..42f87d0 100644
--- a/core/persistence-jpa/src/main/resources/domains.xml
+++ b/core/persistence-jpa/src/main/resources/domains.xml
@@ -24,7 +24,7 @@ under the License.
<import resource="classpath*:domains/*Domain.xml"/>
- <bean class="org.apache.syncope.core.misc.spring.DomainTransactionInterceptorInjector"/>
+ <bean class="org.apache.syncope.core.persistence.jpa.spring.DomainTransactionInterceptorInjector"/>
<bean id="commonEMFConf" class="org.apache.syncope.core.persistence.jpa.spring.CommonEntityManagerFactoryConf">
<property name="packagesToScan" value="org.apache.syncope.core.persistence.jpa.entity"/>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml b/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
index 5cb38c2..f949e32 100644
--- a/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
+++ b/core/persistence-jpa/src/main/resources/domains/MasterDomain.xml
@@ -28,11 +28,11 @@ under the License.
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
- <bean id="MasterContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="MasterContentXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${content.directory}/domains/MasterContent.xml"/>
<property name="fallback" value="classpath:domains/MasterContent.xml"/>
</bean>
- <bean id="MasterProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="MasterProperties" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${content.directory}/domains/Master.properties"/>
<property name="fallback" value="classpath:domains/Master.properties"/>
</bean>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/main/resources/persistenceContext.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/persistenceContext.xml b/core/persistence-jpa/src/main/resources/persistenceContext.xml
index ad2d837..4d12fa1 100644
--- a/core/persistence-jpa/src/main/resources/persistenceContext.xml
+++ b/core/persistence-jpa/src/main/resources/persistenceContext.xml
@@ -33,11 +33,11 @@ under the License.
<bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
- <bean id="viewsXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="viewsXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${content.directory}/views.xml"/>
<property name="fallback" value="classpath:views.xml"/>
</bean>
- <bean id="indexesXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="indexesXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${content.directory}/indexes.xml"/>
<property name="fallback" value="classpath:indexes.xml"/>
</bean>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
index bffe55f..f59ac32 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java
@@ -19,8 +19,8 @@
package org.apache.syncope.core.persistence.jpa;
import javax.persistence.EntityManager;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.junit.runner.RunWith;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
index 9366705..4b402bd 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java
@@ -30,8 +30,8 @@ import org.apache.commons.collections4.Transformer;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.CipherAlgorithm;
import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
-import org.apache.syncope.core.misc.security.SyncopeGrantedAuthority;
+import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
+import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority;
import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java
index 3cea9ab..b033ecb 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java
@@ -39,7 +39,7 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.spring.security.Encryptor;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
index fc8305b..6762b7f 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
@@ -30,7 +30,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
import org.apache.syncope.common.lib.types.PolicyType;
import org.apache.syncope.common.lib.policy.SyncPolicySpec;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
index 44b888b..810534b 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
@@ -33,8 +33,8 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.apache.syncope.core.misc.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.misc.security.PasswordGenerator;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
+import org.apache.syncope.core.spring.security.PasswordGenerator;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.junit.Test;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
index 33980a2..7c7df15 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
@@ -31,7 +31,7 @@ import java.util.List;
import javax.persistence.TypedQuery;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
index f9d284f..544a470 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
@@ -30,7 +30,7 @@ import javax.persistence.TypedQuery;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
[05/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DBPasswordSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DBPasswordSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DBPasswordSyncActions.java
new file mode 100644
index 0000000..84504ec
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DBPasswordSyncActions.java
@@ -0,0 +1,142 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+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.user.User;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * A SyncActions implementation which allows the ability to import passwords from a Database
+ * backend, where the passwords are hashed according to the password cipher algorithm property
+ * of the (DB) Connector and HEX-encoded.
+ */
+public class DBPasswordSyncActions extends DefaultSyncActions {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DBPasswordSyncActions.class);
+
+ private static final String CLEARTEXT = "CLEARTEXT";
+
+ @Autowired
+ private UserDAO userDAO;
+
+ private String encodedPassword;
+
+ private CipherAlgorithm cipher;
+
+ @Transactional(readOnly = true)
+ @Override
+ public <A extends AnyTO> SyncDelta beforeProvision(
+ final ProvisioningProfile<?, ?> profile,
+ final SyncDelta delta,
+ final A any) throws JobExecutionException {
+
+ if (any instanceof UserTO) {
+ String password = ((UserTO) any).getPassword();
+ parseEncodedPassword(password, profile.getConnector());
+ }
+
+ return delta;
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+ final ProvisioningProfile<?, ?> profile,
+ final SyncDelta delta,
+ final A any,
+ final M anyPatch) throws JobExecutionException {
+
+ if (anyPatch instanceof UserPatch) {
+ PasswordPatch modPassword = ((UserPatch) anyPatch).getPassword();
+ parseEncodedPassword(modPassword == null ? null : modPassword.getValue(), profile.getConnector());
+ }
+
+ return delta;
+ }
+
+ private void parseEncodedPassword(final String password, final Connector connector) {
+ if (password != null) {
+ ConnInstance connInstance = connector.getConnInstance();
+
+ String cipherAlgorithm = getCipherAlgorithm(connInstance);
+ if (!CLEARTEXT.equals(cipherAlgorithm)) {
+ try {
+ encodedPassword = password;
+ cipher = CipherAlgorithm.valueOf(cipherAlgorithm);
+ } catch (IllegalArgumentException e) {
+ LOG.error("Cipher algorithm not allowed: {}", cipherAlgorithm, e);
+ encodedPassword = null;
+ }
+ }
+ }
+ }
+
+ private String getCipherAlgorithm(final ConnInstance connInstance) {
+ ConnConfProperty cipherAlgorithm =
+ IterableUtils.find(connInstance.getConf(), new Predicate<ConnConfProperty>() {
+
+ @Override
+ public boolean evaluate(final ConnConfProperty property) {
+ return "cipherAlgorithm".equals(property.getSchema().getName())
+ && property.getValues() != null && !property.getValues().isEmpty();
+ }
+ });
+
+ return cipherAlgorithm == null
+ ? CLEARTEXT
+ : (String) cipherAlgorithm.getValues().get(0);
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public <A extends AnyTO> void after(
+ final ProvisioningProfile<?, ?> profile,
+ final SyncDelta delta,
+ final A any,
+ final ProvisioningReport result) throws JobExecutionException {
+
+ if (any instanceof UserTO && encodedPassword != null && cipher != null) {
+ User syncopeUser = userDAO.find(any.getKey());
+ if (syncopeUser != null) {
+ syncopeUser.setEncodedPassword(encodedPassword.toUpperCase(), cipher);
+ }
+ encodedPassword = null;
+ cipher = null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultPushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultPushActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultPushActions.java
new file mode 100644
index 0000000..49135f9
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultPushActions.java
@@ -0,0 +1,100 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.provisioning.api.syncpull.PushActions;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.quartz.JobExecutionException;
+
+/**
+ * Default (empty) implementation of PushActions.
+ */
+public abstract class DefaultPushActions implements PushActions {
+
+ @Override
+ public void beforeAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException {
+ }
+
+ @Override
+ public <A extends Any<?>> A beforeAssign(final ProvisioningProfile<?, ?> profile, final A any)
+ throws JobExecutionException {
+
+ return any;
+ }
+
+ @Override
+ public <A extends Any<?>> A beforeProvision(final ProvisioningProfile<?, ?> profile, final A any)
+ throws JobExecutionException {
+
+ return any;
+ }
+
+ @Override
+ public <A extends Any<?>> A beforeLink(final ProvisioningProfile<?, ?> profile, final A any)
+ throws JobExecutionException {
+
+ return any;
+ }
+
+ @Override
+ public <A extends Any<?>> A beforeUnassign(final ProvisioningProfile<?, ?> profile, final A any)
+ throws JobExecutionException {
+
+ return any;
+ }
+
+ @Override
+ public <A extends Any<?>> A beforeDeprovision(final ProvisioningProfile<?, ?> profile, final A any)
+ throws JobExecutionException {
+
+ return any;
+ }
+
+ @Override
+ public <A extends Any<?>> A beforeUnlink(final ProvisioningProfile<?, ?> profile, final A any)
+ throws JobExecutionException {
+
+ return any;
+ }
+
+ @Override
+ public <A extends Any<?>> void onError(
+ final ProvisioningProfile<?, ?> profile, final A any, final ProvisioningReport result,
+ final Exception error) throws JobExecutionException {
+
+ // do nothing
+ }
+
+ @Override
+ public <A extends Any<?>> void after(
+ final ProvisioningProfile<?, ?> profile, final A any, final ProvisioningReport result)
+ throws JobExecutionException {
+
+ // do nothing
+ }
+
+ @Override
+ public void afterAll(final ProvisioningProfile<?, ?> profile)
+ throws JobExecutionException {
+
+ // do nothing
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultReconciliationFilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultReconciliationFilterBuilder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultReconciliationFilterBuilder.java
new file mode 100644
index 0000000..f82b40c
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultReconciliationFilterBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import static org.identityconnectors.framework.impl.api.local.operations.FilteredResultsHandler.PassThroughFilter;
+
+import org.identityconnectors.framework.common.objects.filter.Filter;
+import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
+
+/**
+ * Default (pass-through) implementation of {@link ReconciliationFilterBuilder}.
+ */
+public abstract class DefaultReconciliationFilterBuilder implements ReconciliationFilterBuilder {
+
+ private static final PassThroughFilter PASS_THROUGH = new PassThroughFilter();
+
+ @Override
+ public Filter build() {
+ return PASS_THROUGH;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultSyncActions.java
new file mode 100644
index 0000000..159382c
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/DefaultSyncActions.java
@@ -0,0 +1,121 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncActions;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+
+/**
+ * Default (empty) implementation of {@link SyncActions}.
+ */
+public abstract class DefaultSyncActions implements SyncActions {
+
+ @Override
+ public void beforeAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException {
+ }
+
+ @Override
+ public <A extends AnyTO, P extends AnyPatch> SyncDelta beforeUpdate(
+ final ProvisioningProfile<?, ?> profile,
+ final SyncDelta delta,
+ final A any,
+ final P anyMod) throws JobExecutionException {
+
+ return delta;
+ }
+
+ @Override
+ public <A extends AnyTO> SyncDelta beforeDelete(
+ final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+ throws JobExecutionException {
+
+ return delta;
+ }
+
+ @Override
+ public <A extends AnyTO> SyncDelta beforeAssign(
+ final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+ throws JobExecutionException {
+
+ return delta;
+ }
+
+ @Override
+ public <A extends AnyTO> SyncDelta beforeProvision(
+ final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+ throws JobExecutionException {
+
+ return delta;
+ }
+
+ @Override
+ public <A extends AnyTO> SyncDelta beforeLink(
+ final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+ throws JobExecutionException {
+
+ return delta;
+ }
+
+ @Override
+ public <A extends AnyTO> SyncDelta beforeUnassign(
+ final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+ throws JobExecutionException {
+
+ return delta;
+ }
+
+ @Override
+ public <A extends AnyTO> SyncDelta beforeDeprovision(
+ final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+ throws JobExecutionException {
+
+ return delta;
+ }
+
+ @Override
+ public <A extends AnyTO> SyncDelta beforeUnlink(
+ final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
+ throws JobExecutionException {
+
+ return delta;
+ }
+
+ @Override
+ public void onError(
+ final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final ProvisioningReport result,
+ final Exception error) throws JobExecutionException {
+ }
+
+ @Override
+ public <A extends AnyTO> void after(
+ final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any,
+ final ProvisioningReport result)
+ throws JobExecutionException {
+ }
+
+ @Override
+ public void afterAll(final ProvisioningProfile<?, ?> profile)
+ throws JobExecutionException {
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupPushResultHandlerImpl.java
new file mode 100644
index 0000000..0455b08
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupPushResultHandlerImpl.java
@@ -0,0 +1,70 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import org.apache.syncope.common.lib.patch.GroupPatch;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.syncpull.GroupPushResultHandler;
+
+public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implements GroupPushResultHandler {
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
+ }
+
+ @Override
+ protected String getName(final Any<?> any) {
+ return Group.class.cast(any).getName();
+ }
+
+ @Override
+ protected Any<?> getAny(final long key) {
+ try {
+ return groupDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving group {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final long key) {
+ return groupDataBinder.getGroupTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final long key) {
+ GroupPatch patch = new GroupPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<Long> update(final AnyPatch patch) {
+ return gwfAdapter.update((GroupPatch) patch);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupSyncResultHandlerImpl.java
new file mode 100644
index 0000000..8b73e42
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/GroupSyncResultHandlerImpl.java
@@ -0,0 +1,138 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.AttrPatch;
+import org.apache.syncope.common.lib.patch.GroupPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.syncpull.GroupSyncResultHandler;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+
+public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implements GroupSyncResultHandler {
+
+ protected final Map<Long, String> groupOwnerMap = new HashMap<>();
+
+ @Override
+ public Map<Long, String> getGroupOwnerMap() {
+ return this.groupOwnerMap;
+ }
+
+ @Override
+ protected AnyUtils getAnyUtils() {
+ return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
+ }
+
+ @Override
+ protected String getName(final AnyTO anyTO) {
+ return GroupTO.class.cast(anyTO).getName();
+ }
+
+ @Override
+ protected ProvisioningManager<?, ?> getProvisioningManager() {
+ return groupProvisioningManager;
+ }
+
+ @Override
+ protected Any<?> getAny(final long key) {
+ try {
+ return groupDAO.authFind(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving group {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AnyTO getAnyTO(final long key) {
+ return groupDataBinder.getGroupTO(key);
+ }
+
+ @Override
+ protected AnyPatch newPatch(final long key) {
+ GroupPatch patch = new GroupPatch();
+ patch.setKey(key);
+ return patch;
+ }
+
+ @Override
+ protected WorkflowResult<Long> update(final AnyPatch patch) {
+ return gwfAdapter.update((GroupPatch) patch);
+ }
+
+ @Override
+ protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningReport result) {
+ GroupTO groupTO = GroupTO.class.cast(anyTO);
+
+ Map.Entry<Long, List<PropagationStatus>> created = groupProvisioningManager.create(
+ groupTO,
+ groupOwnerMap,
+ Collections.singleton(profile.getTask().getResource().getKey()),
+ true);
+
+ result.setKey(created.getKey());
+ result.setName(getName(anyTO));
+
+ return getAnyTO(created.getKey());
+ }
+
+ @Override
+ protected AnyTO doUpdate(
+ final AnyTO before,
+ final AnyPatch anyPatch,
+ final SyncDelta delta,
+ final ProvisioningReport result) {
+
+ GroupPatch groupPatch = GroupPatch.class.cast(anyPatch);
+
+ Map.Entry<Long, List<PropagationStatus>> updated = groupProvisioningManager.update(groupPatch, true);
+
+ String groupOwner = null;
+ for (AttrPatch attrPatch : groupPatch.getPlainAttrs()) {
+ if (attrPatch.getOperation() == PatchOperation.ADD_REPLACE && attrPatch.getAttrTO() != null
+ && attrPatch.getAttrTO().getSchema().isEmpty() && !attrPatch.getAttrTO().getValues().isEmpty()) {
+
+ groupOwner = attrPatch.getAttrTO().getValues().get(0);
+ }
+ }
+ if (groupOwner != null) {
+ groupOwnerMap.put(updated.getKey(), groupOwner);
+ }
+
+ GroupTO after = groupDataBinder.getGroupTO(updated.getKey());
+
+ result.setName(getName(after));
+
+ return after;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPMembershipSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPMembershipSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPMembershipSyncActions.java
new file mode 100644
index 0000000..464c56b
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPMembershipSyncActions.java
@@ -0,0 +1,335 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.MembershipPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.apache.syncope.core.provisioning.api.AuditManager;
+import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
+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.OperationOptionsBuilder;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * Simple action for synchronizing LDAP groups memberships to Syncope group memberships, when the same resource is
+ * configured for both users and groups.
+ *
+ * @see org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions
+ */
+public class LDAPMembershipSyncActions extends DefaultSyncActions {
+
+ protected static final Logger LOG = LoggerFactory.getLogger(LDAPMembershipSyncActions.class);
+
+ @Autowired
+ protected AnyTypeDAO anyTypeDAO;
+
+ @Autowired
+ protected UserDAO userDAO;
+
+ @Autowired
+ protected GroupDAO groupDAO;
+
+ @Autowired
+ protected UserWorkflowAdapter uwfAdapter;
+
+ @Autowired
+ protected PropagationManager propagationManager;
+
+ @Autowired
+ private PropagationTaskExecutor taskExecutor;
+
+ @Autowired
+ private NotificationManager notificationManager;
+
+ @Autowired
+ private AuditManager auditManager;
+
+ @Autowired
+ private SyncUtils syncUtils;
+
+ protected Map<Long, Long> membersBeforeGroupUpdate = Collections.<Long, Long>emptyMap();
+
+ /**
+ * Allows easy subclassing for the ConnId AD connector bundle.
+ *
+ * @param connector A Connector instance to query for the groupMemberAttribute property name
+ * @return the name of the attribute used to keep track of group memberships
+ */
+ protected String getGroupMembershipAttrName(final Connector connector) {
+ ConnConfProperty groupMembership = IterableUtils.find(connector.getConnInstance().getConf(),
+ new Predicate<ConnConfProperty>() {
+
+ @Override
+ public boolean evaluate(final ConnConfProperty property) {
+ return "groupMemberAttribute".equals(property.getSchema().getName())
+ && property.getValues() != null && !property.getValues().isEmpty();
+ }
+ });
+
+ return groupMembership == null
+ ? "uniquemember"
+ : (String) groupMembership.getValues().get(0);
+ }
+
+ /**
+ * Keep track of members of the group being updated <b>before</b> actual update takes place. This is not needed on
+ * <ul> <li>beforeProvision() - because the synchronizing group does not exist yet on Syncope</li>
+ * <li>beforeDelete() - because group delete cascades as membership removal for all users involved</li> </ul>
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+ final ProvisioningProfile<?, ?> profile,
+ final SyncDelta delta, final A any, final M anyPatch) throws JobExecutionException {
+
+ if (any instanceof GroupTO) {
+ // search for all users assigned to given group
+ Group group = groupDAO.find(any.getKey());
+ if (group != null) {
+ List<UMembership> membs = groupDAO.findUMemberships(group);
+ // save memberships before group update takes place
+ membersBeforeGroupUpdate = new HashMap<>(membs.size());
+ for (UMembership memb : membs) {
+ membersBeforeGroupUpdate.put(memb.getLeftEnd().getKey(), memb.getKey());
+ }
+ }
+ }
+
+ return super.beforeUpdate(profile, delta, any, anyPatch);
+ }
+
+ /**
+ * Build UserPatch for adding membership to given user, for given group.
+ *
+ * @param userKey user to be assigned membership to given group
+ * @param groupTO group for adding membership
+ * @return UserPatch for user update
+ */
+ protected UserPatch getUserPatch(final Long userKey, final GroupTO groupTO) {
+ UserPatch userPatch = new UserPatch();
+ // no actual modification takes place when user has already the group assigned
+ if (membersBeforeGroupUpdate.containsKey(userKey)) {
+ membersBeforeGroupUpdate.remove(userKey);
+ } else {
+ userPatch.setKey(userKey);
+
+ userPatch.getMemberships().add(
+ new MembershipPatch.Builder().
+ operation(PatchOperation.ADD_REPLACE).
+ membershipTO(new MembershipTO.Builder().group(groupTO.getKey(), null).build()).
+ build());
+ }
+
+ return userPatch;
+ }
+
+ /**
+ * Read values of attribute returned by getGroupMembershipAttrName(); if not present in the given delta, perform an
+ * additional read on the underlying connector.
+ *
+ * @param delta representing the synchronizing group
+ * @param connector associated to the current resource
+ * @return value of attribute returned by
+ * {@link #getGroupMembershipAttrName}
+ */
+ protected List<Object> getMembAttrValues(final SyncDelta delta, final Connector connector) {
+ List<Object> result = Collections.<Object>emptyList();
+ String groupMemberName = getGroupMembershipAttrName(connector);
+
+ // first, try to read the configured attribute from delta, returned by the ongoing synchronization
+ Attribute membAttr = delta.getObject().getAttributeByName(groupMemberName);
+ // if not found, perform an additional read on the underlying connector for the same connector object
+ if (membAttr == null) {
+ OperationOptionsBuilder oob = new OperationOptionsBuilder();
+ oob.setAttributesToGet(groupMemberName);
+ ConnectorObject remoteObj = connector.getObject(ObjectClass.GROUP, delta.getUid(), oob.build());
+ if (remoteObj == null) {
+ LOG.debug("Object for '{}' not found", delta.getUid().getUidValue());
+ } else {
+ membAttr = remoteObj.getAttributeByName(groupMemberName);
+ }
+ }
+ if (membAttr != null && membAttr.getValue() != null) {
+ result = membAttr.getValue();
+ }
+
+ return result;
+ }
+
+ /**
+ * Perform actual modifications (i.e. membership add / remove) for the given group on the given resource.
+ *
+ * @param userPatch modifications to perform on the user
+ * @param resourceName resource to be propagated for changes
+ */
+ protected void userUpdate(final UserPatch userPatch, final String resourceName) {
+ if (userPatch.getKey() == 0) {
+ return;
+ }
+
+ Result result;
+
+ WorkflowResult<Pair<UserPatch, Boolean>> updated = null;
+
+ try {
+ updated = uwfAdapter.update(userPatch);
+
+ List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
+ updated, false, Collections.singleton(resourceName));
+
+ taskExecutor.execute(tasks);
+ result = Result.SUCCESS;
+ } catch (PropagationException e) {
+ result = Result.FAILURE;
+ LOG.error("Could not propagate {}", userPatch, e);
+ } catch (Exception e) {
+ result = Result.FAILURE;
+ LOG.error("Could not perform update {}", userPatch, e);
+ }
+
+ notificationManager.createTasks(
+ AuditElements.EventCategoryType.SYNCHRONIZATION,
+ this.getClass().getSimpleName(),
+ null,
+ "update",
+ result,
+ null, // searching for before object is too much expensive ...
+ updated == null ? null : updated.getResult().getKey(),
+ userPatch,
+ resourceName);
+
+ auditManager.audit(
+ AuditElements.EventCategoryType.SYNCHRONIZATION,
+ this.getClass().getSimpleName(),
+ null,
+ "update",
+ result,
+ null, // searching for before object is too much expensive ...
+ updated == null ? null : updated.getResult().getKey(),
+ userPatch,
+ resourceName);
+ }
+
+ /**
+ * Synchronize Syncope memberships with the situation read on the external resource's group.
+ *
+ * @param profile sync profile
+ * @param delta representing the synchronizing group
+ * @param groupTO group after modification performed by the handler
+ * @throws JobExecutionException if anything goes wrong
+ */
+ protected void synchronizeMemberships(
+ final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final GroupTO groupTO)
+ throws JobExecutionException {
+
+ ProvisioningTask task = profile.getTask();
+ ExternalResource resource = task.getResource();
+ Connector connector = profile.getConnector();
+
+ for (Object membValue : getMembAttrValues(delta, connector)) {
+ Long userKey = syncUtils.findMatchingAnyKey(
+ anyTypeDAO.findUser(),
+ membValue.toString(),
+ profile.getTask().getResource(),
+ profile.getConnector());
+ if (userKey != null) {
+ UserPatch userPatch = getUserPatch(userKey, groupTO);
+ userUpdate(userPatch, resource.getKey());
+ }
+ }
+
+ // finally remove any residual membership that was present before group update but not any more
+ for (Map.Entry<Long, Long> member : membersBeforeGroupUpdate.entrySet()) {
+ UserPatch userPatch = new UserPatch();
+ userPatch.setKey(member.getKey());
+
+ userPatch.getMemberships().add(
+ new MembershipPatch.Builder().
+ operation(PatchOperation.DELETE).
+ membershipTO(new MembershipTO.Builder().group(groupTO.getKey(), null).build()).
+ build());
+
+ userUpdate(userPatch, resource.getKey());
+ }
+ }
+
+ /**
+ * Synchronize membership at group synchronization time (because SyncJob first synchronize users then groups).
+ * {@inheritDoc}
+ */
+ @Override
+ public <A extends AnyTO> void after(
+ final ProvisioningProfile<?, ?> profile,
+ final SyncDelta delta,
+ final A any,
+ final ProvisioningReport result) throws JobExecutionException {
+
+ if (!(profile.getTask() instanceof SyncTask)) {
+ return;
+ }
+
+ if (!(any instanceof GroupTO)
+ || profile.getTask().getResource().getProvision(anyTypeDAO.findUser()) == null
+ || profile.getTask().getResource().getProvision(anyTypeDAO.findUser()).getMapping() == null) {
+
+ super.after(profile, delta, any, result);
+ } else {
+ synchronizeMemberships(profile, delta, (GroupTO) any);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPPasswordSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPPasswordSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPPasswordSyncActions.java
new file mode 100644
index 0000000..134c1f1
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/LDAPPasswordSyncActions.java
@@ -0,0 +1,124 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import org.apache.syncope.common.lib.patch.AnyPatch;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.UserTO;
+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.user.User;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.codec.Base64;
+import org.springframework.security.crypto.codec.Hex;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * A SyncActions implementation which allows the ability to import passwords from an LDAP backend
+ * that are hashed.
+ */
+public class LDAPPasswordSyncActions extends DefaultSyncActions {
+
+ protected static final Logger LOG = LoggerFactory.getLogger(LDAPPasswordSyncActions.class);
+
+ @Autowired
+ private UserDAO userDAO;
+
+ private String encodedPassword;
+
+ private CipherAlgorithm cipher;
+
+ @Transactional(readOnly = true)
+ @Override
+ public <A extends AnyTO> SyncDelta beforeProvision(
+ final ProvisioningProfile<?, ?> profile,
+ final SyncDelta delta,
+ final A any) throws JobExecutionException {
+
+ if (any instanceof UserTO) {
+ String password = ((UserTO) any).getPassword();
+ parseEncodedPassword(password);
+ }
+
+ return delta;
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
+ final ProvisioningProfile<?, ?> profile,
+ final SyncDelta delta,
+ final A any,
+ final M anyPatch) throws JobExecutionException {
+
+ if (anyPatch instanceof UserPatch) {
+ PasswordPatch modPassword = ((UserPatch) anyPatch).getPassword();
+ parseEncodedPassword(modPassword == null ? null : modPassword.getValue());
+ }
+
+ return delta;
+ }
+
+ private void parseEncodedPassword(final String password) {
+ if (password != null && password.startsWith("{")) {
+ int closingBracketIndex = password.indexOf('}');
+ String digest = password.substring(1, password.indexOf('}'));
+ if (digest != null) {
+ digest = digest.toUpperCase();
+ }
+ try {
+ encodedPassword = password.substring(closingBracketIndex + 1);
+ cipher = CipherAlgorithm.valueOf(digest);
+ } catch (IllegalArgumentException e) {
+ LOG.error("Cipher algorithm not allowed: {}", digest, e);
+ encodedPassword = null;
+ }
+ }
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public <A extends AnyTO> void after(
+ final ProvisioningProfile<?, ?> profile,
+ final SyncDelta delta,
+ final A any,
+ final ProvisioningReport result) throws JobExecutionException {
+
+ if (any instanceof UserTO && encodedPassword != null && cipher != null) {
+ User syncopeUser = userDAO.find(any.getKey());
+ if (syncopeUser != null) {
+ byte[] encodedPasswordBytes = Base64.decode(encodedPassword.getBytes());
+ char[] encodedHex = Hex.encode(encodedPasswordBytes);
+ String encodedHexStr = new String(encodedHex).toUpperCase();
+
+ syncopeUser.setEncodedPassword(encodedHexStr, cipher);
+ }
+ encodedPassword = null;
+ cipher = null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PlainAttrsSyncCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PlainAttrsSyncCorrelationRule.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PlainAttrsSyncCorrelationRule.java
new file mode 100644
index 0000000..343ba3f
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PlainAttrsSyncCorrelationRule.java
@@ -0,0 +1,115 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncCorrelationRule;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+
+public class PlainAttrsSyncCorrelationRule implements SyncCorrelationRule {
+
+ private final List<String> plainSchemaNames;
+
+ private final Provision provision;
+
+ public PlainAttrsSyncCorrelationRule(final String[] plainSchemaNames, final Provision provision) {
+ this.plainSchemaNames = Arrays.asList(plainSchemaNames);
+ this.provision = provision;
+ }
+
+ @Override
+ public SearchCond getSearchCond(final ConnectorObject connObj) {
+ Map<String, MappingItem> mappingItems = new HashMap<>();
+ for (MappingItem item : MappingManagerImpl.getSyncMappingItems(provision)) {
+ mappingItems.put(item.getIntAttrName(), item);
+ }
+
+ // search for anys by attribute(s) specified in the policy
+ SearchCond searchCond = null;
+
+ for (String schema : plainSchemaNames) {
+ Attribute attr = mappingItems.get(schema) == null
+ ? null
+ : connObj.getAttributeByName(mappingItems.get(schema).getExtAttrName());
+ if (attr == null) {
+ throw new IllegalArgumentException(
+ "Connector object does not contains the attributes to perform the search: " + schema);
+ }
+
+ List<Object> values = attr.getValue();
+ for (MappingItemTransformer transformer
+ : MappingManagerImpl.getMappingItemTransformers(mappingItems.get(schema))) {
+
+ values = transformer.beforeSync(values);
+ }
+
+ AttributeCond.Type type;
+ String expression = null;
+
+ if (values == null || values.isEmpty() || (values.size() == 1 && values.get(0) == null)) {
+ type = AttributeCond.Type.ISNULL;
+ } else {
+ type = AttributeCond.Type.EQ;
+ expression = values.size() > 1
+ ? values.toString()
+ : values.get(0).toString();
+ }
+
+ SearchCond nodeCond;
+ // users: just key or username can be selected
+ // groups: just key or name can be selected
+ // any objects: just key can be selected
+ if ("key".equalsIgnoreCase(schema)
+ || "username".equalsIgnoreCase(schema) || "name".equalsIgnoreCase(schema)) {
+
+ AnyCond cond = new AnyCond();
+ cond.setSchema(schema);
+ cond.setType(type);
+ cond.setExpression(expression);
+
+ nodeCond = SearchCond.getLeafCond(cond);
+ } else {
+ AttributeCond cond = new AttributeCond();
+ cond.setSchema(schema);
+ cond.setType(type);
+ cond.setExpression(expression);
+
+ nodeCond = SearchCond.getLeafCond(cond);
+ }
+
+ searchCond = searchCond == null
+ ? nodeCond
+ : SearchCond.getAndCond(searchCond, nodeCond);
+ }
+
+ return searchCond;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PushJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PushJobDelegate.java
new file mode 100644
index 0000000..4d44086
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/PushJobDelegate.java
@@ -0,0 +1,206 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.syncpull.AnyObjectPushResultHandler;
+import org.apache.syncope.core.provisioning.api.syncpull.GroupPushResultHandler;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.syncpull.PushActions;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncopePushResultHandler;
+import org.apache.syncope.core.provisioning.api.syncpull.UserPushResultHandler;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+
+public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
+
+ private static final int PAGE_SIZE = 1000;
+
+ /**
+ * User DAO.
+ */
+ @Autowired
+ private UserDAO userDAO;
+
+ /**
+ * Search DAO.
+ */
+ @Autowired
+ private AnySearchDAO searchDAO;
+
+ /**
+ * Group DAO.
+ */
+ @Autowired
+ private GroupDAO groupDAO;
+
+ @Autowired
+ private AnyObjectDAO anyObjectDAO;
+
+ private AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
+ AnyDAO<?> result;
+ switch (anyTypeKind) {
+ case USER:
+ result = userDAO;
+ break;
+
+ case GROUP:
+ result = groupDAO;
+ break;
+
+ case ANY_OBJECT:
+ default:
+ result = anyObjectDAO;
+ }
+
+ return result;
+ }
+
+ protected void handle(
+ final List<? extends Any<?>> anys,
+ final SyncopePushResultHandler handler,
+ final ExternalResource resource)
+ throws JobExecutionException {
+
+ for (Any<?> any : anys) {
+ try {
+ handler.handle(any.getKey());
+ } catch (Exception e) {
+ LOG.warn("Failure pushing '{}' on '{}'", any, resource, e);
+ throw new JobExecutionException("While pushing " + any + " on " + resource, e);
+ }
+ }
+ }
+
+ @Override
+ protected String doExecuteProvisioning(
+ final PushTask pushTask,
+ final Connector connector,
+ final boolean dryRun) throws JobExecutionException {
+
+ LOG.debug("Executing push on {}", pushTask.getResource());
+
+ List<PushActions> actions = new ArrayList<>();
+ for (String className : pushTask.getActionsClassNames()) {
+ try {
+ Class<?> actionsClass = Class.forName(className);
+
+ PushActions syncActions = (PushActions) ApplicationContextProvider.getBeanFactory().
+ createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
+ actions.add(syncActions);
+ } catch (Exception e) {
+ LOG.info("Class '{}' not found", className, e);
+ }
+ }
+
+ ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
+ profile.setDryRun(dryRun);
+ profile.setResAct(null);
+
+ AnyObjectPushResultHandler ahandler =
+ (AnyObjectPushResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(AnyObjectPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ ahandler.setProfile(profile);
+
+ UserPushResultHandler uhandler =
+ (UserPushResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ uhandler.setProfile(profile);
+
+ GroupPushResultHandler ghandler =
+ (GroupPushResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ ghandler.setProfile(profile);
+
+ if (!profile.isDryRun()) {
+ for (PushActions action : actions) {
+ action.beforeAll(profile);
+ }
+ }
+
+ for (Provision provision : pushTask.getResource().getProvisions()) {
+ if (provision.getMapping() != null) {
+ AnyDAO<?> anyDAO = getAnyDAO(provision.getAnyType().getKind());
+
+ SyncopePushResultHandler handler;
+ switch (provision.getAnyType().getKind()) {
+ case USER:
+ handler = uhandler;
+ break;
+
+ case GROUP:
+ handler = ghandler;
+ break;
+
+ case ANY_OBJECT:
+ default:
+ handler = ahandler;
+ }
+
+ String filter = pushTask.getFilter(provision.getAnyType()) == null
+ ? null
+ : pushTask.getFilter(provision.getAnyType()).getFIQLCond();
+ if (StringUtils.isBlank(filter)) {
+ handle(anyDAO.findAll(), handler, pushTask.getResource());
+ } else {
+ int count = anyDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
+ for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
+ List<? extends Any<?>> anys = searchDAO.search(
+ SyncopeConstants.FULL_ADMIN_REALMS,
+ SearchCondConverter.convert(filter),
+ page,
+ PAGE_SIZE,
+ Collections.<OrderByClause>emptyList(),
+ provision.getAnyType().getKind());
+ handle(anys, handler, pushTask.getResource());
+ }
+ }
+ }
+ }
+
+ if (!profile.isDryRun()) {
+ for (PushActions action : actions) {
+ action.afterAll(profile);
+ }
+ }
+
+ String result = createReport(profile.getResults(), pushTask.getResource().getSyncTraceLevel(), dryRun);
+ LOG.debug("Sync result: {}", result);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncJobDelegate.java
new file mode 100644
index 0000000..78f253a
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncJobDelegate.java
@@ -0,0 +1,248 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.collections4.IteratorUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.policy.SyncPolicySpec;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.syncpull.AnyObjectSyncResultHandler;
+import org.apache.syncope.core.provisioning.api.syncpull.GroupSyncResultHandler;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncActions;
+import org.apache.syncope.core.provisioning.api.syncpull.UserSyncResultHandler;
+import org.identityconnectors.framework.common.objects.SyncResultsHandler;
+import org.identityconnectors.framework.common.objects.SyncToken;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
+
+public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> {
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Autowired
+ private GroupDAO groupDAO;
+
+ @Autowired
+ private VirSchemaDAO virSchemaDAO;
+
+ @Autowired
+ protected SyncUtils syncUtils;
+
+ protected void setGroupOwners(final GroupSyncResultHandler ghandler) {
+ for (Map.Entry<Long, String> entry : ghandler.getGroupOwnerMap().entrySet()) {
+ Group group = groupDAO.find(entry.getKey());
+ if (group == null) {
+ throw new NotFoundException("Group " + entry.getKey());
+ }
+
+ if (StringUtils.isBlank(entry.getValue())) {
+ group.setGroupOwner(null);
+ group.setUserOwner(null);
+ } else {
+ Long userKey = syncUtils.findMatchingAnyKey(
+ anyTypeDAO.findUser(),
+ entry.getValue(),
+ ghandler.getProfile().getTask().getResource(),
+ ghandler.getProfile().getConnector());
+
+ if (userKey == null) {
+ Long groupKey = syncUtils.findMatchingAnyKey(
+ anyTypeDAO.findGroup(),
+ entry.getValue(),
+ ghandler.getProfile().getTask().getResource(),
+ ghandler.getProfile().getConnector());
+
+ if (groupKey != null) {
+ group.setGroupOwner(groupDAO.find(groupKey));
+ }
+ } else {
+ group.setUserOwner(userDAO.find(userKey));
+ }
+ }
+
+ groupDAO.save(group);
+ }
+ }
+
+ @Override
+ protected String doExecuteProvisioning(
+ final SyncTask syncTask,
+ final Connector connector,
+ final boolean dryRun) throws JobExecutionException {
+
+ LOG.debug("Executing sync on {}", syncTask.getResource());
+
+ List<SyncActions> actions = new ArrayList<>();
+ for (String className : syncTask.getActionsClassNames()) {
+ try {
+ Class<?> actionsClass = Class.forName(className);
+ SyncActions syncActions = (SyncActions) ApplicationContextProvider.getBeanFactory().
+ createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
+
+ actions.add(syncActions);
+ } catch (Exception e) {
+ LOG.warn("Class '{}' not found", className, e);
+ }
+ }
+
+ ProvisioningProfile<SyncTask, SyncActions> profile = new ProvisioningProfile<>(connector, syncTask);
+ profile.getActions().addAll(actions);
+ profile.setDryRun(dryRun);
+ profile.setResAct(getSyncPolicySpec(syncTask).getConflictResolutionAction());
+
+ // Prepare handler for SyncDelta objects (any objects)
+ AnyObjectSyncResultHandler ahandler = (AnyObjectSyncResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(AnyObjectSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ ahandler.setProfile(profile);
+
+ // Prepare handler for SyncDelta objects (users)
+ UserSyncResultHandler uhandler = (UserSyncResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(UserSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ uhandler.setProfile(profile);
+
+ // Prepare handler for SyncDelta objects (groups)
+ GroupSyncResultHandler ghandler = (GroupSyncResultHandler) ApplicationContextProvider.getBeanFactory().
+ createBean(GroupSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ ghandler.setProfile(profile);
+
+ if (!profile.isDryRun()) {
+ for (SyncActions action : actions) {
+ action.beforeAll(profile);
+ }
+ }
+
+ for (Provision provision : syncTask.getResource().getProvisions()) {
+ if (provision.getMapping() != null) {
+ SyncResultsHandler handler;
+ switch (provision.getAnyType().getKind()) {
+ case USER:
+ handler = uhandler;
+ break;
+
+ case GROUP:
+ handler = ghandler;
+ break;
+
+ case ANY_OBJECT:
+ default:
+ handler = ahandler;
+ }
+
+ try {
+ Set<MappingItem> linkinMappingItems = new HashSet<>();
+ for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) {
+ linkinMappingItems.add(virSchema.asLinkingMappingItem());
+ }
+ Iterator<MappingItem> mapItems = IteratorUtils.chainedIterator(
+ provision.getMapping().getItems().iterator(),
+ linkinMappingItems.iterator());
+
+ switch (syncTask.getSyncMode()) {
+ case INCREMENTAL:
+ SyncToken latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass());
+ connector.sync(provision.getObjectClass(),
+ provision.getSyncToken(),
+ handler,
+ MappingManagerImpl.buildOperationOptions(mapItems));
+ if (!dryRun) {
+ provision.setSyncToken(latestSyncToken);
+ resourceDAO.save(provision.getResource());
+ }
+ break;
+
+ case FILTERED_RECONCILIATION:
+ ReconciliationFilterBuilder filterBuilder =
+ (ReconciliationFilterBuilder) ApplicationContextProvider.getBeanFactory().
+ createBean(Class.forName(syncTask.getReconciliationFilterBuilderClassName()),
+ AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ connector.filteredReconciliation(provision.getObjectClass(),
+ filterBuilder,
+ handler,
+ MappingManagerImpl.buildOperationOptions(mapItems));
+ break;
+
+ case FULL_RECONCILIATION:
+ default:
+ connector.fullReconciliation(provision.getObjectClass(),
+ handler,
+ MappingManagerImpl.buildOperationOptions(mapItems));
+ break;
+ }
+ } catch (Throwable t) {
+ throw new JobExecutionException("While syncing from connector", t);
+ }
+ }
+ }
+
+ try {
+ setGroupOwners(ghandler);
+ } catch (Exception e) {
+ LOG.error("While setting group owners", e);
+ }
+
+ if (!profile.isDryRun()) {
+ for (SyncActions action : actions) {
+ action.afterAll(profile);
+ }
+ }
+
+ String result = createReport(profile.getResults(), syncTask.getResource().getSyncTraceLevel(), dryRun);
+
+ LOG.debug("Sync result: {}", result);
+
+ return result;
+ }
+
+ private SyncPolicySpec getSyncPolicySpec(final ProvisioningTask task) {
+ SyncPolicySpec syncPolicySpec;
+
+ if (task instanceof SyncTask) {
+ syncPolicySpec = task.getResource().getSyncPolicy() == null
+ ? null
+ : task.getResource().getSyncPolicy().getSpecification();
+ } else {
+ syncPolicySpec = null;
+ }
+
+ // step required because the call <policy>.getSpecification() could return a null value
+ return syncPolicySpec == null ? new SyncPolicySpec() : syncPolicySpec;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncUtils.java
new file mode 100644
index 0000000..9038b42
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/syncpull/SyncUtils.java
@@ -0,0 +1,317 @@
+/*
+ * 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.core.provisioning.java.syncpull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.policy.SyncPolicySpec;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.Connector;
+import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncCorrelationRule;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeUtil;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.Name;
+import org.identityconnectors.framework.common.objects.OperationalAttributes;
+import org.identityconnectors.framework.common.objects.ResultsHandler;
+import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional(readOnly = true)
+@Component
+public class SyncUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SyncUtils.class);
+
+ /**
+ * Schema DAO.
+ */
+ @Autowired
+ private PlainSchemaDAO plainSchemaDAO;
+
+ /**
+ * Any Object DAO.
+ */
+ @Autowired
+ private AnyObjectDAO anyObjectDAO;
+
+ /**
+ * User DAO.
+ */
+ @Autowired
+ private UserDAO userDAO;
+
+ /**
+ * Group DAO.
+ */
+ @Autowired
+ private GroupDAO groupDAO;
+
+ /**
+ * Search DAO.
+ */
+ @Autowired
+ private AnySearchDAO searchDAO;
+
+ @Autowired
+ private AnyUtilsFactory anyUtilsFactory;
+
+ public Long findMatchingAnyKey(
+ final AnyType anyType,
+ final String name,
+ final ExternalResource resource,
+ final Connector connector) {
+
+ Provision provision = resource.getProvision(anyType);
+ if (provision == null) {
+ return null;
+ }
+
+ Long result = null;
+
+ AnyUtils anyUtils = anyUtilsFactory.getInstance(anyType.getKind());
+
+ final List<ConnectorObject> found = new ArrayList<>();
+ connector.search(provision.getObjectClass(),
+ new EqualsFilter(new Name(name)),
+ new ResultsHandler() {
+
+ @Override
+ public boolean handle(final ConnectorObject obj) {
+ return found.add(obj);
+ }
+ },
+ MappingManagerImpl.buildOperationOptions(MappingManagerImpl.getSyncMappingItems(provision).iterator()));
+
+ if (found.isEmpty()) {
+ LOG.debug("No {} found on {} with __NAME__ {}", provision.getObjectClass(), resource, name);
+ } else {
+ if (found.size() > 1) {
+ LOG.warn("More than one {} found on {} with __NAME__ {} - taking first only",
+ provision.getObjectClass(), resource, name);
+ }
+
+ ConnectorObject connObj = found.iterator().next();
+ try {
+ List<Long> anyKeys = findExisting(connObj.getUid().getUidValue(), connObj, provision, anyUtils);
+ if (anyKeys.isEmpty()) {
+ LOG.debug("No matching {} found for {}, aborting", anyUtils.getAnyTypeKind(), connObj);
+ } else {
+ if (anyKeys.size() > 1) {
+ LOG.warn("More than one {} found {} - taking first only", anyUtils.getAnyTypeKind(), anyKeys);
+ }
+
+ result = anyKeys.iterator().next();
+ }
+ } catch (IllegalArgumentException e) {
+ LOG.warn(e.getMessage());
+ }
+ }
+
+ return result;
+ }
+
+ private AnyDAO<?> getAnyDAO(final MappingItem connObjectKeyItem) {
+ return AnyTypeKind.USER == connObjectKeyItem.getIntMappingType().getAnyTypeKind()
+ ? userDAO
+ : AnyTypeKind.ANY_OBJECT == connObjectKeyItem.getIntMappingType().getAnyTypeKind()
+ ? anyObjectDAO
+ : groupDAO;
+ }
+
+ private List<Long> findByConnObjectKeyItem(
+ final String uid, final Provision provision, final AnyUtils anyUtils) {
+
+ List<Long> result = new ArrayList<>();
+
+ MappingItem connObjectKeyItem = MappingManagerImpl.getConnObjectKeyItem(provision);
+
+ String transfUid = uid;
+ for (MappingItemTransformer transformer : MappingManagerImpl.getMappingItemTransformers(connObjectKeyItem)) {
+ List<Object> output = transformer.beforeSync(Collections.<Object>singletonList(transfUid));
+ if (output != null && !output.isEmpty()) {
+ transfUid = output.get(0).toString();
+ }
+ }
+
+ switch (connObjectKeyItem.getIntMappingType()) {
+ case UserPlainSchema:
+ case GroupPlainSchema:
+ case AnyObjectPlainSchema:
+ PlainAttrValue value = anyUtils.newPlainAttrValue();
+
+ PlainSchema schema = plainSchemaDAO.find(connObjectKeyItem.getIntAttrName());
+ if (schema == null) {
+ value.setStringValue(transfUid);
+ } else {
+ try {
+ value.parseValue(schema, transfUid);
+ } catch (ParsingValidationException e) {
+ LOG.error("While parsing provided __UID__ {}", transfUid, e);
+ value.setStringValue(transfUid);
+ }
+ }
+
+ List<? extends Any<?>> anys =
+ getAnyDAO(connObjectKeyItem).findByAttrValue(connObjectKeyItem.getIntAttrName(), value);
+ for (Any<?> any : anys) {
+ result.add(any.getKey());
+ }
+ break;
+
+ case UserDerivedSchema:
+ case GroupDerivedSchema:
+ case AnyObjectDerivedSchema:
+ anys = getAnyDAO(connObjectKeyItem).findByDerAttrValue(connObjectKeyItem.getIntAttrName(), transfUid);
+ for (Any<?> any : anys) {
+ result.add(any.getKey());
+ }
+ break;
+
+ case UserKey:
+ case GroupKey:
+ case AnyObjectKey:
+ Any<?> any = getAnyDAO(connObjectKeyItem).find(Long.parseLong(transfUid));
+ if (any != null) {
+ result.add(any.getKey());
+ }
+ break;
+
+ case Username:
+ User user = userDAO.find(transfUid);
+ if (user != null) {
+ result.add(user.getKey());
+ }
+ break;
+
+ case GroupName:
+ Group group = groupDAO.find(transfUid);
+ if (group != null) {
+ result.add(group.getKey());
+ }
+ break;
+
+ default:
+ LOG.error("Invalid connObjectKey type '{}'", connObjectKeyItem.getIntMappingType());
+ }
+
+ return result;
+ }
+
+ private List<Long> findByCorrelationRule(
+ final ConnectorObject connObj, final SyncCorrelationRule rule, final AnyTypeKind type) {
+
+ List<Long> result = new ArrayList<>();
+ for (Any<?> any : searchDAO.search(rule.getSearchCond(connObj), type)) {
+ result.add(any.getKey());
+ }
+
+ return result;
+ }
+
+ private SyncCorrelationRule getCorrelationRule(final Provision provision, final SyncPolicySpec policySpec) {
+ SyncCorrelationRule result = null;
+
+ String syncCorrelationRule = policySpec.getCorrelationRules().get(provision.getAnyType().getKey());
+ if (StringUtils.isNotBlank(syncCorrelationRule)) {
+ if (syncCorrelationRule.charAt(0) == '[') {
+ result = new PlainAttrsSyncCorrelationRule(
+ POJOHelper.deserialize(syncCorrelationRule, String[].class), provision);
+ } else {
+ try {
+ result = (SyncCorrelationRule) Class.forName(syncCorrelationRule).newInstance();
+ } catch (Exception e) {
+ LOG.error("Failure instantiating correlation rule class '{}'", syncCorrelationRule, e);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Find any objects based on mapped uid value (or previous uid value, if updated).
+ *
+ * @param uid for finding by connObjectKey
+ * @param connObj for finding by attribute value
+ * @param provision external resource
+ * @param anyUtils any util
+ * @return list of matching users / groups
+ */
+ public List<Long> findExisting(
+ final String uid,
+ final ConnectorObject connObj,
+ final Provision provision,
+ final AnyUtils anyUtils) {
+
+ SyncPolicySpec syncPolicySpec = null;
+ if (provision.getResource().getSyncPolicy() != null) {
+ syncPolicySpec = provision.getResource().getSyncPolicy().getSpecification();
+ }
+
+ SyncCorrelationRule syncRule = null;
+ if (syncPolicySpec != null) {
+ syncRule = getCorrelationRule(provision, syncPolicySpec);
+ }
+
+ return syncRule == null
+ ? findByConnObjectKeyItem(uid, provision, anyUtils)
+ : findByCorrelationRule(connObj, syncRule, anyUtils.getAnyTypeKind());
+ }
+
+ public Boolean readEnabled(final ConnectorObject connectorObject, final ProvisioningTask task) {
+ Boolean enabled = null;
+ if (task.isSyncStatus()) {
+ Attribute status = AttributeUtil.find(OperationalAttributes.ENABLE_NAME, connectorObject.getAttributes());
+ if (status != null && status.getValue() != null && !status.getValue().isEmpty()) {
+ enabled = (Boolean) status.getValue().get(0);
+ }
+ }
+
+ return enabled;
+ }
+}
[15/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAccessDeniedHandler.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAccessDeniedHandler.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAccessDeniedHandler.java
deleted file mode 100644
index 8ab1d31..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAccessDeniedHandler.java
+++ /dev/null
@@ -1,43 +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.core.misc.security;
-
-import java.io.IOException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.web.access.AccessDeniedHandlerImpl;
-
-/**
- * Render Spring's {@link AccessDeniedException} as other Syncope errors.
- */
-public class SyncopeAccessDeniedHandler extends AccessDeniedHandlerImpl {
-
- @Override
- public void handle(final HttpServletRequest request, final HttpServletResponse response,
- final AccessDeniedException accessDeniedException) throws IOException, ServletException {
-
- response.addHeader(RESTHeaders.ERROR_INFO, accessDeniedException.getMessage());
-
- super.handle(request, response, accessDeniedException);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetails.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetails.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetails.java
deleted file mode 100644
index 68b27f4..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetails.java
+++ /dev/null
@@ -1,86 +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.core.misc.security;
-
-import java.io.Serializable;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-import org.apache.syncope.common.rest.api.RESTHeaders;
-
-public class SyncopeAuthenticationDetails implements Serializable {
-
- private static final long serialVersionUID = -5899959397393502897L;
-
- private final String remoteAddress;
-
- private final String sessionId;
-
- private String domain;
-
- public SyncopeAuthenticationDetails(final HttpServletRequest request) {
- this.remoteAddress = request.getRemoteAddr();
-
- HttpSession session = request.getSession(false);
- this.sessionId = session == null ? null : session.getId();
-
- this.domain = request.getHeader(RESTHeaders.DOMAIN);
- }
-
- public SyncopeAuthenticationDetails(final String domain) {
- this.remoteAddress = null;
- this.sessionId = null;
- this.domain = domain;
- }
-
- public String getRemoteAddress() {
- return remoteAddress;
- }
-
- public String getSessionId() {
- return sessionId;
- }
-
- public String getDomain() {
- return domain;
- }
-
- public void setDomain(final String domain) {
- this.domain = domain;
- }
-
- @Override
- public boolean equals(final Object obj) {
- return EqualsBuilder.reflectionEquals(this, obj);
- }
-
- @Override
- public int hashCode() {
- return HashCodeBuilder.reflectionHashCode(this);
- }
-
- @Override
- public String toString() {
- return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetailsSource.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetailsSource.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetailsSource.java
deleted file mode 100644
index b943edf..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationDetailsSource.java
+++ /dev/null
@@ -1,32 +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.core.misc.security;
-
-import javax.servlet.http.HttpServletRequest;
-import org.springframework.security.authentication.AuthenticationDetailsSource;
-
-public class SyncopeAuthenticationDetailsSource
- implements AuthenticationDetailsSource<HttpServletRequest, SyncopeAuthenticationDetails> {
-
- @Override
- public SyncopeAuthenticationDetails buildDetails(final HttpServletRequest context) {
- return new SyncopeAuthenticationDetails(context);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationEntryPoint.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationEntryPoint.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationEntryPoint.java
deleted file mode 100644
index 6213264..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationEntryPoint.java
+++ /dev/null
@@ -1,43 +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.core.misc.security;
-
-import java.io.IOException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.syncope.common.rest.api.RESTHeaders;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
-
-/**
- * Render Spring's {@link AuthenticationException} as other Syncope errors.
- */
-public class SyncopeAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
-
- @Override
- public void commence(final HttpServletRequest request, final HttpServletResponse response,
- final AuthenticationException authException) throws IOException, ServletException {
-
- response.addHeader(RESTHeaders.ERROR_INFO, authException.getMessage());
-
- super.commence(request, response, authException);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
deleted file mode 100644
index 313b0f1..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeAuthenticationProvider.java
+++ /dev/null
@@ -1,210 +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.core.misc.security;
-
-import javax.annotation.Resource;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.core.misc.security.AuthContextUtils.Executable;
-import org.apache.syncope.core.persistence.api.entity.Domain;
-import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Configurable;
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.userdetails.UserDetailsService;
-
-@Configurable
-public class SyncopeAuthenticationProvider implements AuthenticationProvider {
-
- protected static final Logger LOG = LoggerFactory.getLogger(SyncopeAuthenticationProvider.class);
-
- @Autowired
- protected AuthDataAccessor dataAccessor;
-
- @Autowired
- protected UserProvisioningManager provisioningManager;
-
- @Resource(name = "adminUser")
- protected String adminUser;
-
- @Resource(name = "anonymousUser")
- protected String anonymousUser;
-
- protected String adminPassword;
-
- protected String adminPasswordAlgorithm;
-
- protected String anonymousKey;
-
- protected UserDetailsService userDetailsService;
-
- protected final Encryptor encryptor = Encryptor.getInstance();
-
- /**
- * @param adminPassword the adminPassword to set
- */
- public void setAdminPassword(final String adminPassword) {
- this.adminPassword = adminPassword;
- }
-
- /**
- * @param adminPasswordAlgorithm the adminPasswordAlgorithm to set
- */
- public void setAdminPasswordAlgorithm(final String adminPasswordAlgorithm) {
- this.adminPasswordAlgorithm = adminPasswordAlgorithm;
- }
-
- /**
- * @param anonymousKey the anonymousKey to set
- */
- public void setAnonymousKey(final String anonymousKey) {
- this.anonymousKey = anonymousKey;
- }
-
- public void setUserDetailsService(final UserDetailsService syncopeUserDetailsService) {
- this.userDetailsService = syncopeUserDetailsService;
- }
-
- @Override
- public Authentication authenticate(final Authentication authentication) {
- String domainKey = SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).getDomain();
- if (StringUtils.isBlank(domainKey)) {
- domainKey = SyncopeConstants.MASTER_DOMAIN;
- }
- SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).setDomain(domainKey);
-
- Boolean authenticated;
- if (anonymousUser.equals(authentication.getName())) {
- authenticated = authentication.getCredentials().toString().equals(anonymousKey);
- } else if (adminUser.equals(authentication.getName())) {
- if (SyncopeConstants.MASTER_DOMAIN.equals(domainKey)) {
- authenticated = encryptor.verify(
- authentication.getCredentials().toString(),
- CipherAlgorithm.valueOf(adminPasswordAlgorithm),
- adminPassword);
- } else {
- final String domainToFind = domainKey;
- authenticated = AuthContextUtils.execWithAuthContext(
- SyncopeConstants.MASTER_DOMAIN, new Executable<Boolean>() {
-
- @Override
- public Boolean exec() {
- Domain domain = dataAccessor.findDomain(domainToFind);
-
- return encryptor.verify(
- authentication.getCredentials().toString(),
- domain.getAdminCipherAlgorithm(),
- domain.getAdminPwd());
- }
- });
- }
- } else {
- final Pair<Long, Boolean> authResult =
- AuthContextUtils.execWithAuthContext(domainKey, new Executable<Pair<Long, Boolean>>() {
-
- @Override
- public Pair<Long, Boolean> exec() {
- return dataAccessor.authenticate(authentication);
- }
- });
- authenticated = authResult.getValue();
- if (authenticated != null && !authenticated) {
- AuthContextUtils.execWithAuthContext(domainKey, new Executable<Void>() {
-
- @Override
- public Void exec() {
- provisioningManager.internalSuspend(authResult.getKey());
- return null;
- }
- });
- }
- }
-
- final boolean isAuthenticated = authenticated != null && authenticated;
- UsernamePasswordAuthenticationToken token;
- if (isAuthenticated) {
- token = AuthContextUtils.execWithAuthContext(
- domainKey, new Executable<UsernamePasswordAuthenticationToken>() {
-
- @Override
- public UsernamePasswordAuthenticationToken exec() {
- UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
- authentication.getPrincipal(),
- null,
- userDetailsService.loadUserByUsername(authentication.getPrincipal().toString()).
- getAuthorities());
- token.setDetails(authentication.getDetails());
-
- dataAccessor.audit(
- AuditElements.EventCategoryType.REST,
- AuditElements.AUTHENTICATION_CATEGORY,
- null,
- AuditElements.LOGIN_EVENT,
- Result.SUCCESS,
- null,
- isAuthenticated,
- authentication,
- "Successfully authenticated, with entitlements: " + token.getAuthorities());
- return token;
- }
- });
-
- LOG.debug("User {} successfully authenticated, with entitlements {}",
- authentication.getPrincipal(), token.getAuthorities());
- } else {
- AuthContextUtils.execWithAuthContext(domainKey, new Executable<Void>() {
-
- @Override
- public Void exec() {
- dataAccessor.audit(
- AuditElements.EventCategoryType.REST,
- AuditElements.AUTHENTICATION_CATEGORY,
- null,
- AuditElements.LOGIN_EVENT,
- Result.FAILURE,
- null,
- isAuthenticated,
- authentication,
- "User " + authentication.getPrincipal() + " not authenticated");
- return null;
- }
- });
-
- LOG.debug("User {} not authenticated", authentication.getPrincipal());
-
- throw new BadCredentialsException("User " + authentication.getPrincipal() + " not authenticated");
- }
-
- return token;
- }
-
- @Override
- public boolean supports(final Class<? extends Object> type) {
- return type.equals(UsernamePasswordAuthenticationToken.class);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
deleted file mode 100644
index 706bf15..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
+++ /dev/null
@@ -1,90 +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.core.misc.security;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import org.apache.commons.collections4.Closure;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.SetUtils;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-import org.apache.syncope.core.misc.utils.RealmUtils;
-import org.springframework.security.core.GrantedAuthority;
-
-public class SyncopeGrantedAuthority implements GrantedAuthority {
-
- private static final long serialVersionUID = -5647624636011919735L;
-
- private final String entitlement;
-
- private final Set<String> realms = SetUtils.orderedSet(new HashSet<String>());
-
- public SyncopeGrantedAuthority(final String entitlement) {
- this.entitlement = entitlement;
- }
-
- public SyncopeGrantedAuthority(final String entitlement, final String realm) {
- this.entitlement = entitlement;
- this.realms.add(realm);
- }
-
- public boolean addRealm(final String newRealm) {
- return RealmUtils.normalizingAddTo(realms, newRealm);
- }
-
- public void addRealms(final Collection<String> newRealms) {
- IterableUtils.forEach(newRealms, new Closure<String>() {
-
- @Override
- public void execute(final String newRealm) {
- addRealm(newRealm);
- }
- });
- }
-
- public Set<String> getRealms() {
- return Collections.unmodifiableSet(realms);
- }
-
- @Override
- public String getAuthority() {
- return entitlement;
- }
-
- @Override
- public boolean equals(final Object obj) {
- return EqualsBuilder.reflectionEquals(this, obj);
- }
-
- @Override
- public int hashCode() {
- return HashCodeBuilder.reflectionHashCode(this);
- }
-
- @Override
- public String toString() {
- return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
deleted file mode 100644
index 70ec6ac..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeUserDetailsService.java
+++ /dev/null
@@ -1,37 +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.core.misc.security;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Configurable;
-import org.springframework.security.core.userdetails.User;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-
-@Configurable
-public class SyncopeUserDetailsService implements UserDetailsService {
-
- @Autowired
- protected AuthDataAccessor dataAccessor;
-
- @Override
- public UserDetails loadUserByUsername(final String username) {
- return new User(username, "<PASSWORD_PLACEHOLDER>", dataAccessor.load(username));
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeDeserializer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeDeserializer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeDeserializer.java
deleted file mode 100644
index 5c2ab51..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeDeserializer.java
+++ /dev/null
@@ -1,83 +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.core.misc.serialization;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.identityconnectors.common.Base64;
-import org.identityconnectors.common.security.GuardedString;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.AttributeBuilder;
-import org.identityconnectors.framework.common.objects.Name;
-import org.identityconnectors.framework.common.objects.Uid;
-
-class AttributeDeserializer extends JsonDeserializer<Attribute> {
-
- @Override
- public Attribute deserialize(final JsonParser jp, final DeserializationContext ctx)
- throws IOException {
-
- ObjectNode tree = jp.readValueAsTree();
-
- String name = tree.get("name").asText();
-
- List<Object> values = new ArrayList<Object>();
- for (Iterator<JsonNode> itor = tree.get("value").iterator(); itor.hasNext();) {
- JsonNode node = itor.next();
- if (node.isNull()) {
- values.add(null);
- } else if (node.isObject()) {
- values.add(((ObjectNode) node).traverse(jp.getCodec()).readValueAs(GuardedString.class));
- } else if (node.isBoolean()) {
- values.add(node.asBoolean());
- } else if (node.isDouble()) {
- values.add(node.asDouble());
- } else if (node.isLong()) {
- values.add(node.asLong());
- } else if (node.isInt()) {
- values.add(node.asInt());
- } else {
- String text = node.asText();
- if (text.startsWith(AttributeSerializer.BYTE_ARRAY_PREFIX)
- && text.endsWith(AttributeSerializer.BYTE_ARRAY_SUFFIX)) {
-
- values.add(Base64.decode(StringUtils.substringBetween(
- text, AttributeSerializer.BYTE_ARRAY_PREFIX, AttributeSerializer.BYTE_ARRAY_SUFFIX)));
- } else {
- values.add(text);
- }
- }
- }
-
- return Uid.NAME.equals(name)
- ? new Uid(values.isEmpty() || values.get(0) == null ? null : values.get(0).toString())
- : Name.NAME.equals(name)
- ? new Name(values.isEmpty() || values.get(0) == null ? null : values.get(0).toString())
- : AttributeBuilder.build(name, values);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeSerializer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeSerializer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeSerializer.java
deleted file mode 100644
index 3c79c28..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/AttributeSerializer.java
+++ /dev/null
@@ -1,73 +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.core.misc.serialization;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import java.io.IOException;
-import org.identityconnectors.common.Base64;
-import org.identityconnectors.common.security.GuardedString;
-import org.identityconnectors.framework.common.objects.Attribute;
-
-class AttributeSerializer extends JsonSerializer<Attribute> {
-
- public static final String BYTE_ARRAY_PREFIX = "<binary>";
-
- public static final String BYTE_ARRAY_SUFFIX = "</binary>";
-
- @Override
- public void serialize(final Attribute source, final JsonGenerator jgen, final SerializerProvider sp)
- throws IOException {
-
- jgen.writeStartObject();
-
- jgen.writeStringField("name", source.getName());
-
- jgen.writeFieldName("value");
- if (source.getValue() == null) {
- jgen.writeNull();
- } else {
- jgen.writeStartArray();
- for (Object value : source.getValue()) {
- if (value == null) {
- jgen.writeNull();
- } else if (value instanceof GuardedString) {
- jgen.writeObject(value);
- } else if (value instanceof Integer) {
- jgen.writeNumber((Integer) value);
- } else if (value instanceof Long) {
- jgen.writeNumber((Long) value);
- } else if (value instanceof Double) {
- jgen.writeNumber((Double) value);
- } else if (value instanceof Boolean) {
- jgen.writeBoolean((Boolean) value);
- } else if (value instanceof byte[]) {
- jgen.writeString(BYTE_ARRAY_PREFIX + Base64.encode((byte[]) value) + BYTE_ARRAY_SUFFIX);
- } else {
- jgen.writeString(value.toString());
- }
- }
- jgen.writeEndArray();
- }
-
- jgen.writeEndObject();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringDeserializer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringDeserializer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringDeserializer.java
deleted file mode 100644
index 1cd0ec0..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringDeserializer.java
+++ /dev/null
@@ -1,93 +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.core.misc.serialization;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import org.identityconnectors.common.Base64;
-import org.identityconnectors.common.security.EncryptorFactory;
-import org.identityconnectors.common.security.GuardedString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class GuardedStringDeserializer extends JsonDeserializer<GuardedString> {
-
- private static final Logger LOG = LoggerFactory.getLogger(GuardedStringDeserializer.class);
-
- @Override
- public GuardedString deserialize(final JsonParser jp, final DeserializationContext ctx)
- throws IOException {
-
- ObjectNode tree = jp.readValueAsTree();
-
- boolean readOnly = false;
- if (tree.has("readOnly")) {
- readOnly = tree.get("readOnly").asBoolean();
- }
- boolean disposed = false;
- if (tree.has("disposed")) {
- disposed = tree.get("disposed").asBoolean();
- }
- byte[] encryptedBytes = null;
- if (tree.has("encryptedBytes")) {
- encryptedBytes = Base64.decode(tree.get("encryptedBytes").asText());
- }
- String base64SHA1Hash = null;
- if (tree.has("base64SHA1Hash")) {
- base64SHA1Hash = tree.get("base64SHA1Hash").asText();
- }
-
- final byte[] clearBytes = EncryptorFactory.getInstance().getDefaultEncryptor().decrypt(encryptedBytes);
-
- GuardedString dest = new GuardedString(new String(clearBytes).toCharArray());
-
- try {
- Field field = GuardedString.class.getDeclaredField("readOnly");
- field.setAccessible(true);
- field.setBoolean(dest, readOnly);
- } catch (Exception e) {
- LOG.error("Could not set field value to {}", readOnly, e);
- }
-
- try {
- Field field = GuardedString.class.getDeclaredField("disposed");
- field.setAccessible(true);
- field.setBoolean(dest, disposed);
- } catch (Exception e) {
- LOG.error("Could not set field value to {}", disposed, e);
- }
-
- if (base64SHA1Hash != null) {
- try {
- Field field = GuardedString.class.getDeclaredField("base64SHA1Hash");
- field.setAccessible(true);
- field.set(dest, base64SHA1Hash);
- } catch (Exception e) {
- LOG.error("Could not set field value to {}", base64SHA1Hash, e);
- }
- }
-
- return dest;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringSerializer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringSerializer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringSerializer.java
deleted file mode 100644
index 5c780f0..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/GuardedStringSerializer.java
+++ /dev/null
@@ -1,89 +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.core.misc.serialization;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import org.identityconnectors.common.Base64;
-import org.identityconnectors.common.security.EncryptorFactory;
-import org.identityconnectors.common.security.GuardedString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class GuardedStringSerializer extends JsonSerializer<GuardedString> {
-
- private static final Logger LOG = LoggerFactory.getLogger(GuardedStringSerializer.class);
-
- @Override
- public void serialize(final GuardedString source, final JsonGenerator jgen, final SerializerProvider sp)
- throws IOException {
-
- jgen.writeStartObject();
-
- boolean readOnly = false;
- try {
- Field field = GuardedString.class.getDeclaredField("readOnly");
- field.setAccessible(true);
- readOnly = field.getBoolean(source);
- } catch (Exception e) {
- LOG.error("Could not get field value", e);
- }
- jgen.writeBooleanField("readOnly", readOnly);
-
- boolean disposed = false;
- try {
- Field field = GuardedString.class.getDeclaredField("disposed");
- field.setAccessible(true);
- disposed = field.getBoolean(source);
- } catch (Exception e) {
- LOG.error("Could not get field value", e);
- }
- jgen.writeBooleanField("disposed", disposed);
-
- final StringBuilder cleartext = new StringBuilder();
- source.access(new GuardedString.Accessor() {
-
- @Override
- public void access(final char[] clearChars) {
- cleartext.append(clearChars);
- }
- });
- byte[] encryptedBytes =
- EncryptorFactory.getInstance().getDefaultEncryptor().encrypt(cleartext.toString().getBytes());
- jgen.writeStringField("encryptedBytes", Base64.encode(encryptedBytes));
-
- String base64SHA1Hash = null;
- try {
- Field field = GuardedString.class.getDeclaredField("base64SHA1Hash");
- field.setAccessible(true);
- base64SHA1Hash = field.get(source).toString();
- } catch (Exception e) {
- LOG.error("Could not get field value", e);
- }
- if (base64SHA1Hash != null) {
- jgen.writeStringField("base64SHA1Hash", base64SHA1Hash);
- }
-
- jgen.writeEndObject();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/POJOHelper.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/POJOHelper.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/POJOHelper.java
deleted file mode 100644
index dd42568..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/POJOHelper.java
+++ /dev/null
@@ -1,80 +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.core.misc.serialization;
-
-import com.fasterxml.jackson.core.Version;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
-import org.identityconnectors.common.security.GuardedString;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.SyncToken;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Helper class for serialization and deserialization of configuration objects (POJOs) in JSON.
- */
-public final class POJOHelper {
-
- private static final Logger LOG = LoggerFactory.getLogger(POJOHelper.class);
-
- private static final ObjectMapper MAPPER;
-
- static {
- SimpleModule pojoModule = new SimpleModule("POJOModule", new Version(1, 0, 0, null, null, null));
- pojoModule.addSerializer(GuardedString.class, new GuardedStringSerializer());
- pojoModule.addSerializer(Attribute.class, new AttributeSerializer());
- pojoModule.addSerializer(SyncToken.class, new SyncTokenSerializer());
- pojoModule.addDeserializer(GuardedString.class, new GuardedStringDeserializer());
- pojoModule.addDeserializer(Attribute.class, new AttributeDeserializer());
- pojoModule.addDeserializer(SyncToken.class, new SyncTokenDeserializer());
-
- MAPPER = new ObjectMapper();
- MAPPER.registerModule(pojoModule);
- MAPPER.registerModule(new AfterburnerModule());
- }
-
- public static String serialize(final Object object) {
- String result = null;
-
- try {
- result = MAPPER.writeValueAsString(object);
- } catch (Exception e) {
- LOG.error("During serialization", e);
- }
-
- return result;
- }
-
- public static <T extends Object> T deserialize(final String serialized, final Class<T> reference) {
- T result = null;
-
- try {
- result = MAPPER.readValue(serialized, reference);
- } catch (Exception e) {
- LOG.error("During deserialization", e);
- }
-
- return result;
- }
-
- private POJOHelper() {
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenDeserializer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenDeserializer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenDeserializer.java
deleted file mode 100644
index cc25ef3..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenDeserializer.java
+++ /dev/null
@@ -1,64 +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.core.misc.serialization;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import java.io.IOException;
-import org.apache.commons.codec.binary.Base64;
-import org.identityconnectors.framework.common.objects.SyncToken;
-
-class SyncTokenDeserializer extends JsonDeserializer<SyncToken> {
-
- @Override
- public SyncToken deserialize(final JsonParser jp, final DeserializationContext ctx)
- throws IOException {
-
- ObjectNode tree = jp.readValueAsTree();
-
- Object value = null;
- if (tree.has("value")) {
- JsonNode node = tree.get("value");
- value = node.isNull()
- ? null
- : node.isBoolean()
- ? node.asBoolean()
- : node.isDouble()
- ? node.asDouble()
- : node.isLong()
- ? node.asLong()
- : node.isInt()
- ? node.asInt()
- : node.asText();
-
- if (value instanceof String) {
- String base64 = (String) value;
- if (Base64.isBase64(base64)) {
- value = Base64.decodeBase64(base64);
- }
- }
- }
-
- return new SyncToken(value);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenSerializer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenSerializer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenSerializer.java
deleted file mode 100644
index eb75eb2..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/serialization/SyncTokenSerializer.java
+++ /dev/null
@@ -1,57 +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.core.misc.serialization;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import java.io.IOException;
-import org.apache.commons.codec.binary.Base64;
-import org.identityconnectors.framework.common.objects.SyncToken;
-
-class SyncTokenSerializer extends JsonSerializer<SyncToken> {
-
- @Override
- public void serialize(final SyncToken source, final JsonGenerator jgen, final SerializerProvider sp)
- throws IOException {
-
- jgen.writeStartObject();
-
- jgen.writeFieldName("value");
-
- if (source.getValue() == null) {
- jgen.writeNull();
- } else if (source.getValue() instanceof Boolean) {
- jgen.writeBoolean((Boolean) source.getValue());
- } else if (source.getValue() instanceof Double) {
- jgen.writeNumber((Double) source.getValue());
- } else if (source.getValue() instanceof Long) {
- jgen.writeNumber((Long) source.getValue());
- } else if (source.getValue() instanceof Integer) {
- jgen.writeNumber((Integer) source.getValue());
- } else if (source.getValue() instanceof byte[]) {
- jgen.writeString(Base64.encodeBase64String((byte[]) source.getValue()));
- } else {
- jgen.writeString(source.getValue().toString());
- }
-
- jgen.writeEndObject();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
deleted file mode 100644
index e67dcd6..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ApplicationContextProvider.java
+++ /dev/null
@@ -1,57 +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.core.misc.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;
-
- private static DefaultListableBeanFactory BEAN_FACTORY;
-
- public static ConfigurableApplicationContext getApplicationContext() {
- return CTX;
- }
-
- public static DefaultListableBeanFactory getBeanFactory() {
- return BEAN_FACTORY == null
- ? CTX == null
- ? null
- : (DefaultListableBeanFactory) CTX.getBeanFactory()
- : BEAN_FACTORY;
- }
-
- public static void setBeanFactory(final DefaultListableBeanFactory beanFactory) {
- BEAN_FACTORY = beanFactory;
- }
-
- /**
- * Wiring the ApplicationContext into a static method.
- *
- * @param ctx Spring application context
- */
- @Override
- public void setApplicationContext(final ApplicationContext ctx) {
- CTX = (ConfigurableApplicationContext) ctx;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/spring/BeanUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/BeanUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/BeanUtils.java
deleted file mode 100644
index 5f9fd4d..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/BeanUtils.java
+++ /dev/null
@@ -1,193 +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.core.misc.spring;
-
-import static org.springframework.beans.BeanUtils.getPropertyDescriptor;
-import static org.springframework.beans.BeanUtils.getPropertyDescriptors;
-
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.springframework.beans.FatalBeanException;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-
-/**
- * Overrides Spring's BeanUtils not using collection setters but instead getters + addAll() / putAll(),
- * in a JAXB friendly way.
- *
- * Refer to <a href="https://issues.apache.org/jira/browse/SYNCOPE-246">SYNCOPE-246</a> for more information.
- *
- * @see org.springframework.beans.BeanUtils
- */
-public final class BeanUtils {
-
- private BeanUtils() {
- // Empty private constructor for static utility classes
- }
-
- /**
- * Copy the property values of the given source bean into the target bean.
- * <p>
- * Note: The source and target classes do not have to match or even be derived
- * from each other, as long as the properties match. Any bean properties that the
- * source bean exposes but the target bean does not will silently be ignored.
- * </p><p>
- * This is just a convenience method. For more complex transfer needs,
- * consider using a full BeanWrapper.
- * </p>
- *
- * @param source the source bean
- * @param target the target bean
- * @see org.springframework.beans.BeanWrapper
- */
- public static void copyProperties(final Object source, final Object target) {
- copyProperties(source, target, null, (String[]) null);
- }
-
- /**
- * Copy the property values of the given source bean into the given target bean,
- * only setting properties defined in the given "editable" class (or interface).
- * <p>
- * Note: The source and target classes do not have to match or even be derived
- * from each other, as long as the properties match. Any bean properties that the
- * source bean exposes but the target bean does not will silently be ignored.
- * </p><p>
- * This is just a convenience method. For more complex transfer needs,
- * consider using a full BeanWrapper.
- * </p>
- *
- * @param source the source bean
- * @param target the target bean
- * @param editable the class (or interface) to restrict property setting to
- * @see org.springframework.beans.BeanWrapper
- */
- public static void copyProperties(final Object source, final Object target, final Class<?> editable) {
- copyProperties(source, target, editable, (String[]) null);
- }
-
- /**
- * Copy the property values of the given source bean into the given target bean,
- * ignoring the given "ignoreProperties".
- * <p>
- * Note: The source and target classes do not have to match or even be derived
- * from each other, as long as the properties match. Any bean properties that the
- * source bean exposes but the target bean does not will silently be ignored.
- * </p><p>
- * This is just a convenience method. For more complex transfer needs,
- * consider using a full BeanWrapper.
- * </p>
- *
- * @param source the source bean
- * @param target the target bean
- * @param ignoreProperties array of property names to ignore
- * @see org.springframework.beans.BeanWrapper
- */
- public static void copyProperties(final Object source, final Object target, final String... ignoreProperties) {
- copyProperties(source, target, null, ignoreProperties);
- }
-
- /**
- * Copy the property values of the given source bean into the given target bean.
- * <p>
- * Note: The source and target classes do not have to match or even be derived
- * from each other, as long as the properties match. Any bean properties that the
- * source bean exposes but the target bean does not will silently be ignored.
- * </p>
- *
- * @param source the source bean
- * @param target the target bean
- * @param editable the class (or interface) to restrict property setting to
- * @param ignoreProperties array of property names to ignore
- * @see org.springframework.beans.BeanWrapper
- */
- @SuppressWarnings("unchecked")
- private static void copyProperties(
- final Object source, final Object target, final Class<?> editable, final String... ignoreProperties) {
-
- Assert.notNull(source, "Source must not be null");
- Assert.notNull(target, "Target must not be null");
-
- Class<?> actualEditable = target.getClass();
- if (editable != null) {
- if (!editable.isInstance(target)) {
- throw new IllegalArgumentException("Target class [" + target.getClass().getName()
- + "] not assignable to Editable class [" + editable.getName() + "]");
- }
- actualEditable = editable;
- }
- PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
- List<String> ignoreList = (ignoreProperties == null)
- ? Collections.<String>emptyList() : Arrays.asList(ignoreProperties);
-
- for (PropertyDescriptor targetPd : targetPds) {
- if (ignoreProperties == null || (!ignoreList.contains(targetPd.getName()))) {
- PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
- if (sourcePd != null) {
- Method readMethod = sourcePd.getReadMethod();
- if (readMethod != null) {
- Method writeMethod = targetPd.getWriteMethod();
-
- try {
- // Diverts from Spring's BeanUtils: if no write method is found and property is collection,
- // try to use addAll() / putAll().
- if (writeMethod == null) {
- Object value = readMethod.invoke(source);
- Method targetReadMethod = targetPd.getReadMethod();
- if (targetReadMethod != null) {
- if (!Modifier.isPublic(targetReadMethod.getDeclaringClass().getModifiers())) {
- targetReadMethod.setAccessible(true);
- }
- Object destValue = targetReadMethod.invoke(target);
-
- if (value instanceof Collection && destValue instanceof Collection) {
- ((Collection) destValue).clear();
- ((Collection) destValue).addAll((Collection) value);
- } else if (value instanceof Map && destValue instanceof Map) {
- ((Map) destValue).clear();
- ((Map) destValue).putAll((Map) value);
- }
- }
- } else if (ClassUtils.isAssignable(
- writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
-
- if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
- readMethod.setAccessible(true);
- }
- Object value = readMethod.invoke(source);
- if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
- writeMethod.setAccessible(true);
- }
- writeMethod.invoke(target, value);
- }
- } catch (Throwable ex) {
- throw new FatalBeanException(
- "Could not copy property '" + targetPd.getName() + "' from source to target", ex);
- }
- }
- }
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DefaultRolesPrefixPostProcessor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DefaultRolesPrefixPostProcessor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DefaultRolesPrefixPostProcessor.java
deleted file mode 100644
index d91a60f..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DefaultRolesPrefixPostProcessor.java
+++ /dev/null
@@ -1,65 +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.core.misc.spring;
-
-import javax.servlet.ServletException;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.FatalBeanException;
-import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.core.PriorityOrdered;
-import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
-import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
-import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
-
-/**
- * Removes the limitation of having Spring security roles to be prefixed with 'ROLE_'.
- */
-public class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {
-
- @Override
- public Object postProcessAfterInitialization(final Object bean, final String beanName) {
- if (bean instanceof DefaultMethodSecurityExpressionHandler) {
- ((DefaultMethodSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
- }
- if (bean instanceof DefaultWebSecurityExpressionHandler) {
- ((DefaultWebSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
- }
- if (bean instanceof SecurityContextHolderAwareRequestFilter) {
- SecurityContextHolderAwareRequestFilter filter = (SecurityContextHolderAwareRequestFilter) bean;
- filter.setRolePrefix(StringUtils.EMPTY);
- try {
- filter.afterPropertiesSet();
- } catch (ServletException e) {
- throw new FatalBeanException(e.getMessage(), e);
- }
- }
-
- return bean;
- }
-
- @Override
- public Object postProcessBeforeInitialization(final Object bean, final String beanName) {
- return bean;
- }
-
- @Override
- public int getOrder() {
- return PriorityOrdered.HIGHEST_PRECEDENCE;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptor.java
deleted file mode 100644
index e239002..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptor.java
+++ /dev/null
@@ -1,70 +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.core.misc.spring;
-
-import java.lang.reflect.Method;
-import org.aopalliance.intercept.MethodInvocation;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
-import org.springframework.transaction.interceptor.TransactionAttribute;
-import org.springframework.transaction.interceptor.TransactionAttributeSource;
-import org.springframework.transaction.interceptor.TransactionInterceptor;
-
-/**
- * Extends the standard {@link TransactionInterceptor} by dynamically setting the appropriate
- * {@link TransactionAttribute} qualifier according to the authentication domain of the caller - retrieved via
- * {@link AuthContextUtils#getDomain()}.
- */
-public class DomainTransactionInterceptor extends TransactionInterceptor {
-
- private static final long serialVersionUID = 5113728988680448551L;
-
- private static final Logger LOG = LoggerFactory.getLogger(DomainTransactionInterceptor.class);
-
- @Override
- public TransactionAttributeSource getTransactionAttributeSource() {
- final TransactionAttributeSource origTxAttrSource = super.getTransactionAttributeSource();
-
- return new TransactionAttributeSource() {
-
- @Override
- public TransactionAttribute getTransactionAttribute(final Method method, final Class<?> targetClass) {
- TransactionAttribute txAttr = origTxAttrSource.getTransactionAttribute(method, targetClass);
-
- if (txAttr instanceof DefaultTransactionAttribute) {
- ((DefaultTransactionAttribute) txAttr).setQualifier(AuthContextUtils.getDomain());
- }
-
- return txAttr;
- }
- };
- }
-
- @Override
- public Object invoke(final MethodInvocation invocation) throws Throwable {
- try {
- return super.invoke(invocation);
- } catch (Throwable e) {
- LOG.debug("Error during {} invocation", invocation.getMethod(), e);
- throw e;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptorInjector.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptorInjector.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptorInjector.java
deleted file mode 100644
index d9d772b..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/DomainTransactionInterceptorInjector.java
+++ /dev/null
@@ -1,38 +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.core.misc.spring;
-
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.transaction.interceptor.TransactionInterceptor;
-
-/**
- * Replaces Spring's {@link TransactionInterceptor} with {@link DomainTransactionInterceptor}.
- */
-public class DomainTransactionInterceptorInjector implements BeanFactoryPostProcessor {
-
- @Override
- public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
- BeanDefinition bd = beanFactory.getBeanDefinition(TransactionInterceptor.class.getName() + "#0");
- bd.setBeanClassName(DomainTransactionInterceptor.class.getName());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ResourceWithFallbackLoader.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ResourceWithFallbackLoader.java b/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ResourceWithFallbackLoader.java
deleted file mode 100644
index 0fdc116..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/spring/ResourceWithFallbackLoader.java
+++ /dev/null
@@ -1,82 +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.core.misc.spring;
-
-import java.io.IOException;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.ArrayUtils;
-import org.springframework.context.ResourceLoaderAware;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.ResourceLoader;
-import org.springframework.core.io.support.ResourcePatternResolver;
-
-public class ResourceWithFallbackLoader implements ResourceLoaderAware, ResourcePatternResolver {
-
- private ResourcePatternResolver resolver;
-
- private String primary;
-
- private String fallback;
-
- @Override
- public void setResourceLoader(final ResourceLoader resourceLoader) {
- this.resolver = (ResourcePatternResolver) resourceLoader;
- }
-
- public void setPrimary(final String primary) {
- this.primary = primary;
- }
-
- public void setFallback(final String fallback) {
- this.fallback = fallback;
- }
-
- @Override
- public Resource getResource(final String location) {
- Resource resource = resolver.getResource(primary + location);
- if (!resource.exists()) {
- resource = resolver.getResource(fallback + location);
- }
-
- return resource;
- }
-
- public Resource getResource() {
- return getResource(StringUtils.EMPTY);
- }
-
- @Override
- public Resource[] getResources(final String locationPattern) throws IOException {
- Resource[] resources = resolver.getResources(primary + locationPattern);
- if (ArrayUtils.isEmpty(resources)) {
- resources = resolver.getResources(fallback + locationPattern);
- }
-
- return resources;
- }
-
- public Resource[] getResources() throws IOException {
- return getResources(StringUtils.EMPTY);
- }
-
- @Override
- public ClassLoader getClassLoader() {
- return resolver.getClassLoader();
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ConnObjectUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ConnObjectUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ConnObjectUtils.java
deleted file mode 100644
index 667a28e..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ConnObjectUtils.java
+++ /dev/null
@@ -1,267 +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.core.misc.utils;
-
-import org.apache.syncope.core.misc.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.misc.security.SecureRandomUtils;
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.AnyOperations;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.misc.security.Encryptor;
-import org.apache.syncope.core.misc.security.PasswordGenerator;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.identityconnectors.common.Base64;
-import org.identityconnectors.common.security.GuardedByteArray;
-import org.identityconnectors.common.security.GuardedString;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-@Component
-public class ConnObjectUtils {
-
- private static final Logger LOG = LoggerFactory.getLogger(ConnObjectUtils.class);
-
- private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
-
- @Autowired
- private TemplateUtils templateUtils;
-
- @Autowired
- private RealmDAO realmDAO;
-
- @Autowired
- private UserDAO userDAO;
-
- @Autowired
- private ExternalResourceDAO resourceDAO;
-
- @Autowired
- private PasswordGenerator passwordGenerator;
-
- @Autowired
- private MappingUtils mappingUtils;
-
- /**
- * Extract password value from passed value (if instance of GuardedString or GuardedByteArray).
- *
- * @param pwd received from the underlying connector
- * @return password value
- */
- public static String getPassword(final Object pwd) {
- final StringBuilder result = new StringBuilder();
-
- if (pwd instanceof GuardedString) {
- ((GuardedString) pwd).access(new GuardedString.Accessor() {
-
- @Override
- public void access(final char[] clearChars) {
- result.append(clearChars);
- }
- });
- } else if (pwd instanceof GuardedByteArray) {
- ((GuardedByteArray) pwd).access(new GuardedByteArray.Accessor() {
-
- @Override
- public void access(final byte[] clearBytes) {
- result.append(new String(clearBytes));
- }
- });
- } else if (pwd instanceof String) {
- result.append((String) pwd);
- } else {
- result.append(pwd.toString());
- }
-
- return result.toString();
- }
-
- /**
- * Build a UserTO / GroupTO / AnyObjectTO out of connector object attributes and schema mapping.
- *
- * @param obj connector object
- * @param syncTask synchronization task
- * @param provision provision information
- * @param anyUtils utils
- * @param <T> any object
- * @return UserTO for the user to be created
- */
- @Transactional(readOnly = true)
- public <T extends AnyTO> T getAnyTO(
- final ConnectorObject obj, final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
-
- T anyTO = getAnyTOFromConnObject(obj, syncTask, provision, anyUtils);
-
- // (for users) if password was not set above, generate
- if (anyTO instanceof UserTO && StringUtils.isBlank(((UserTO) anyTO).getPassword())) {
- final UserTO userTO = (UserTO) anyTO;
-
- List<PasswordRuleConf> ruleConfs = new ArrayList<>();
-
- Realm realm = realmDAO.find(userTO.getRealm());
- if (realm != null) {
- for (Realm ancestor : realmDAO.findAncestors(realm)) {
- if (ancestor.getPasswordPolicy() != null) {
- ruleConfs.addAll(ancestor.getPasswordPolicy().getRuleConfs());
- }
- }
- }
-
- for (String resName : userTO.getResources()) {
- ExternalResource resource = resourceDAO.find(resName);
- if (resource != null && resource.getPasswordPolicy() != null) {
- ruleConfs.addAll(resource.getPasswordPolicy().getRuleConfs());
- }
- }
-
- String password;
- try {
- password = passwordGenerator.generate(ruleConfs);
- } catch (InvalidPasswordRuleConf e) {
- LOG.error("Could not generate policy-compliant random password for {}", userTO, e);
-
- password = SecureRandomUtils.generateRandomPassword(16);
- }
- userTO.setPassword(password);
- }
-
- return anyTO;
- }
-
- /**
- * Build {@link AnyPatch} out of connector object attributes and schema mapping.
- *
- * @param key any object to be updated
- * @param obj connector object
- * @param original any object to get diff from
- * @param syncTask synchronization task
- * @param provision provision information
- * @param anyUtils utils
- * @param <T> any object
- * @return modifications for the any object to be updated
- */
- @SuppressWarnings("unchecked")
- @Transactional(readOnly = true)
- public <T extends AnyPatch> T getAnyPatch(final Long key, final ConnectorObject obj,
- final AnyTO original, final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
-
- AnyTO updated = getAnyTOFromConnObject(obj, syncTask, provision, anyUtils);
- updated.setKey(key);
-
- if (null != anyUtils.getAnyTypeKind()) {
- switch (anyUtils.getAnyTypeKind()) {
- case USER:
- // update password if and only if password is really changed
- User user = userDAO.authFind(key);
- if (StringUtils.isBlank(((UserTO) updated).getPassword())
- || ENCRYPTOR.verify(((UserTO) updated).getPassword(),
- user.getCipherAlgorithm(), user.getPassword())) {
-
- ((UserTO) updated).setPassword(null);
- }
- return (T) AnyOperations.diff(((UserTO) updated), ((UserTO) original), true);
-
- case GROUP:
- return (T) AnyOperations.diff(((GroupTO) updated), ((GroupTO) original), true);
-
- case ANY_OBJECT:
- return (T) AnyOperations.diff(((AnyObjectTO) updated), ((AnyObjectTO) original), true);
-
- default:
- }
- }
-
- return null;
- }
-
- private <T extends AnyTO> T getAnyTOFromConnObject(final ConnectorObject obj,
- final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
-
- T anyTO = anyUtils.newAnyTO();
- anyTO.setType(provision.getAnyType().getKey());
-
- // 1. fill with data from connector object
- anyTO.setRealm(syncTask.getDestinatioRealm().getFullPath());
- for (MappingItem item : MappingUtils.getSyncMappingItems(provision)) {
- mappingUtils.setIntValues(item, obj.getAttributeByName(item.getExtAttrName()), anyTO, anyUtils);
- }
-
- // 2. add data from defined template (if any)
- templateUtils.apply(anyTO, syncTask.getTemplate(provision.getAnyType()));
-
- return anyTO;
- }
-
- /**
- * Get connector object TO from a connector object.
- *
- * @param connObject connector object.
- * @return connector object TO.
- */
- public ConnObjectTO getConnObjectTO(final ConnectorObject connObject) {
- final ConnObjectTO connObjectTO = new ConnObjectTO();
-
- if (connObject != null) {
- for (Attribute attr : connObject.getAttributes()) {
- AttrTO attrTO = new AttrTO();
- attrTO.setSchema(attr.getName());
-
- if (attr.getValue() != null) {
- for (Object value : attr.getValue()) {
- if (value != null) {
- if (value instanceof GuardedString || value instanceof GuardedByteArray) {
- attrTO.getValues().add(getPassword(value));
- } else if (value instanceof byte[]) {
- attrTO.getValues().add(Base64.encode((byte[]) value));
- } else {
- attrTO.getValues().add(value.toString());
- }
- }
- }
- }
-
- connObjectTO.getPlainAttrs().add(attrTO);
- }
- }
-
- return connObjectTO;
- }
-}
[17/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
Further refactoring as per SYNCOPE-620
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/28569df5
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/28569df5
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/28569df5
Branch: refs/heads/master
Commit: 28569df55015aa2ac86ac21020005d0e8fb4addf
Parents: 0d09829
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Mar 8 16:12:14 2016 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Mar 9 12:41:12 2016 +0100
----------------------------------------------------------------------
archetype/pom.xml | 2 +-
.../syncope/core/logic/AbstractAnyLogic.java | 8 +-
.../syncope/core/logic/AnyObjectLogic.java | 4 +-
.../apache/syncope/core/logic/AnyTypeLogic.java | 2 +-
.../syncope/core/logic/ConfigurationLogic.java | 2 +-
.../apache/syncope/core/logic/GroupLogic.java | 6 +-
.../apache/syncope/core/logic/LoggerLogic.java | 6 +-
.../core/logic/LogicInvocationHandler.java | 2 +-
.../syncope/core/logic/ResourceLogic.java | 16 +-
.../apache/syncope/core/logic/SyncopeLogic.java | 4 +-
.../apache/syncope/core/logic/UserLogic.java | 4 +-
.../init/ClassPathScanImplementationLookup.java | 12 +-
.../core/logic/init/EntitlementAccessor.java | 2 +-
.../core/logic/init/EntitlementLoader.java | 4 +-
.../syncope/core/logic/init/JobManagerImpl.java | 8 +-
.../syncope/core/logic/init/LoggerAccessor.java | 2 +-
.../syncope/core/logic/init/LoggerLoader.java | 9 +-
.../core/logic/init/LogicInitializer.java | 2 +-
.../logic/notification/NotificationJob.java | 2 +-
.../notification/NotificationJobDelegate.java | 4 +-
.../core/logic/report/AuditReportlet.java | 6 +-
.../core/logic/report/GroupReportlet.java | 2 +-
.../logic/report/ReconciliationReportlet.java | 24 +-
.../syncope/core/logic/report/ReportJob.java | 2 +-
.../core/logic/report/ReportJobDelegate.java | 4 +-
.../core/logic/report/StaticReportlet.java | 2 +-
.../core/logic/report/UserReportlet.java | 4 +-
core/misc/pom.xml | 137 ---
.../apache/syncope/core/misc/AuditEntry.java | 77 --
.../apache/syncope/core/misc/AuditManager.java | 79 --
.../syncope/core/misc/EntitlementsHolder.java | 72 --
.../core/misc/jexl/ClassFreeUberspect.java | 41 -
.../core/misc/jexl/EmptyClassLoader.java | 36 -
.../syncope/core/misc/jexl/JexlUtils.java | 241 ------
.../misc/policy/AccountPolicyException.java | 32 -
.../misc/policy/InvalidPasswordRuleConf.java | 37 -
.../misc/policy/PasswordPolicyException.java | 32 -
.../core/misc/policy/PolicyException.java | 32 -
.../syncope/core/misc/policy/PolicyPattern.java | 50 --
.../core/misc/search/SearchCondConverter.java | 64 --
.../core/misc/search/SearchCondVisitor.java | 222 -----
.../core/misc/security/AuthContextUtils.java | 126 ---
.../core/misc/security/AuthDataAccessor.java | 318 -------
.../misc/security/DefaultPasswordGenerator.java | 334 --------
.../DelegatedAdministrationException.java | 33 -
.../syncope/core/misc/security/Encryptor.java | 256 ------
.../misc/security/MustChangePasswordFilter.java | 80 --
.../core/misc/security/PasswordGenerator.java | 32 -
.../core/misc/security/SecureRandomUtils.java | 48 --
.../security/SyncopeAccessDeniedHandler.java | 43 -
.../security/SyncopeAuthenticationDetails.java | 86 --
.../SyncopeAuthenticationDetailsSource.java | 32 -
.../SyncopeAuthenticationEntryPoint.java | 43 -
.../security/SyncopeAuthenticationProvider.java | 210 -----
.../misc/security/SyncopeGrantedAuthority.java | 90 --
.../security/SyncopeUserDetailsService.java | 37 -
.../serialization/AttributeDeserializer.java | 83 --
.../misc/serialization/AttributeSerializer.java | 73 --
.../GuardedStringDeserializer.java | 93 --
.../serialization/GuardedStringSerializer.java | 89 --
.../core/misc/serialization/POJOHelper.java | 80 --
.../serialization/SyncTokenDeserializer.java | 64 --
.../misc/serialization/SyncTokenSerializer.java | 57 --
.../misc/spring/ApplicationContextProvider.java | 57 --
.../syncope/core/misc/spring/BeanUtils.java | 193 -----
.../spring/DefaultRolesPrefixPostProcessor.java | 65 --
.../spring/DomainTransactionInterceptor.java | 70 --
.../DomainTransactionInterceptorInjector.java | 38 -
.../misc/spring/ResourceWithFallbackLoader.java | 82 --
.../core/misc/utils/ConnObjectUtils.java | 267 ------
.../syncope/core/misc/utils/EntityUtils.java | 41 -
.../core/misc/utils/ExceptionUtils2.java | 47 -
.../syncope/core/misc/utils/FormatUtils.java | 121 ---
.../syncope/core/misc/utils/MappingUtils.java | 841 ------------------
.../syncope/core/misc/utils/RealmUtils.java | 63 --
.../syncope/core/misc/utils/TemplateUtils.java | 224 -----
.../misc/src/main/resources/security.properties | 32 -
.../misc/src/main/resources/securityContext.xml | 95 ---
core/misc/src/main/resources/utilsContext.xml | 32 -
.../misc/search/SearchCondConverterTest.java | 226 -----
.../core/misc/security/EncryptorTest.java | 58 --
.../misc/security/PasswordGeneratorTest.java | 144 ----
core/persistence-api/pom.xml | 13 +
.../api/search/SearchCondConverter.java | 64 ++
.../api/search/SearchCondVisitor.java | 222 +++++
.../api/search/SearchCondConverterTest.java | 226 +++++
core/persistence-jpa/pom.xml | 14 +-
.../jpa/content/ContentLoaderHandler.java | 2 +-
.../jpa/content/XMLContentExporter.java | 4 +-
.../jpa/content/XMLContentLoader.java | 4 +-
.../core/persistence/jpa/dao/AbstractDAO.java | 4 +-
.../persistence/jpa/dao/DefaultAccountRule.java | 2 +-
.../jpa/dao/DefaultPasswordRule.java | 4 +-
.../persistence/jpa/dao/JPAAnyObjectDAO.java | 8 +-
.../persistence/jpa/dao/JPAAnySearchDAO.java | 4 +-
.../core/persistence/jpa/dao/JPAGroupDAO.java | 8 +-
.../core/persistence/jpa/dao/JPARoleDAO.java | 2 +-
.../core/persistence/jpa/dao/JPAUserDAO.java | 10 +-
.../persistence/jpa/entity/AbstractAny.java | 2 +-
.../jpa/entity/AbstractPlainAttrValue.java | 4 +-
.../jpa/entity/AnnotatedEntityListener.java | 2 +-
.../jpa/entity/JPAAnyUtilsFactory.java | 2 +-
.../persistence/jpa/entity/JPAConnInstance.java | 2 +-
.../core/persistence/jpa/entity/JPADomain.java | 2 +-
.../jpa/entity/JPAReportletConfInstance.java | 2 +-
.../persistence/jpa/entity/group/JPAGroup.java | 2 +-
.../jpa/entity/policy/JPAAccountPolicy.java | 2 +-
.../policy/JPAAccountRuleConfInstance.java | 2 +-
.../policy/JPAPasswordRuleConfInstance.java | 2 +-
.../jpa/entity/policy/JPAPushPolicy.java | 2 +-
.../jpa/entity/policy/JPASyncPolicy.java | 2 +-
.../entity/resource/AbstractAnyTemplate.java | 2 +-
.../entity/resource/JPAExternalResource.java | 2 +-
.../jpa/entity/resource/JPAProvision.java | 2 +-
.../jpa/entity/task/JPAPropagationTask.java | 2 +-
.../persistence/jpa/entity/user/JPAUser.java | 6 +-
.../spring/DomainTransactionInterceptor.java | 70 ++
.../DomainTransactionInterceptorInjector.java | 38 +
.../entity/ConnInstanceValidator.java | 4 +-
.../entity/EntityValidationListener.java | 2 +-
.../entity/ExternalResourceValidator.java | 2 +-
.../entity/ProvisioningTaskValidator.java | 6 +-
.../src/main/resources/domains.xml | 2 +-
.../src/main/resources/domains/MasterDomain.xml | 4 +-
.../src/main/resources/persistenceContext.xml | 4 +-
.../core/persistence/jpa/AbstractTest.java | 4 +-
.../persistence/jpa/inner/MultitenancyTest.java | 4 +-
.../persistence/jpa/inner/PlainAttrTest.java | 2 +-
.../core/persistence/jpa/inner/PolicyTest.java | 2 +-
.../core/persistence/jpa/inner/UserTest.java | 4 +-
.../core/persistence/jpa/outer/GroupTest.java | 2 +-
.../core/persistence/jpa/outer/RoleTest.java | 2 +-
.../core/persistence/jpa/outer/TaskTest.java | 2 +-
.../test/resources/domains/MasterContent.xml | 2 +-
.../src/test/resources/domains/TwoDomain.xml | 4 +-
.../src/test/resources/persistenceTest.xml | 7 +-
core/pom.xml | 2 +-
core/provisioning-api/pom.xml | 13 +
.../core/provisioning/api/AuditManager.java | 35 +
.../provisioning/api/ConnPoolConfUtils.java | 69 --
.../core/provisioning/api/Connector.java | 2 +-
.../provisioning/api/EntitlementsHolder.java | 72 ++
.../core/provisioning/api/MappingManager.java | 78 ++
.../syncope/core/provisioning/api/URIUtils.java | 61 --
.../api/UserProvisioningManager.java | 2 +-
.../serialization/AttributeDeserializer.java | 83 ++
.../api/serialization/AttributeSerializer.java | 73 ++
.../GuardedStringDeserializer.java | 93 ++
.../serialization/GuardedStringSerializer.java | 89 ++
.../api/serialization/POJOHelper.java | 80 ++
.../serialization/SyncTokenDeserializer.java | 66 ++
.../api/serialization/SyncTokenSerializer.java | 57 ++
.../api/sync/AnyObjectPushResultHandler.java | 23 -
.../api/sync/AnyObjectSyncResultHandler.java | 23 -
.../api/sync/GroupPushResultHandler.java | 23 -
.../api/sync/GroupSyncResultHandler.java | 26 -
.../api/sync/IgnoreProvisionException.java | 29 -
.../api/sync/ProvisioningActions.java | 40 -
.../api/sync/ProvisioningProfile.java | 81 --
.../api/sync/ProvisioningReport.java | 140 ---
.../core/provisioning/api/sync/PushActions.java | 163 ----
.../api/sync/ReconciliationFilterBuilder.java | 30 -
.../core/provisioning/api/sync/SyncActions.java | 203 -----
.../api/sync/SyncCorrelationRule.java | 36 -
.../api/sync/SyncopePushResultHandler.java | 26 -
.../api/sync/SyncopeResultHandler.java | 29 -
.../api/sync/SyncopeSyncResultHandler.java | 29 -
.../api/sync/UserPushResultHandler.java | 23 -
.../api/sync/UserSyncResultHandler.java | 23 -
.../syncpull/AnyObjectPushResultHandler.java | 23 +
.../syncpull/AnyObjectSyncResultHandler.java | 23 +
.../api/syncpull/GroupPushResultHandler.java | 23 +
.../api/syncpull/GroupSyncResultHandler.java | 26 +
.../api/syncpull/IgnoreProvisionException.java | 29 +
.../api/syncpull/ProvisioningActions.java | 40 +
.../api/syncpull/ProvisioningProfile.java | 81 ++
.../api/syncpull/ProvisioningReport.java | 140 +++
.../provisioning/api/syncpull/PushActions.java | 163 ++++
.../syncpull/ReconciliationFilterBuilder.java | 30 +
.../provisioning/api/syncpull/SyncActions.java | 203 +++++
.../api/syncpull/SyncCorrelationRule.java | 36 +
.../api/syncpull/SyncopePushResultHandler.java | 26 +
.../api/syncpull/SyncopeResultHandler.java | 29 +
.../api/syncpull/SyncopeSyncResultHandler.java | 29 +
.../api/syncpull/UserPushResultHandler.java | 23 +
.../api/syncpull/UserSyncResultHandler.java | 23 +
.../api/utils/ConnPoolConfUtils.java | 69 ++
.../provisioning/api/utils/EntityUtils.java | 41 +
.../provisioning/api/utils/ExceptionUtils2.java | 47 +
.../provisioning/api/utils/FormatUtils.java | 121 +++
.../core/provisioning/api/utils/RealmUtils.java | 63 ++
.../core/provisioning/api/utils/URIUtils.java | 61 ++
.../utils/policy/AccountPolicyException.java | 32 +
.../utils/policy/InvalidPasswordRuleConf.java | 37 +
.../utils/policy/PasswordPolicyException.java | 32 +
.../api/utils/policy/PolicyException.java | 32 +
.../api/utils/policy/PolicyPattern.java | 50 ++
core/provisioning-java/pom.xml | 7 +-
.../core/provisioning/java/AuditEntry.java | 77 ++
.../provisioning/java/AuditManagerImpl.java | 81 ++
.../java/ConnIdBundleManagerImpl.java | 2 +-
.../provisioning/java/ConnectorFacadeProxy.java | 9 +-
.../provisioning/java/ConnectorManager.java | 4 +-
.../DefaultAnyObjectProvisioningManager.java | 2 +-
.../java/DefaultGroupProvisioningManager.java | 2 +-
.../java/DefaultUserProvisioningManager.java | 4 +-
.../provisioning/java/DerAttrHandlerImpl.java | 2 +-
.../provisioning/java/MappingManagerImpl.java | 847 +++++++++++++++++++
.../provisioning/java/VirAttrHandlerImpl.java | 13 +-
.../java/data/AbstractAnyDataBinder.java | 20 +-
.../java/data/AnyObjectDataBinderImpl.java | 4 +-
.../java/data/ConfigurationDataBinderImpl.java | 2 +-
.../java/data/ConnInstanceDataBinderImpl.java | 4 +-
.../java/data/GroupDataBinderImpl.java | 2 +-
.../java/data/NotificationDataBinderImpl.java | 2 +-
.../java/data/RealmDataBinderImpl.java | 2 +-
.../java/data/ReportDataBinderImpl.java | 2 +-
.../java/data/ResourceDataBinderImpl.java | 4 +-
.../java/data/RoleDataBinderImpl.java | 2 +-
.../java/data/SchemaDataBinderImpl.java | 4 +-
.../data/SecurityQuestionDataBinderImpl.java | 2 +-
.../java/data/TaskDataBinderImpl.java | 8 +-
.../java/data/UserDataBinderImpl.java | 8 +-
.../java/jexl/ClassFreeUberspect.java | 41 +
.../java/jexl/EmptyClassLoader.java | 36 +
.../core/provisioning/java/jexl/JexlUtils.java | 241 ++++++
.../java/job/AbstractInterruptableJob.java | 2 +-
.../java/job/AbstractSchedTaskJobDelegate.java | 4 +-
.../core/provisioning/java/job/TaskJob.java | 4 +-
.../notification/NotificationManagerImpl.java | 6 +-
.../AbstractPropagationTaskExecutor.java | 17 +-
.../propagation/DefaultPropagationReporter.java | 2 +-
.../LDAPMembershipPropagationActions.java | 2 +-
.../PriorityPropagationTaskExecutor.java | 2 +-
.../propagation/PropagationManagerImpl.java | 13 +-
.../PropagationTaskCallableImpl.java | 4 +-
.../sync/AbstractProvisioningJobDelegate.java | 434 ----------
.../java/sync/AbstractPushResultHandler.java | 434 ----------
.../java/sync/AbstractSyncResultHandler.java | 797 -----------------
.../java/sync/AbstractSyncopeResultHandler.java | 155 ----
.../sync/AnyObjectPushResultHandlerImpl.java | 70 --
.../sync/AnyObjectSyncResultHandlerImpl.java | 112 ---
.../java/sync/DBPasswordSyncActions.java | 142 ----
.../java/sync/DefaultPushActions.java | 100 ---
.../DefaultReconciliationFilterBuilder.java | 38 -
.../java/sync/DefaultSyncActions.java | 121 ---
.../java/sync/GroupPushResultHandlerImpl.java | 70 --
.../java/sync/GroupSyncResultHandlerImpl.java | 138 ---
.../java/sync/LDAPMembershipSyncActions.java | 335 --------
.../java/sync/LDAPPasswordSyncActions.java | 124 ---
.../sync/PlainAttrsSyncCorrelationRule.java | 115 ---
.../provisioning/java/sync/PushJobDelegate.java | 206 -----
.../provisioning/java/sync/SyncJobDelegate.java | 251 ------
.../core/provisioning/java/sync/SyncUtils.java | 318 -------
.../java/sync/UserPushResultHandlerImpl.java | 96 ---
.../java/sync/UserSyncResultHandlerImpl.java | 133 ---
.../AbstractProvisioningJobDelegate.java | 434 ++++++++++
.../syncpull/AbstractPushResultHandler.java | 434 ++++++++++
.../syncpull/AbstractSyncResultHandler.java | 797 +++++++++++++++++
.../syncpull/AbstractSyncopeResultHandler.java | 155 ++++
.../AnyObjectPushResultHandlerImpl.java | 70 ++
.../AnyObjectSyncResultHandlerImpl.java | 112 +++
.../java/syncpull/DBPasswordSyncActions.java | 142 ++++
.../java/syncpull/DefaultPushActions.java | 100 +++
.../DefaultReconciliationFilterBuilder.java | 38 +
.../java/syncpull/DefaultSyncActions.java | 121 +++
.../syncpull/GroupPushResultHandlerImpl.java | 70 ++
.../syncpull/GroupSyncResultHandlerImpl.java | 138 +++
.../syncpull/LDAPMembershipSyncActions.java | 335 ++++++++
.../java/syncpull/LDAPPasswordSyncActions.java | 124 +++
.../syncpull/PlainAttrsSyncCorrelationRule.java | 115 +++
.../java/syncpull/PushJobDelegate.java | 206 +++++
.../java/syncpull/SyncJobDelegate.java | 248 ++++++
.../provisioning/java/syncpull/SyncUtils.java | 317 +++++++
.../syncpull/UserPushResultHandlerImpl.java | 96 +++
.../syncpull/UserSyncResultHandlerImpl.java | 133 +++
.../java/utils/ConnObjectUtils.java | 269 ++++++
.../provisioning/java/utils/TemplateUtils.java | 224 +++++
.../core/provisioning/java/AbstractTest.java | 1 -
.../provisioning/java/ConnectorManagerTest.java | 2 +-
.../provisioning/java/MailTemplateTest.java | 2 +-
.../core/provisioning/java/MappingTest.java | 5 +-
.../syncope/core/rest/cxf/AddDomainFilter.java | 2 +-
.../rest/cxf/RestServiceExceptionMapper.java | 2 +-
.../rest/cxf/ThreadLocalCleanupListener.java | 2 +-
.../rest/cxf/service/AbstractServiceImpl.java | 2 +-
core/spring/pom.xml | 103 +++
.../core/spring/ApplicationContextProvider.java | 57 ++
.../apache/syncope/core/spring/BeanUtils.java | 193 +++++
.../spring/DefaultRolesPrefixPostProcessor.java | 65 ++
.../core/spring/ResourceWithFallbackLoader.java | 82 ++
.../core/spring/security/AuthContextUtils.java | 126 +++
.../core/spring/security/AuthDataAccessor.java | 319 +++++++
.../security/DefaultPasswordGenerator.java | 334 ++++++++
.../DelegatedAdministrationException.java | 33 +
.../syncope/core/spring/security/Encryptor.java | 256 ++++++
.../security/MustChangePasswordFilter.java | 80 ++
.../core/spring/security/PasswordGenerator.java | 32 +
.../core/spring/security/SecureRandomUtils.java | 48 ++
.../security/SyncopeAccessDeniedHandler.java | 43 +
.../security/SyncopeAuthenticationDetails.java | 86 ++
.../SyncopeAuthenticationDetailsSource.java | 32 +
.../SyncopeAuthenticationEntryPoint.java | 43 +
.../security/SyncopeAuthenticationProvider.java | 210 +++++
.../security/SyncopeGrantedAuthority.java | 90 ++
.../security/SyncopeUserDetailsService.java | 37 +
.../src/main/resources/security.properties | 32 +
.../src/main/resources/securityContext.xml | 96 +++
.../core/spring/security/EncryptorTest.java | 60 ++
.../spring/security/PasswordGeneratorTest.java | 146 ++++
core/workflow-activiti/pom.xml | 2 +-
.../activiti/ActivitiDefinitionLoader.java | 2 +-
.../activiti/ActivitiUserWorkflowAdapter.java | 4 +-
.../activiti/spring/DomainProcessEngine.java | 2 +-
.../main/resources/workflowActivitiContext.xml | 2 +-
deb/core/pom.xml | 2 +-
.../core/logic/init/CamelRouteLoader.java | 4 +-
.../camel/CamelUserProvisioningManager.java | 2 +-
.../provisioning/camel/SyncopeCamelContext.java | 2 +-
.../camel/data/CamelRouteDataBinderImpl.java | 2 +-
.../processor/AnyObjectCreateProcessor.java | 2 +-
.../processor/AnyObjectDeleteProcessor.java | 2 +-
.../AnyObjectDeprovisionProcessor.java | 2 +-
.../processor/AnyObjectProvisionProcessor.java | 2 +-
.../processor/AnyObjectUpdateProcessor.java | 2 +-
.../processor/GroupCreateInSyncProcessor.java | 2 +-
.../camel/processor/GroupCreateProcessor.java | 2 +-
.../camel/processor/GroupDeleteProcessor.java | 2 +-
.../processor/GroupDeprovisionProcessor.java | 2 +-
.../processor/GroupProvisionProcessor.java | 2 +-
.../camel/processor/GroupUpdateProcessor.java | 2 +-
.../processor/UserConfirmPwdResetProcessor.java | 2 +-
.../camel/processor/UserCreateProcessor.java | 2 +-
.../camel/processor/UserDeleteProcessor.java | 2 +-
.../processor/UserDeprovisionProcessor.java | 2 +-
.../camel/processor/UserProvisionProcessor.java | 2 +-
.../UserStatusPropagationProcessor.java | 2 +-
.../processor/UserUpdateInSyncProcessor.java | 2 +-
.../camel/processor/UserUpdateProcessor.java | 2 +-
.../main/resources/provisioningCamelContext.xml | 6 +-
fit/core-reference/pom.xml | 5 +-
.../fit/core/reference/TestAccountRule.java | 2 +-
.../fit/core/reference/TestPasswordRule.java | 2 +-
.../TestReconciliationFilterBuilder.java | 2 +-
.../fit/core/reference/TestSyncActions.java | 6 +-
.../fit/core/reference/TestSyncRule.java | 2 +-
.../src/main/resources/coreContext.xml | 2 +-
.../resources/jboss/domains/MasterDomain.xml | 4 +-
.../main/resources/jboss/domains/TwoDomain.xml | 4 +-
.../src/main/webapp/cacheStats.jsp | 2 +-
.../syncope/fit/core/AuthenticationITCase.java | 2 +-
.../apache/syncope/fit/core/SyncTaskITCase.java | 6 +-
.../org/apache/syncope/fit/core/UserITCase.java | 2 +-
fit/enduser-reference/pom.xml | 2 +-
354 files changed, 11814 insertions(+), 11729 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/archetype/pom.xml
----------------------------------------------------------------------
diff --git a/archetype/pom.xml b/archetype/pom.xml
index 93e2202..b295c81 100644
--- a/archetype/pom.xml
+++ b/archetype/pom.xml
@@ -153,7 +153,7 @@ under the License.
</excludes>
</resource>
<resource>
- <directory>../core/misc/src/main/resources</directory>
+ <directory>../core/spring/src/main/resources</directory>
<includes>
<include>security.properties</include>
</includes>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
index f108052..42701e0 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAnyLogic.java
@@ -37,10 +37,10 @@ import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.core.misc.utils.RealmUtils;
-import org.apache.syncope.core.misc.utils.TemplateUtils;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
index 37392a2..b74cd4f 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyObjectLogic.java
@@ -38,13 +38,13 @@ import org.apache.syncope.common.lib.types.AnyEntitlement;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.core.misc.EntitlementsHolder;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
index 697fb07..19129d1 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
@@ -29,7 +29,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.AnyTypeTO;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.EntitlementsHolder;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.DuplicateException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
index 5f2ef24..98e1032 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ConfigurationLogic.java
@@ -23,7 +23,7 @@ import java.lang.reflect.Method;
import java.util.List;
import org.apache.syncope.common.lib.to.AttrTO;
import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.persistence.api.content.ContentExporter;
import org.apache.syncope.core.persistence.api.dao.ConfDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index 0e9850b..344675c 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -41,7 +41,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.PatchOperation;
import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.utils.RealmUtils;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
@@ -49,8 +49,8 @@ import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.provisioning.api.LogicActions;
import org.springframework.beans.factory.annotation.Autowired;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
index 7b2842d..adb33d0 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
@@ -56,9 +56,9 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.Logger;
import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
-import org.apache.syncope.core.misc.spring.BeanUtils;
-import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
+import org.apache.syncope.core.spring.BeanUtils;
+import org.apache.syncope.core.provisioning.java.syncpull.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.syncpull.SyncJobDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
index 77ff7b5..63d1689 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.logic;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.provisioning.api.AuditManager;
import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
index 8825e67..da51c71 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
@@ -49,8 +49,8 @@ import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.provisioning.api.Connector;
import org.apache.syncope.core.provisioning.api.ConnectorFactory;
import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.misc.utils.MappingUtils;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
@@ -61,6 +61,7 @@ import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.MappingManager;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeUtil;
import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -104,7 +105,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
private ConnObjectUtils connObjectUtils;
@Autowired
- private MappingUtils mappingUtils;
+ private MappingManager mappingManager;
@Autowired
private ConnectorFactory connFactory;
@@ -228,12 +229,12 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
}
// 2. build connObjectKeyItem
- MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(init.getRight());
+ MappingItem connObjectKeyItem = MappingManagerImpl.getConnObjectKeyItem(init.getRight());
if (connObjectKeyItem == null) {
throw new NotFoundException(
"ConnObjectKey mapping for " + init.getMiddle() + " " + anyKey + " on resource '" + key + "'");
}
- String connObjectKeyValue = mappingUtils.getConnObjectKeyValue(any, init.getRight());
+ String connObjectKeyValue = mappingManager.getConnObjectKeyValue(any, init.getRight());
// 3. determine attributes to query
Set<MappingItem> linkinMappingItems = new HashSet<>();
@@ -246,10 +247,9 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
// 4. read from the underlying connector
Connector connector = connFactory.getConnector(init.getLeft());
- ConnectorObject connectorObject = connector.getObject(
- init.getRight().getObjectClass(),
+ ConnectorObject connectorObject = connector.getObject(init.getRight().getObjectClass(),
new Uid(connObjectKeyValue),
- MappingUtils.buildOperationOptions(mapItems));
+ MappingManagerImpl.buildOperationOptions(mapItems));
if (connectorObject == null) {
throw new NotFoundException(
"Object " + connObjectKeyValue + " with class " + init.getRight().getObjectClass()
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
index f72d6e9..5f2e632 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.logic;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
-import org.apache.syncope.core.misc.EntitlementsHolder;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.URI;
@@ -35,7 +35,7 @@ import org.apache.syncope.common.lib.info.SystemInfo;
import org.apache.syncope.common.lib.info.PlatformInfo;
import org.apache.syncope.common.lib.types.PolicyType;
import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.core.misc.security.PasswordGenerator;
+import org.apache.syncope.core.spring.security.PasswordGenerator;
import org.apache.syncope.core.persistence.api.ImplementationLookup;
import org.apache.syncope.core.persistence.api.ImplementationLookup.Type;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
index 63e7984..7d30e0b 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserLogic.java
@@ -52,8 +52,8 @@ import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.provisioning.api.LogicActions;
import org.springframework.beans.factory.annotation.Autowired;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
index c544f68..200fd13 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
@@ -42,11 +42,11 @@ import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
import org.apache.syncope.core.provisioning.api.notification.NotificationRecipientsProvider;
import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-import org.apache.syncope.core.provisioning.api.sync.SyncCorrelationRule;
-import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
+import org.apache.syncope.core.provisioning.api.syncpull.PushActions;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncActions;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncCorrelationRule;
+import org.apache.syncope.core.provisioning.java.syncpull.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.syncpull.SyncJobDelegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -54,7 +54,7 @@ import org.springframework.context.annotation.ClassPathScanningCandidateComponen
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
-import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder;
+import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
/**
* Cache class names for all implementations of Syncope interfaces found in classpath, for later usage.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java
index f2fdb1f..1c71737 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementAccessor.java
@@ -18,7 +18,7 @@
*/
package org.apache.syncope.core.logic.init;
-import org.apache.syncope.core.misc.EntitlementsHolder;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.springframework.beans.factory.annotation.Autowired;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java
index eb0482f..e49c487 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/EntitlementLoader.java
@@ -21,8 +21,8 @@ package org.apache.syncope.core.logic.init;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.syncope.core.misc.EntitlementsHolder;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.persistence.api.DomainsHolder;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
import org.springframework.beans.factory.annotation.Autowired;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobManagerImpl.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobManagerImpl.java
index 82134ed..2fa7b32 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobManagerImpl.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobManagerImpl.java
@@ -47,13 +47,13 @@ import org.apache.syncope.core.persistence.api.entity.task.Task;
import org.apache.syncope.core.provisioning.api.job.JobNamer;
import org.apache.syncope.core.logic.notification.NotificationJob;
import org.apache.syncope.core.logic.report.ReportJob;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
import org.apache.syncope.core.persistence.api.DomainsHolder;
import org.apache.syncope.core.provisioning.java.job.TaskJob;
-import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
+import org.apache.syncope.core.provisioning.java.syncpull.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.syncpull.SyncJobDelegate;
import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java
index e83a768..8fadf47 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java
@@ -26,7 +26,7 @@ import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.LoggerLevel;
import org.apache.syncope.common.lib.types.LoggerType;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.Logger;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
index 13acaab..9f96ccc 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java
@@ -30,8 +30,8 @@ import org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig;
import org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource;
import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender;
import org.apache.logging.log4j.core.config.LoggerConfig;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.java.AuditManagerImpl;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.persistence.api.DomainsHolder;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
import org.springframework.beans.factory.annotation.Autowired;
@@ -79,9 +79,10 @@ public class LoggerLoader implements SyncopeLoader {
ctx.getConfiguration().addAppender(appender);
}
- LoggerConfig logConf = new LoggerConfig(AuditManager.getDomainAuditLoggerName(entry.getKey()), null, false);
+ LoggerConfig logConf = new LoggerConfig(
+ AuditManagerImpl.getDomainAuditLoggerName(entry.getKey()), null, false);
logConf.addAppender(appender, Level.DEBUG, null);
- ctx.getConfiguration().addLogger(AuditManager.getDomainAuditLoggerName(entry.getKey()), logConf);
+ ctx.getConfiguration().addLogger(AuditManagerImpl.getDomainAuditLoggerName(entry.getKey()), logConf);
AuthContextUtils.execWithAuthContext(entry.getKey(), new AuthContextUtils.Executable<Void>() {
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
index 856fa13..10d1bf4 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
@@ -23,7 +23,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
index 7fea774..bd28aeb 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
@@ -18,7 +18,7 @@
*/
package org.apache.syncope.core.logic.notification;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.persistence.api.DomainsHolder;
import org.apache.syncope.core.provisioning.java.job.AbstractInterruptableJob;
import org.quartz.JobExecutionContext;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
index c09cca6..ea9b1da 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
@@ -25,12 +25,12 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.types.AuditElements;
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.utils.ExceptionUtils2;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
import org.apache.syncope.core.persistence.api.dao.TaskDAO;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.AuditManager;
import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/AuditReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/AuditReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/AuditReportlet.java
index 392c807..69caef9 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/AuditReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/AuditReportlet.java
@@ -26,9 +26,9 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.syncope.common.lib.report.AuditReportletConf;
import org.apache.syncope.common.lib.report.ReportletConf;
-import org.apache.syncope.core.misc.AuditEntry;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.provisioning.java.AuditEntry;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.DomainsHolder;
import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
import org.springframework.beans.factory.annotation.Autowired;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
index 413a665..1d890a6 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
@@ -34,7 +34,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
import org.apache.syncope.core.persistence.api.entity.user.UMembership;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
index 199c02d..37d69d7 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
@@ -35,15 +35,14 @@ import org.apache.syncope.common.lib.report.ReconciliationReportletConf;
import org.apache.syncope.common.lib.report.ReconciliationReportletConf.Feature;
import org.apache.syncope.common.lib.report.ReportletConf;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.utils.FormatUtils;
-import org.apache.syncope.core.misc.utils.MappingUtils;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
@@ -59,6 +58,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.provisioning.api.Connector;
import org.apache.syncope.core.provisioning.api.ConnectorFactory;
+import org.apache.syncope.core.provisioning.api.MappingManager;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeBuilder;
import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -91,10 +91,7 @@ public class ReconciliationReportlet extends AbstractReportlet {
private AnySearchDAO searchDAO;
@Autowired
- private VirSchemaDAO virSchemaDAO;
-
- @Autowired
- private MappingUtils mappingUtils;
+ private MappingManager mappingManager;
@Autowired
private ConnectorFactory connFactory;
@@ -274,17 +271,16 @@ public class ReconciliationReportlet extends AbstractReportlet {
AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
for (final ExternalResource resource : anyUtils.getAllResources(any)) {
Provision provision = resource.getProvision(any.getType());
- MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
+ MappingItem connObjectKeyItem = MappingManagerImpl.getConnObjectKeyItem(provision);
if (provision != null && connObjectKeyItem != null) {
// 1. build connObjectKeyValue
- final String connObjectKeyValue = mappingUtils.getConnObjectKeyValue(any, provision);
+ final String connObjectKeyValue = mappingManager.getConnObjectKeyValue(any, provision);
// 2. read from the underlying connector
Connector connector = connFactory.getConnector(resource);
- ConnectorObject connectorObject = connector.getObject(
- provision.getObjectClass(),
+ ConnectorObject connectorObject = connector.getObject(provision.getObjectClass(),
new Uid(connObjectKeyValue),
- MappingUtils.buildOperationOptions(provision.getMapping().getItems().iterator()));
+ MappingManagerImpl.buildOperationOptions(provision.getMapping().getItems().iterator()));
if (connectorObject == null) {
// 3. not found on resource?
@@ -295,7 +291,7 @@ public class ReconciliationReportlet extends AbstractReportlet {
} else {
// 4. found but misaligned?
Pair<String, Set<Attribute>> preparedAttrs =
- mappingUtils.prepareAttrs(any, null, false, null, provision);
+ mappingManager.prepareAttrs(any, null, false, null, provision);
preparedAttrs.getRight().add(AttributeBuilder.build(
Uid.NAME, preparedAttrs.getLeft()));
preparedAttrs.getRight().add(AttributeBuilder.build(
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
index 5786cfb..19c2b86 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
@@ -18,7 +18,7 @@
*/
package org.apache.syncope.core.logic.report;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.provisioning.java.job.AbstractInterruptableJob;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
index 1980858..e455778 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
@@ -33,8 +33,8 @@ import org.apache.commons.io.IOUtils;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.report.ReportletConf;
import org.apache.syncope.common.lib.types.ReportExecStatus;
-import org.apache.syncope.core.misc.utils.ExceptionUtils2;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.ImplementationLookup;
import org.apache.syncope.core.persistence.api.dao.ReportDAO;
import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java
index 37e896b..404d086 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/StaticReportlet.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.logic.report;
import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
import org.apache.syncope.common.lib.report.ReportletConf;
import org.apache.syncope.common.lib.report.StaticReportletConf;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
import org.springframework.util.StringUtils;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
index 1a447d8..724b8ac 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
@@ -36,8 +36,8 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
import org.apache.syncope.core.persistence.api.entity.user.UMembership;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/pom.xml
----------------------------------------------------------------------
diff --git a/core/misc/pom.xml b/core/misc/pom.xml
deleted file mode 100644
index 44e1df1..0000000
--- a/core/misc/pom.xml
+++ /dev/null
@@ -1,137 +0,0 @@
-<?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-core</artifactId>
- <version>2.0.0-SNAPSHOT</version>
- </parent>
-
- <name>Apache Syncope Core Misc</name>
- <description>Apache Syncope Core Misc</description>
- <groupId>org.apache.syncope.core</groupId>
- <artifactId>syncope-core-misc</artifactId>
- <packaging>jar</packaging>
-
- <properties>
- <rootpom.basedir>${basedir}/../..</rootpom.basedir>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-jexl3</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.module</groupId>
- <artifactId>jackson-module-afterburner</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jasypt</groupId>
- <artifactId>jasypt</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-expression</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-web</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.syncope.core</groupId>
- <artifactId>syncope-core-provisioning-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.syncope.common</groupId>
- <artifactId>syncope-common-rest-api</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <!-- TEST -->
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <version>${slf4j.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/AuditEntry.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditEntry.java b/core/misc/src/main/java/org/apache/syncope/core/misc/AuditEntry.java
deleted file mode 100644
index 3933bc3..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditEntry.java
+++ /dev/null
@@ -1,77 +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.core.misc;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-import org.apache.syncope.common.lib.types.AuditLoggerName;
-
-public class AuditEntry extends AbstractBaseBean {
-
- private static final long serialVersionUID = -2299082316063743582L;
-
- private final String who;
-
- private final AuditLoggerName logger;
-
- private final Object before;
-
- private final Object output;
-
- private final Object[] input;
-
- @JsonCreator
- public AuditEntry(
- @JsonProperty("who") final String who,
- @JsonProperty("logger") final AuditLoggerName logger,
- @JsonProperty("before") final Object before,
- @JsonProperty("output") final Object output,
- @JsonProperty("input") final Object[] input) {
-
- super();
-
- this.who = who;
- this.logger = logger;
- this.before = before;
- this.output = output;
- this.input = input;
- }
-
- public String getWho() {
- return who;
- }
-
- public AuditLoggerName getLogger() {
- return logger;
- }
-
- public Object getBefore() {
- return before;
- }
-
- public Object getOutput() {
- return output;
- }
-
- public Object[] getInput() {
- return input;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java b/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
deleted file mode 100644
index db243dc..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
+++ /dev/null
@@ -1,79 +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.core.misc;
-
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.AuditLoggerName;
-import org.apache.syncope.common.lib.types.LoggerLevel;
-import org.apache.syncope.common.lib.types.LoggerType;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
-import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-@Component
-public class AuditManager {
-
- @Autowired
- private LoggerDAO loggerDAO;
-
- public static String getDomainAuditLoggerName(final String domain) {
- return LoggerType.AUDIT.getPrefix() + "." + domain;
- }
-
- @Transactional(readOnly = true)
- public void audit(
- final AuditElements.EventCategoryType type,
- final String category,
- final String subcategory,
- final String event,
- final Result result,
- final Object before,
- final Object output,
- final Object... input) {
-
- Throwable throwable = null;
- if (output instanceof Throwable) {
- throwable = (Throwable) output;
- }
-
- AuditEntry auditEntry = new AuditEntry(
- AuthContextUtils.getUsername(),
- new AuditLoggerName(type, category, subcategory, event, result),
- before,
- throwable == null ? output : throwable.getMessage(),
- input);
-
- org.apache.syncope.core.persistence.api.entity.Logger syncopeLogger =
- loggerDAO.find(auditEntry.getLogger().toLoggerName());
- if (syncopeLogger != null && syncopeLogger.getLevel() == LoggerLevel.DEBUG) {
- Logger logger = LoggerFactory.getLogger(getDomainAuditLoggerName(AuthContextUtils.getDomain()));
- if (throwable == null) {
- logger.debug(POJOHelper.serialize(auditEntry));
- } else {
- logger.debug(POJOHelper.serialize(auditEntry), throwable);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/EntitlementsHolder.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/EntitlementsHolder.java b/core/misc/src/main/java/org/apache/syncope/core/misc/EntitlementsHolder.java
deleted file mode 100644
index 5a5d09a..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/EntitlementsHolder.java
+++ /dev/null
@@ -1,72 +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.core.misc;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.syncope.common.lib.types.AnyEntitlement;
-
-public final class EntitlementsHolder {
-
- private static final Object MONITOR = new Object();
-
- private static EntitlementsHolder INSTANCE;
-
- public static EntitlementsHolder getInstance() {
- synchronized (MONITOR) {
- if (INSTANCE == null) {
- INSTANCE = new EntitlementsHolder();
- }
- }
- return INSTANCE;
- }
-
- private final Set<String> values = Collections.synchronizedSet(new HashSet<String>());
-
- private EntitlementsHolder() {
- // private constructor for singleton
- }
-
- public void init(final Collection<String> values) {
- this.values.addAll(values);
- }
-
- public String getFor(final String anyTypeKey, final AnyEntitlement operation) {
- return anyTypeKey + "_" + operation.name();
- }
-
- public void addFor(final String anyType) {
- for (AnyEntitlement operation : AnyEntitlement.values()) {
- this.values.add(getFor(anyType, operation));
- }
- }
-
- public void removeFor(final String anyType) {
- for (AnyEntitlement operation : AnyEntitlement.values()) {
- this.values.remove(getFor(anyType, operation));
- }
- }
-
- public Set<String> getValues() {
- return Collections.unmodifiableSet(values);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/ClassFreeUberspect.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/ClassFreeUberspect.java b/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/ClassFreeUberspect.java
deleted file mode 100644
index d115ea9..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/ClassFreeUberspect.java
+++ /dev/null
@@ -1,41 +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.core.misc.jexl;
-
-import org.apache.commons.jexl3.internal.introspection.Uberspect;
-import org.apache.commons.jexl3.introspection.JexlMethod;
-import org.apache.commons.jexl3.introspection.JexlPropertyGet;
-
-class ClassFreeUberspect extends Uberspect {
-
- ClassFreeUberspect() {
- super(null, null);
- }
-
- @Override
- public JexlPropertyGet getPropertyGet(final Object obj, final Object identifier) {
- return "class".equals(identifier) ? null : super.getPropertyGet(obj, identifier);
- }
-
- @Override
- public JexlMethod getMethod(final Object obj, final String method, final Object... args) {
- return "getClass".equals(method) ? null : super.getMethod(obj, method, args);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/EmptyClassLoader.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/EmptyClassLoader.java b/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/EmptyClassLoader.java
deleted file mode 100644
index fe688f3..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/jexl/EmptyClassLoader.java
+++ /dev/null
@@ -1,36 +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.core.misc.jexl;
-
-/**
- * A class loader that will throw {@link ClassNotFoundException} for every class name.
- */
-class EmptyClassLoader extends ClassLoader {
-
- @Override
- public Class<?> loadClass(final String name) throws ClassNotFoundException {
- throw new ClassNotFoundException("This classloader won't attemp to load " + name);
- }
-
- @Override
- protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
- throw new ClassNotFoundException("This classloader won't attemp to load " + name);
- }
-
-}
[02/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/data/CamelRouteDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/data/CamelRouteDataBinderImpl.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/data/CamelRouteDataBinderImpl.java
index 59113af..5e7190a 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/data/CamelRouteDataBinderImpl.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/data/CamelRouteDataBinderImpl.java
@@ -19,7 +19,7 @@
package org.apache.syncope.core.provisioning.camel.data;
import org.apache.syncope.common.lib.to.CamelRouteTO;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
import org.apache.syncope.core.persistence.api.dao.CamelRouteDAO;
import org.apache.syncope.core.persistence.api.entity.CamelRoute;
import org.apache.syncope.core.provisioning.api.data.CamelRouteDataBinder;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
index 443e6aa..40afe61 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
index 189480b..f4ef0a5 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
@@ -23,7 +23,7 @@ import java.util.Set;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
index 5a6fe52..f03c9f5 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
@@ -25,7 +25,7 @@ import org.apache.commons.collections4.CollectionUtils;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
index 2a8a318..584aaa5 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectProvisionProcessor.java
@@ -24,7 +24,7 @@ import org.apache.camel.Processor;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
index a33296d..e222643 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.syncope.common.lib.patch.AnyObjectPatch;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.VirAttrHandler;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java
index fbe34d1..2fb035c 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java
@@ -29,7 +29,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.syncope.common.lib.to.AttrTO;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
index 1c08e8a..785bd0f 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
index 8603af2..30f9218 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeleteProcessor.java
@@ -26,7 +26,7 @@ import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
index dd50c45..1c59157 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupDeprovisionProcessor.java
@@ -25,7 +25,7 @@ import org.apache.commons.collections4.CollectionUtils;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
index def3ca3..ff1f43a 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupProvisionProcessor.java
@@ -24,7 +24,7 @@ import org.apache.camel.Processor;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
index 18aeac2..6cb270f 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.syncope.common.lib.patch.GroupPatch;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.VirAttrHandler;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
index 05b2e75..5b16404 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserConfirmPwdResetProcessor.java
@@ -23,7 +23,7 @@ import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
index 51b8e83..0800bd3 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserCreateProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
index 328b091..0356afe 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeleteProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
index 2438f17..a97a5b9 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserDeprovisionProcessor.java
@@ -25,7 +25,7 @@ import org.apache.commons.collections4.CollectionUtils;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
index 324d54c..fdb42cb 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserProvisionProcessor.java
@@ -31,7 +31,7 @@ import org.apache.syncope.common.lib.patch.UserPatch;
import org.apache.syncope.common.lib.types.PatchOperation;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
index 4877140..b8f09ab 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserStatusPropagationProcessor.java
@@ -27,7 +27,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.common.lib.types.StatusPatchType;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
index 6c1d3a3..7c4d6e0 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateInSyncProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
index 57233a6..c9a5fbf 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/UserUpdateProcessor.java
@@ -24,7 +24,7 @@ import org.apache.camel.Processor;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.VirAttrHandler;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml b/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
index d334d75..e0360c6 100644
--- a/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
@@ -25,15 +25,15 @@ under the License.
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
- <bean id="userRoutes" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="userRoutes" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${camel.directory}/userRoutes.xml"/>
<property name="fallback" value="classpath:userRoutes.xml"/>
</bean>
- <bean id="groupRoutes" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="groupRoutes" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${camel.directory}/groupRoutes.xml"/>
<property name="fallback" value="classpath:groupRoutes.xml"/>
</bean>
- <bean id="anyObjectRoutes" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="anyObjectRoutes" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${camel.directory}/anyObjectRoutes.xml"/>
<property name="fallback" value="classpath:anyObjectRoutes.xml"/>
</bean>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 985817b..78a7912 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -340,7 +340,7 @@ under the License.
<filtering>true</filtering>
</resource>
<resource>
- <directory>${basedir}/../../core/misc/src/main/resources</directory>
+ <directory>${basedir}/../../core/spring/src/main/resources</directory>
<includes>
<include>security.properties</include>
</includes>
@@ -784,9 +784,8 @@ under the License.
</excludes>
</resource>
<resource>
- <directory>${basedir}/../../core/misc/target/classes</directory>
+ <directory>${basedir}/../../core/spring/target/classes</directory>
<excludes>
- <exclude>utilsContext.xml</exclude>
<exclude>securityContext.xml</exclude>
</excludes>
</resource>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java
index 2b67f37..d3039d0 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java
@@ -19,7 +19,7 @@
package org.apache.syncope.fit.core.reference;
import org.apache.syncope.common.lib.policy.AccountRuleConf;
-import org.apache.syncope.core.misc.policy.AccountPolicyException;
+import org.apache.syncope.core.provisioning.api.utils.policy.AccountPolicyException;
import org.apache.syncope.core.persistence.api.dao.AccountRule;
import org.apache.syncope.core.persistence.api.dao.AccountRuleConfClass;
import org.apache.syncope.core.persistence.api.entity.user.User;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java
index ea41274..2ca008b 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java
@@ -19,7 +19,7 @@
package org.apache.syncope.fit.core.reference;
import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.core.misc.policy.PasswordPolicyException;
+import org.apache.syncope.core.provisioning.api.utils.policy.PasswordPolicyException;
import org.apache.syncope.core.persistence.api.dao.PasswordRule;
import org.apache.syncope.core.persistence.api.dao.PasswordRuleConfClass;
import org.apache.syncope.core.persistence.api.entity.user.User;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java
index f6b5c2d..1603083 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java
@@ -18,7 +18,7 @@
*/
package org.apache.syncope.fit.core.reference;
-import org.apache.syncope.core.provisioning.java.sync.DefaultReconciliationFilterBuilder;
+import org.apache.syncope.core.provisioning.java.syncpull.DefaultReconciliationFilterBuilder;
import org.identityconnectors.framework.common.objects.AttributeBuilder;
import org.identityconnectors.framework.common.objects.filter.Filter;
import org.identityconnectors.framework.common.objects.filter.FilterBuilder;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java
index dbe1bd1..19b172f 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncActions.java
@@ -25,9 +25,9 @@ import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.AttrTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.core.provisioning.api.sync.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.java.sync.DefaultSyncActions;
+import org.apache.syncope.core.provisioning.api.syncpull.IgnoreProvisionException;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.java.syncpull.DefaultSyncActions;
import org.identityconnectors.framework.common.objects.SyncDelta;
import org.quartz.JobExecutionException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncRule.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncRule.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncRule.java
index 5cb8b10..5a1624a 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncRule.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSyncRule.java
@@ -20,7 +20,7 @@ package org.apache.syncope.fit.core.reference;
import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.provisioning.api.sync.SyncCorrelationRule;
+import org.apache.syncope.core.provisioning.api.syncpull.SyncCorrelationRule;
import org.identityconnectors.framework.common.objects.ConnectorObject;
/**
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/resources/coreContext.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/coreContext.xml b/fit/core-reference/src/main/resources/coreContext.xml
index ecdb57d..03f7fc9 100644
--- a/fit/core-reference/src/main/resources/coreContext.xml
+++ b/fit/core-reference/src/main/resources/coreContext.xml
@@ -54,6 +54,6 @@ under the License.
</property>
</bean>
- <bean class="org.apache.syncope.core.misc.spring.ApplicationContextProvider"/>
+ <bean class="org.apache.syncope.core.spring.ApplicationContextProvider"/>
</beans>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/resources/jboss/domains/MasterDomain.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/jboss/domains/MasterDomain.xml b/fit/core-reference/src/main/resources/jboss/domains/MasterDomain.xml
index e11e928..afd18ad 100644
--- a/fit/core-reference/src/main/resources/jboss/domains/MasterDomain.xml
+++ b/fit/core-reference/src/main/resources/jboss/domains/MasterDomain.xml
@@ -28,11 +28,11 @@ under the License.
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
- <bean id="MasterContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="MasterContentXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${content.directory}/domains/MasterContent.xml"/>
<property name="fallback" value="classpath:domains/MasterContent.xml"/>
</bean>
- <bean id="MasterProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="MasterProperties" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${content.directory}/domains/Master.properties"/>
<property name="fallback" value="classpath:domains/Master.properties"/>
</bean>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/resources/jboss/domains/TwoDomain.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/jboss/domains/TwoDomain.xml b/fit/core-reference/src/main/resources/jboss/domains/TwoDomain.xml
index 205553f..6d9d1bb 100644
--- a/fit/core-reference/src/main/resources/jboss/domains/TwoDomain.xml
+++ b/fit/core-reference/src/main/resources/jboss/domains/TwoDomain.xml
@@ -28,11 +28,11 @@ under the License.
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
- <bean id="TwoContentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="TwoContentXML" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${content.directory}/domains/TwoContent.xml"/>
<property name="fallback" value="classpath:domains/TwoContent.xml"/>
</bean>
- <bean id="TwoProperties" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="TwoProperties" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${content.directory}/domains/Two.properties"/>
<property name="fallback" value="classpath:domains/Two.properties"/>
</bean>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/main/webapp/cacheStats.jsp
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/webapp/cacheStats.jsp b/fit/core-reference/src/main/webapp/cacheStats.jsp
index 16063db..b599365 100644
--- a/fit/core-reference/src/main/webapp/cacheStats.jsp
+++ b/fit/core-reference/src/main/webapp/cacheStats.jsp
@@ -21,7 +21,7 @@ under the License.
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<%@page import="org.springframework.beans.factory.support.DefaultListableBeanFactory"%>
<%@page import="org.apache.syncope.common.lib.SyncopeConstants"%>
-<%@page import="org.apache.syncope.core.misc.spring.ApplicationContextProvider"%>
+<%@page import="org.apache.syncope.core.spring.ApplicationContextProvider"%>
<%@page import="org.apache.commons.lang3.time.FastDateFormat"%>
<%@page import="java.util.Date"%>
<%@page import="org.apache.openjpa.datacache.CacheStatisticsImpl"%>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
index d32350c..43c9938 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
@@ -72,7 +72,7 @@ import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
import org.apache.syncope.common.rest.api.service.AnyObjectService;
import org.apache.syncope.common.rest.api.service.SchemaService;
import org.apache.syncope.common.rest.api.service.UserService;
-import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.spring.security.Encryptor;
import org.apache.syncope.fit.AbstractITCase;
import org.junit.Assume;
import org.junit.FixMethodOrder;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
index 3498b86..87bec8b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SyncTaskITCase.java
@@ -69,9 +69,9 @@ import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
import org.apache.syncope.common.rest.api.beans.TaskQuery;
import org.apache.syncope.common.rest.api.service.TaskService;
-import org.apache.syncope.core.misc.security.Encryptor;
-import org.apache.syncope.core.provisioning.java.sync.DBPasswordSyncActions;
-import org.apache.syncope.core.provisioning.java.sync.LDAPPasswordSyncActions;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.provisioning.java.syncpull.DBPasswordSyncActions;
+import org.apache.syncope.core.provisioning.java.syncpull.LDAPPasswordSyncActions;
import org.apache.syncope.fit.core.reference.PrefixMappingItemTransformer;
import org.apache.syncope.fit.core.reference.TestReconciliationFilterBuilder;
import org.apache.syncope.fit.core.reference.TestSyncActions;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
index 1cccb74..ff39d5f 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
@@ -93,7 +93,7 @@ import org.apache.syncope.common.rest.api.beans.TaskQuery;
import org.apache.syncope.common.rest.api.service.ResourceService;
import org.apache.syncope.common.rest.api.service.UserSelfService;
import org.apache.syncope.common.rest.api.service.UserService;
-import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.spring.security.Encryptor;
import org.apache.syncope.core.provisioning.java.propagation.DBPasswordPropagationActions;
import org.apache.syncope.core.provisioning.java.propagation.LDAPPasswordPropagationActions;
import org.apache.syncope.fit.core.reference.DoubleValueLogicActions;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/fit/enduser-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/enduser-reference/pom.xml b/fit/enduser-reference/pom.xml
index 707e4f5..48dd75f 100644
--- a/fit/enduser-reference/pom.xml
+++ b/fit/enduser-reference/pom.xml
@@ -324,7 +324,7 @@ under the License.
</excludes>
</resource>
<resource>
- <directory>${basedir}/../../core/misc/target/classes</directory>
+ <directory>${basedir}/../../core/spring/target/classes</directory>
<excludes>
<exclude>securityContext.xml</exclude>
</excludes>
[09/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
new file mode 100644
index 0000000..7c6c38a
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
@@ -0,0 +1,241 @@
+/*
+ * 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.core.provisioning.java.jexl;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.jexl3.JexlBuilder;
+import org.apache.commons.jexl3.JexlContext;
+import org.apache.commons.jexl3.JexlEngine;
+import org.apache.commons.jexl3.JexlException;
+import org.apache.commons.jexl3.JexlExpression;
+import org.apache.commons.jexl3.JxltEngine;
+import org.apache.commons.jexl3.MapContext;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.provisioning.api.DerAttrHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * JEXL <a href="http://commons.apache.org/jexl/reference/index.html">reference</a> is available.
+ */
+public final class JexlUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(JexlUtils.class);
+
+ private static final String[] IGNORE_FIELDS = { "password", "clearPassword", "serialVersionUID", "class" };
+
+ private static JexlEngine JEXL_ENGINE;
+
+ private static JexlEngine getEngine() {
+ synchronized (LOG) {
+ if (JEXL_ENGINE == null) {
+ JEXL_ENGINE = new JexlBuilder().
+ uberspect(new ClassFreeUberspect()).
+ loader(new EmptyClassLoader()).
+ cache(512).
+ silent(false).
+ strict(false).
+ create();
+ }
+ }
+
+ return JEXL_ENGINE;
+ }
+
+ public static JxltEngine newJxltEngine() {
+ return getEngine().createJxltEngine(false);
+ }
+
+ public static boolean isExpressionValid(final String expression) {
+ boolean result;
+ try {
+ getEngine().createExpression(expression);
+ result = true;
+ } catch (JexlException e) {
+ LOG.error("Invalid jexl expression: " + expression, e);
+ result = false;
+ }
+
+ return result;
+ }
+
+ public static String evaluate(final String expression, final JexlContext jexlContext) {
+ String result = StringUtils.EMPTY;
+
+ if (StringUtils.isNotBlank(expression) && jexlContext != null) {
+ try {
+ JexlExpression jexlExpression = getEngine().createExpression(expression);
+ Object evaluated = jexlExpression.evaluate(jexlContext);
+ if (evaluated != null) {
+ result = evaluated.toString();
+ }
+ } catch (Exception e) {
+ LOG.error("Error while evaluating JEXL expression: " + expression, e);
+ }
+ } else {
+ LOG.debug("Expression not provided or invalid context");
+ }
+
+ return result;
+ }
+
+ public static JexlContext addFieldsToContext(final Object object, final JexlContext jexlContext) {
+ JexlContext context = jexlContext == null ? new MapContext() : jexlContext;
+
+ try {
+ for (PropertyDescriptor desc : Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors()) {
+ Class<?> type = desc.getPropertyType();
+ String fieldName = desc.getName();
+
+ if ((!fieldName.startsWith("pc"))
+ && (!ArrayUtils.contains(IGNORE_FIELDS, fieldName))
+ && (!Iterable.class.isAssignableFrom(type))
+ && (!type.isArray())) {
+
+ try {
+ Object fieldValue;
+ if (desc.getReadMethod() == null) {
+ final Field field = object.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ fieldValue = field.get(object);
+ } else {
+ fieldValue = desc.getReadMethod().invoke(object);
+ }
+
+ context.set(fieldName, fieldValue == null
+ ? StringUtils.EMPTY
+ : (type.equals(Date.class)
+ ? FormatUtils.format((Date) fieldValue, false)
+ : fieldValue));
+
+ LOG.debug("Add field {} with value {}", fieldName, fieldValue);
+ } catch (Exception iae) {
+ LOG.error("Reading '{}' value error", fieldName, iae);
+ }
+ }
+ }
+ } catch (IntrospectionException ie) {
+ LOG.error("Reading class attributes error", ie);
+ }
+
+ if (object instanceof Any) {
+ Any<?> any = (Any<?>) object;
+ if (any.getRealm() != null) {
+ context.set("realm", any.getRealm().getName());
+ }
+ }
+
+ return context;
+ }
+
+ public static void addPlainAttrsToContext(
+ final Collection<? extends PlainAttr<?>> attrs, final JexlContext jexlContext) {
+
+ for (PlainAttr<?> attr : attrs) {
+ if (attr.getSchema() != null) {
+ List<String> attrValues = attr.getValuesAsStrings();
+ String expressionValue = attrValues.isEmpty()
+ ? StringUtils.EMPTY
+ : attrValues.get(0);
+
+ LOG.debug("Add attribute {} with value {}", attr.getSchema().getKey(), expressionValue);
+
+ jexlContext.set(attr.getSchema().getKey(), expressionValue);
+ }
+ }
+ }
+
+ public static void addDerAttrsToContext(final Any<?> any, final JexlContext jexlContext) {
+ Map<DerSchema, String> derAttrs =
+ ApplicationContextProvider.getBeanFactory().getBean(DerAttrHandler.class).getValues(any);
+
+ for (Map.Entry<DerSchema, String> entry : derAttrs.entrySet()) {
+ jexlContext.set(entry.getKey().getKey(), entry.getValue());
+ }
+ }
+
+ public static boolean evaluateMandatoryCondition(final String mandatoryCondition, final Any<?> any) {
+ JexlContext jexlContext = new MapContext();
+ addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
+ addDerAttrsToContext(any, jexlContext);
+
+ return Boolean.parseBoolean(evaluate(mandatoryCondition, jexlContext));
+ }
+
+ public static String evaluate(final String expression, final AnyTO anyTO) {
+ final JexlContext context = new MapContext();
+
+ addFieldsToContext(anyTO, context);
+
+ for (AttrTO plainAttr : anyTO.getPlainAttrs()) {
+ List<String> values = plainAttr.getValues();
+ String expressionValue = values.isEmpty()
+ ? StringUtils.EMPTY
+ : values.get(0);
+
+ LOG.debug("Add plain attribute {} with value {}", plainAttr.getSchema(), expressionValue);
+
+ context.set(plainAttr.getSchema(), expressionValue);
+ }
+ for (AttrTO derAttr : anyTO.getDerAttrs()) {
+ List<String> values = derAttr.getValues();
+ String expressionValue = values.isEmpty()
+ ? StringUtils.EMPTY
+ : values.get(0);
+
+ LOG.debug("Add derived attribute {} with value {}", derAttr.getSchema(), expressionValue);
+
+ context.set(derAttr.getSchema(), expressionValue);
+ }
+ for (AttrTO virAttr : anyTO.getVirAttrs()) {
+ List<String> values = virAttr.getValues();
+ String expressionValue = values.isEmpty()
+ ? StringUtils.EMPTY
+ : values.get(0);
+
+ LOG.debug("Add virtual attribute {} with value {}", virAttr.getSchema(), expressionValue);
+
+ context.set(virAttr.getSchema(), expressionValue);
+ }
+
+ // Evaluate expression using the context prepared before
+ return evaluate(expression, context);
+ }
+
+ /**
+ * Private default constructor, for static-only classes.
+ */
+ private JexlUtils() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
index bd550b5..3b22728 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.provisioning.java.job;
import java.util.Date;
import java.util.concurrent.atomic.AtomicReference;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
import org.apache.syncope.core.provisioning.api.job.JobManager;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.InterruptableJob;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
index ea6a525..aec8853 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
@@ -20,13 +20,13 @@ package org.apache.syncope.core.provisioning.java.job;
import java.util.Date;
import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.utils.ExceptionUtils2;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
import org.apache.syncope.core.persistence.api.dao.TaskDAO;
import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.AuditManager;
import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
import org.quartz.JobExecutionException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
index 4692e88..50067dc 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
@@ -19,8 +19,8 @@
package org.apache.syncope.core.provisioning.java.job;
import org.apache.commons.lang3.ClassUtils;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
index 74dc39f..b119bd1 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
@@ -37,7 +37,7 @@ import org.apache.syncope.common.lib.types.IntMappingType;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
import org.apache.syncope.core.persistence.api.dao.ConfDAO;
import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
@@ -54,8 +54,8 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 7d7edc1..2c2e9ea 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -44,11 +44,10 @@ import org.apache.syncope.core.provisioning.api.TimeoutException;
import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.misc.utils.ExceptionUtils2;
-import org.apache.syncope.core.misc.utils.MappingUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
import org.apache.syncope.core.persistence.api.entity.Any;
@@ -59,6 +58,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.AuditManager;
import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
@@ -574,11 +574,10 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
ConnectorObject obj = null;
try {
- obj = connector.getObject(
- new ObjectClass(task.getObjectClassName()),
+ obj = connector.getObject(new ObjectClass(task.getObjectClassName()),
new Uid(connObjectKey),
- MappingUtils.buildOperationOptions(IteratorUtils.chainedIterator(
- MappingUtils.getPropagationMappingItems(provision).iterator(),
+ MappingManagerImpl.buildOperationOptions(IteratorUtils.chainedIterator(MappingManagerImpl.
+ getPropagationMappingItems(provision).iterator(),
linkingMappingItems.iterator())));
for (MappingItem item : linkingMappingItems) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
index 55c4a0b..635c015 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
@@ -28,7 +28,7 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
import org.identityconnectors.framework.common.objects.ConnectorObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
index 9a7214c..6aa076e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
@@ -30,7 +30,7 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.identityconnectors.framework.common.objects.Attribute;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
index 5ea6616..15ddb30 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
@@ -36,7 +36,7 @@ import javax.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
index f816228..5f66a2f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
@@ -43,9 +43,9 @@ import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
import org.apache.syncope.core.persistence.api.dao.AnyDAO;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
@@ -58,6 +58,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.MappingManager;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeBuilder;
import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -108,7 +109,7 @@ public class PropagationManagerImpl implements PropagationManager {
protected ConnObjectUtils connObjectUtils;
@Autowired
- protected MappingUtils mappingUtils;
+ protected MappingManager mappingManager;
@Autowired
protected AnyUtilsFactory anyUtilsFactory;
@@ -367,7 +368,7 @@ public class PropagationManagerImpl implements PropagationManager {
Provision provision = resource == null ? null : resource.getProvision(any.getType());
List<MappingItem> mappingItems = provision == null
? Collections.<MappingItem>emptyList()
- : MappingUtils.getPropagationMappingItems(provision);
+ : MappingManagerImpl.getPropagationMappingItems(provision);
if (resource == null) {
LOG.error("Invalid resource name specified: {}, ignoring...", entry.getKey());
@@ -391,7 +392,7 @@ public class PropagationManagerImpl implements PropagationManager {
task.setOldConnObjectKey(propByRes.getOldConnObjectKey(resource.getKey()));
Pair<String, Set<Attribute>> preparedAttrs =
- mappingUtils.prepareAttrs(any, password, changePwd, enable, provision);
+ mappingManager.prepareAttrs(any, password, changePwd, enable, provision);
task.setConnObjectKey(preparedAttrs.getKey());
// Check if any of mandatory attributes (in the mapping) is missing or not received any value:
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
index 4e6b875..1c0aa9b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
@@ -19,8 +19,8 @@
package org.apache.syncope.core.provisioning.java.propagation;
import java.util.Collection;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
deleted file mode 100644
index d6f4c15..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
+++ /dev/null
@@ -1,434 +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.core.provisioning.java.sync;
-
-import java.lang.reflect.ParameterizedType;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import javax.annotation.Resource;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.java.job.AbstractSchedTaskJobDelegate;
-import org.apache.syncope.core.provisioning.java.job.TaskJob;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public abstract class AbstractProvisioningJobDelegate<T extends ProvisioningTask>
- extends AbstractSchedTaskJobDelegate {
-
- @Resource(name = "adminUser")
- protected String adminUser;
-
- /**
- * ConnInstance loader.
- */
- @Autowired
- protected ConnectorFactory connFactory;
-
- @Autowired
- protected AnyTypeDAO anyTypeDAO;
-
- /**
- * Resource DAO.
- */
- @Autowired
- protected ExternalResourceDAO resourceDAO;
-
- /**
- * Policy DAO.
- */
- @Autowired
- protected PolicyDAO policyDAO;
-
- /**
- * Create a textual report of the synchronization, based on the trace level.
- *
- * @param provResults Sync results
- * @param syncTraceLevel Sync trace level
- * @param dryRun dry run?
- * @return report as string
- */
- protected String createReport(final Collection<ProvisioningReport> provResults, final TraceLevel syncTraceLevel,
- final boolean dryRun) {
-
- if (syncTraceLevel == TraceLevel.NONE) {
- return null;
- }
-
- StringBuilder report = new StringBuilder();
-
- if (dryRun) {
- report.append("==>Dry run only, no modifications were made<==\n\n");
- }
-
- List<ProvisioningReport> uSuccCreate = new ArrayList<>();
- List<ProvisioningReport> uFailCreate = new ArrayList<>();
- List<ProvisioningReport> uSuccUpdate = new ArrayList<>();
- List<ProvisioningReport> uFailUpdate = new ArrayList<>();
- List<ProvisioningReport> uSuccDelete = new ArrayList<>();
- List<ProvisioningReport> uFailDelete = new ArrayList<>();
- List<ProvisioningReport> uSuccNone = new ArrayList<>();
- List<ProvisioningReport> uIgnore = new ArrayList<>();
- List<ProvisioningReport> gSuccCreate = new ArrayList<>();
- List<ProvisioningReport> gFailCreate = new ArrayList<>();
- List<ProvisioningReport> gSuccUpdate = new ArrayList<>();
- List<ProvisioningReport> gFailUpdate = new ArrayList<>();
- List<ProvisioningReport> gSuccDelete = new ArrayList<>();
- List<ProvisioningReport> gFailDelete = new ArrayList<>();
- List<ProvisioningReport> gSuccNone = new ArrayList<>();
- List<ProvisioningReport> gIgnore = new ArrayList<>();
- List<ProvisioningReport> aSuccCreate = new ArrayList<>();
- List<ProvisioningReport> aFailCreate = new ArrayList<>();
- List<ProvisioningReport> aSuccUpdate = new ArrayList<>();
- List<ProvisioningReport> aFailUpdate = new ArrayList<>();
- List<ProvisioningReport> aSuccDelete = new ArrayList<>();
- List<ProvisioningReport> aFailDelete = new ArrayList<>();
- List<ProvisioningReport> aSuccNone = new ArrayList<>();
- List<ProvisioningReport> aIgnore = new ArrayList<>();
-
- for (ProvisioningReport provResult : provResults) {
- AnyType anyType = anyTypeDAO.find(provResult.getAnyType());
-
- switch (provResult.getStatus()) {
- case SUCCESS:
- switch (provResult.getOperation()) {
- case CREATE:
- switch (anyType.getKind()) {
- case USER:
- uSuccCreate.add(provResult);
- break;
-
- case GROUP:
- gSuccCreate.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aSuccCreate.add(provResult);
- }
- break;
-
- case UPDATE:
- switch (anyType.getKind()) {
- case USER:
- uSuccUpdate.add(provResult);
- break;
-
- case GROUP:
- gSuccUpdate.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aSuccUpdate.add(provResult);
- }
- break;
-
- case DELETE:
- switch (anyType.getKind()) {
- case USER:
- uSuccDelete.add(provResult);
- break;
-
- case GROUP:
- gSuccDelete.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aSuccDelete.add(provResult);
- }
- break;
-
- case NONE:
- switch (anyType.getKind()) {
- case USER:
- uSuccNone.add(provResult);
- break;
-
- case GROUP:
- gSuccNone.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aSuccNone.add(provResult);
- }
- break;
-
- default:
- }
- break;
-
- case FAILURE:
- switch (provResult.getOperation()) {
- case CREATE:
- switch (anyType.getKind()) {
- case USER:
- uFailCreate.add(provResult);
- break;
-
- case GROUP:
- gFailCreate.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aFailCreate.add(provResult);
- }
- break;
-
- case UPDATE:
- switch (anyType.getKind()) {
- case USER:
- uFailUpdate.add(provResult);
- break;
-
- case GROUP:
- gFailUpdate.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aFailUpdate.add(provResult);
- }
- break;
-
- case DELETE:
- switch (anyType.getKind()) {
- case USER:
- uFailDelete.add(provResult);
- break;
-
- case GROUP:
- gFailDelete.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aFailDelete.add(provResult);
- }
- break;
-
- default:
- }
- break;
-
- case IGNORE:
- switch (anyType.getKind()) {
- case USER:
- uIgnore.add(provResult);
- break;
-
- case GROUP:
- gIgnore.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aIgnore.add(provResult);
- }
- break;
-
- default:
- }
- }
-
- // Summary, also to be included for FAILURE and ALL, so create it anyway.
- report.append("Users ").
- append("[created/failures]: ").append(uSuccCreate.size()).append('/').append(uFailCreate.size()).
- append(' ').
- append("[updated/failures]: ").append(uSuccUpdate.size()).append('/').append(uFailUpdate.size()).
- append(' ').
- append("[deleted/failures]: ").append(uSuccDelete.size()).append('/').append(uFailDelete.size()).
- append(' ').
- append("[no operation/ignored]: ").append(uSuccNone.size()).append('/').append(uIgnore.size()).
- append('\n');
- report.append("Groups ").
- append("[created/failures]: ").append(gSuccCreate.size()).append('/').append(gFailCreate.size()).
- append(' ').
- append("[updated/failures]: ").append(gSuccUpdate.size()).append('/').append(gFailUpdate.size()).
- append(' ').
- append("[deleted/failures]: ").append(gSuccDelete.size()).append('/').append(gFailDelete.size()).
- append(' ').
- append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size()).
- append('\n');
- report.append("Any objects ").
- append("[created/failures]: ").append(aSuccCreate.size()).append('/').append(aFailCreate.size()).
- append(' ').
- append("[updated/failures]: ").append(aSuccUpdate.size()).append('/').append(aFailUpdate.size()).
- append(' ').
- append("[deleted/failures]: ").append(aSuccDelete.size()).append('/').append(aFailDelete.size()).
- append(' ').
- append("[no operation/ignored]: ").append(aSuccNone.size()).append('/').append(aIgnore.size());
-
- // Failures
- if (syncTraceLevel == TraceLevel.FAILURES || syncTraceLevel == TraceLevel.ALL) {
- if (!uFailCreate.isEmpty()) {
- report.append("\n\nUsers failed to create: ");
- report.append(ProvisioningReport.produceReport(uFailCreate, syncTraceLevel));
- }
- if (!uFailUpdate.isEmpty()) {
- report.append("\nUsers failed to update: ");
- report.append(ProvisioningReport.produceReport(uFailUpdate, syncTraceLevel));
- }
- if (!uFailDelete.isEmpty()) {
- report.append("\nUsers failed to delete: ");
- report.append(ProvisioningReport.produceReport(uFailDelete, syncTraceLevel));
- }
-
- if (!gFailCreate.isEmpty()) {
- report.append("\n\nGroups failed to create: ");
- report.append(ProvisioningReport.produceReport(gFailCreate, syncTraceLevel));
- }
- if (!gFailUpdate.isEmpty()) {
- report.append("\nGroups failed to update: ");
- report.append(ProvisioningReport.produceReport(gFailUpdate, syncTraceLevel));
- }
- if (!gFailDelete.isEmpty()) {
- report.append("\nGroups failed to delete: ");
- report.append(ProvisioningReport.produceReport(gFailDelete, syncTraceLevel));
- }
-
- if (!aFailCreate.isEmpty()) {
- report.append("\nAny objects failed to create: ");
- report.append(ProvisioningReport.produceReport(aFailCreate, syncTraceLevel));
- }
- if (!aFailUpdate.isEmpty()) {
- report.append("\nAny objects failed to update: ");
- report.append(ProvisioningReport.produceReport(aFailUpdate, syncTraceLevel));
- }
- if (!aFailDelete.isEmpty()) {
- report.append("\nAny objects failed to delete: ");
- report.append(ProvisioningReport.produceReport(aFailDelete, syncTraceLevel));
- }
- }
-
- // Succeeded, only if on 'ALL' level
- if (syncTraceLevel == TraceLevel.ALL) {
- report.append("\n\nUsers created:\n").
- append(ProvisioningReport.produceReport(uSuccCreate, syncTraceLevel)).
- append("\nUsers updated:\n").
- append(ProvisioningReport.produceReport(uSuccUpdate, syncTraceLevel)).
- append("\nUsers deleted:\n").
- append(ProvisioningReport.produceReport(uSuccDelete, syncTraceLevel)).
- append("\nUsers no operation:\n").
- append(ProvisioningReport.produceReport(uSuccNone, syncTraceLevel)).
- append("\nUsers ignored:\n").
- append(ProvisioningReport.produceReport(uIgnore, syncTraceLevel));
- report.append("\n\nGroups created:\n").
- append(ProvisioningReport.produceReport(gSuccCreate, syncTraceLevel)).
- append("\nGroups updated:\n").
- append(ProvisioningReport.produceReport(gSuccUpdate, syncTraceLevel)).
- append("\nGroups deleted:\n").
- append(ProvisioningReport.produceReport(gSuccDelete, syncTraceLevel)).
- append("\nGroups no operation:\n").
- append(ProvisioningReport.produceReport(gSuccNone, syncTraceLevel)).
- append("\nGroups ignored:\n").
- append(ProvisioningReport.produceReport(gSuccNone, syncTraceLevel));
- report.append("\n\nAny objects created:\n").
- append(ProvisioningReport.produceReport(aSuccCreate, syncTraceLevel)).
- append("\nAny objects updated:\n").
- append(ProvisioningReport.produceReport(aSuccUpdate, syncTraceLevel)).
- append("\nAny objects deleted:\n").
- append(ProvisioningReport.produceReport(aSuccDelete, syncTraceLevel)).
- append("\nAny objects no operation:\n").
- append(ProvisioningReport.produceReport(aSuccNone, syncTraceLevel)).
- append("\nAny objects ignored:\n").
- append(ProvisioningReport.produceReport(aSuccNone, syncTraceLevel));
- }
-
- return report.toString();
- }
-
- @Override
- protected String doExecute(final boolean dryRun) throws JobExecutionException {
- try {
- Class<T> clazz = getTaskClassReference();
- if (!clazz.isAssignableFrom(task.getClass())) {
- throw new JobExecutionException("Task " + task.getKey() + " isn't a ProvisioningTask");
- }
-
- T provisioningTask = clazz.cast(task);
-
- Connector connector;
- try {
- connector = connFactory.getConnector(provisioningTask.getResource());
- } catch (Exception e) {
- String msg = String.format("Connector instance bean for resource %s and connInstance %s not found",
- provisioningTask.getResource(), provisioningTask.getResource().getConnector());
- throw new JobExecutionException(msg, e);
- }
-
- boolean noMapping = true;
- for (Provision provision : provisioningTask.getResource().getProvisions()) {
- Mapping mapping = provision.getMapping();
- if (mapping != null) {
- noMapping = false;
- if (mapping.getConnObjectKeyItem() == null) {
- throw new JobExecutionException(
- "Invalid ConnObjectKey mapping for provision " + provision);
- }
- }
- }
- if (noMapping) {
- return "No mapping configured for both users and groups: aborting...";
- }
-
- return doExecuteProvisioning(
- provisioningTask,
- connector,
- dryRun);
- } catch (Throwable t) {
- LOG.error("While executing provisioning job {}", getClass().getName(), t);
- throw t;
- }
- }
-
- protected abstract String doExecuteProvisioning(
- final T task,
- final Connector connector,
- final boolean dryRun) throws JobExecutionException;
-
- @Override
- protected boolean hasToBeRegistered(final TaskExec execution) {
- final ProvisioningTask provTask = (ProvisioningTask) task;
-
- // True if either failed and failures have to be registered, or if ALL has to be registered.
- return (TaskJob.Status.valueOf(execution.getStatus()) == TaskJob.Status.FAILURE
- && provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
- || provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.SUMMARY.ordinal();
- }
-
- @SuppressWarnings("unchecked")
- private Class<T> getTaskClassReference() {
- return (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
deleted file mode 100644
index f88982f..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
+++ /dev/null
@@ -1,434 +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.core.provisioning.java.sync;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.apache.commons.collections4.IteratorUtils;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.StringPatchItem;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.MatchingRule;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.TimeoutException;
-import org.apache.syncope.core.provisioning.api.sync.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.Uid;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions>
- implements SyncopePushResultHandler {
-
- @Autowired
- protected MappingUtils mappingUtils;
-
- protected abstract String getName(Any<?> any);
-
- protected void deprovision(final Any<?> any) {
- AnyTO before = getAnyTO(any.getKey());
-
- List<String> noPropResources = new ArrayList<>(before.getResources());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- taskExecutor.execute(propagationManager.getDeleteTasks(
- any.getType().getKind(),
- any.getKey(),
- null,
- noPropResources));
- }
-
- protected void provision(final Any<?> any, final Boolean enabled) {
- AnyTO before = getAnyTO(any.getKey());
-
- List<String> noPropResources = new ArrayList<>(before.getResources());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
- taskExecutor.execute(propagationManager.getCreateTasks(
- any.getType().getKind(),
- any.getKey(),
- propByRes,
- before.getVirAttrs(),
- noPropResources));
- }
-
- @SuppressWarnings("unchecked")
- protected void link(final Any<?> any, final Boolean unlink) {
- AnyPatch patch = newPatch(any.getKey());
- patch.getResources().add(new StringPatchItem.Builder().
- operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE).
- value(profile.getTask().getResource().getKey()).build());
-
- update(patch);
- }
-
- @SuppressWarnings("unchecked")
- protected void unassign(final Any<?> any) {
- AnyPatch patch = newPatch(any.getKey());
- patch.getResources().add(new StringPatchItem.Builder().
- operation(PatchOperation.DELETE).
- value(profile.getTask().getResource().getKey()).build());
-
- update(patch);
-
- deprovision(any);
- }
-
- protected void assign(final Any<?> any, final Boolean enabled) {
- AnyPatch patch = newPatch(any.getKey());
- patch.getResources().add(new StringPatchItem.Builder().
- operation(PatchOperation.ADD_REPLACE).
- value(profile.getTask().getResource().getKey()).build());
-
- update(patch);
-
- provision(any, enabled);
- }
-
- protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
- ConnectorObject obj = null;
- try {
- Uid uid = new Uid(connObjectKey);
-
- obj = profile.getConnector().getObject(
- objectClass,
- uid,
- MappingUtils.buildOperationOptions(IteratorUtils.<MappingItem>emptyIterator()));
- } catch (TimeoutException toe) {
- LOG.debug("Request timeout", toe);
- throw toe;
- } catch (RuntimeException ignore) {
- LOG.debug("While resolving {}", connObjectKey, ignore);
- }
-
- return obj;
- }
-
- @Transactional(propagation = Propagation.REQUIRES_NEW)
- @Override
- public boolean handle(final long anyKey) {
- Any<?> any = null;
- try {
- any = getAny(anyKey);
- doHandle(any);
- return true;
- } catch (IgnoreProvisionException e) {
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.NONE);
- result.setAnyType(any == null ? null : any.getType().getKey());
- result.setStatus(ProvisioningReport.Status.IGNORE);
- result.setKey(anyKey);
- profile.getResults().add(result);
-
- LOG.warn("Ignoring during push", e);
- return true;
- } catch (JobExecutionException e) {
- LOG.error("Push failed", e);
- return false;
- }
- }
-
- protected final void doHandle(final Any<?> any) throws JobExecutionException {
- AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-
- ProvisioningReport result = new ProvisioningReport();
- profile.getResults().add(result);
-
- result.setKey(any.getKey());
- result.setAnyType(any.getType().getKey());
- result.setName(getName(any));
-
- Boolean enabled = any instanceof User && profile.getTask().isSyncStatus()
- ? ((User) any).isSuspended() ? Boolean.FALSE : Boolean.TRUE
- : null;
-
- LOG.debug("Propagating {} with key {} towards {}",
- anyUtils.getAnyTypeKind(), any.getKey(), profile.getTask().getResource());
-
- Object output = null;
- Result resultStatus = null;
- String operation = null;
-
- // Try to read remote object BEFORE any actual operation
- Provision provision = profile.getTask().getResource().getProvision(any.getType());
- String connObjecKey = mappingUtils.getConnObjectKeyValue(any, provision);
-
- ConnectorObject beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass());
-
- Boolean status = profile.getTask().isSyncStatus() ? enabled : null;
-
- if (profile.isDryRun()) {
- if (beforeObj == null) {
- result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
- } else {
- result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
- }
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- } else {
- try {
- if (beforeObj == null) {
- operation = UnmatchingRule.toEventName(profile.getTask().getUnmatchingRule());
- result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
-
- switch (profile.getTask().getUnmatchingRule()) {
- case ASSIGN:
- for (PushActions action : profile.getActions()) {
- action.beforeAssign(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("PushTask not configured for create");
- } else {
- assign(any, status);
- }
-
- break;
-
- case PROVISION:
- for (PushActions action : profile.getActions()) {
- action.beforeProvision(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("PushTask not configured for create");
- } else {
- provision(any, status);
- }
-
- break;
-
- case UNLINK:
- for (PushActions action : profile.getActions()) {
- action.beforeUnlink(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PushTask not configured for update");
- } else {
- link(any, true);
- }
-
- break;
-
- case IGNORE:
- LOG.debug("Ignored any: {}", any);
- break;
- default:
- // do nothing
- }
- } else {
- operation = MatchingRule.toEventName(profile.getTask().getMatchingRule());
- result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
-
- switch (profile.getTask().getMatchingRule()) {
- case UPDATE:
- for (PushActions action : profile.getActions()) {
- action.beforeUpdate(this.getProfile(), any);
- }
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PushTask not configured for update");
- } else {
- update(any, status);
- }
-
- break;
-
- case DEPROVISION:
- for (PushActions action : profile.getActions()) {
- action.beforeDeprovision(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformDelete()) {
- LOG.debug("PushTask not configured for delete");
- } else {
- deprovision(any);
- }
-
- break;
-
- case UNASSIGN:
- for (PushActions action : profile.getActions()) {
- action.beforeUnassign(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformDelete()) {
- LOG.debug("PushTask not configured for delete");
- } else {
- unassign(any);
- }
-
- break;
-
- case LINK:
- for (PushActions action : profile.getActions()) {
- action.beforeLink(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PushTask not configured for update");
- } else {
- link(any, false);
- }
-
- break;
-
- case UNLINK:
- for (PushActions action : profile.getActions()) {
- action.beforeUnlink(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PushTask not configured for update");
- } else {
- link(any, true);
- }
-
- break;
-
- case IGNORE:
- LOG.debug("Ignored any: {}", any);
- break;
- default:
- // do nothing
- }
- }
-
- for (PushActions action : profile.getActions()) {
- action.after(this.getProfile(), any, result);
- }
-
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- resultStatus = AuditElements.Result.SUCCESS;
- output = getRemoteObject(connObjecKey, provision.getObjectClass());
- } catch (IgnoreProvisionException e) {
- throw e;
- } catch (Exception e) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- resultStatus = AuditElements.Result.FAILURE;
- output = e;
-
- LOG.warn("Error pushing {} towards {}", any, profile.getTask().getResource(), e);
-
- for (PushActions action : profile.getActions()) {
- action.onError(this.getProfile(), any, result, e);
- }
-
- throw new JobExecutionException(e);
- } finally {
- notificationManager.createTasks(AuditElements.EventCategoryType.PUSH,
- any.getType().getKind().name().toLowerCase(),
- profile.getTask().getResource().getKey(),
- operation,
- resultStatus,
- beforeObj,
- output,
- any);
- auditManager.audit(AuditElements.EventCategoryType.PUSH,
- any.getType().getKind().name().toLowerCase(),
- profile.getTask().getResource().getKey(),
- operation,
- resultStatus,
- connObjectUtils.getConnObjectTO(beforeObj),
- output instanceof ConnectorObject
- ? connObjectUtils.getConnObjectTO((ConnectorObject) output) : output,
- any);
- }
- }
- }
-
- private ResourceOperation getResourceOperation(final UnmatchingRule rule) {
- switch (rule) {
- case ASSIGN:
- case PROVISION:
- return ResourceOperation.CREATE;
- default:
- return ResourceOperation.NONE;
- }
- }
-
- private ResourceOperation getResourceOperation(final MatchingRule rule) {
- switch (rule) {
- case UPDATE:
- return ResourceOperation.UPDATE;
- case DEPROVISION:
- case UNASSIGN:
- return ResourceOperation.DELETE;
- default:
- return ResourceOperation.NONE;
- }
- }
-
- protected Any<?> update(final Any<?> any, final Boolean enabled) {
- boolean changepwd;
- Collection<String> resourceNames;
- if (any instanceof User) {
- changepwd = true;
- resourceNames = userDAO.findAllResourceNames((User) any);
- } else if (any instanceof AnyObject) {
- changepwd = false;
- resourceNames = anyObjectDAO.findAllResourceNames((AnyObject) any);
- } else {
- changepwd = false;
- resourceNames = ((Group) any).getResourceNames();
- }
-
- List<String> noPropResources = new ArrayList<>(resourceNames);
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
- taskExecutor.execute(propagationManager.getUpdateTasks(
- any.getType().getKind(),
- any.getKey(),
- changepwd,
- null,
- propByRes,
- null,
- noPropResources));
-
- return getAny(any.getKey());
- }
-}
[03/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java
new file mode 100644
index 0000000..ee55ea4
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DefaultPasswordGenerator.java
@@ -0,0 +1,334 @@
+/*
+ * 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.core.spring.security;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
+import org.apache.syncope.common.lib.policy.PasswordRuleConf;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
+import org.apache.syncope.core.provisioning.api.utils.policy.PolicyPattern;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * Generate random passwords according to given policies.
+ * When no minimum and / or maximum length are specified, default values are set.
+ *
+ * <strong>WARNING</strong>: This class only takes {@link DefaultPasswordRuleConf} into account.
+ */
+public class DefaultPasswordGenerator implements PasswordGenerator {
+
+ private static final char[] SPECIAL_CHARS = { '!', 'ÂŁ', '%', '&', '(', ')', '?', '#', '$' };
+
+ private static final int VERY_MIN_LENGTH = 0;
+
+ private static final int VERY_MAX_LENGTH = 64;
+
+ private static final int MIN_LENGTH_IF_ZERO = 6;
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Autowired
+ private RealmDAO realmDAO;
+
+ @Override
+ public String generate(final User user) throws InvalidPasswordRuleConf {
+ List<PasswordRuleConf> ruleConfs = new ArrayList<>();
+
+ for (Realm ancestor : realmDAO.findAncestors(user.getRealm())) {
+ if (ancestor.getPasswordPolicy() != null) {
+ ruleConfs.addAll(ancestor.getPasswordPolicy().getRuleConfs());
+ }
+ }
+
+ for (ExternalResource resource : userDAO.findAllResources(user)) {
+ if (resource.getPasswordPolicy() != null) {
+ ruleConfs.addAll(resource.getPasswordPolicy().getRuleConfs());
+ }
+ }
+
+ return generate(ruleConfs);
+ }
+
+ @Override
+ public String generate(final List<PasswordRuleConf> ruleConfs) throws InvalidPasswordRuleConf {
+ List<DefaultPasswordRuleConf> defaultRuleConfs = new ArrayList<>();
+ for (PasswordRuleConf ruleConf : ruleConfs) {
+ if (ruleConf instanceof DefaultPasswordRuleConf) {
+ defaultRuleConfs.add((DefaultPasswordRuleConf) ruleConf);
+ }
+ }
+
+ DefaultPasswordRuleConf ruleConf = merge(defaultRuleConfs);
+ check(ruleConf);
+ return generate(ruleConf);
+ }
+
+ private DefaultPasswordRuleConf merge(final List<DefaultPasswordRuleConf> defaultRuleConfs) {
+ DefaultPasswordRuleConf result = new DefaultPasswordRuleConf();
+ result.setMinLength(VERY_MIN_LENGTH);
+ result.setMaxLength(VERY_MAX_LENGTH);
+
+ for (DefaultPasswordRuleConf ruleConf : defaultRuleConfs) {
+ if (ruleConf.getMinLength() > result.getMinLength()) {
+ result.setMinLength(ruleConf.getMinLength());
+ }
+
+ if ((ruleConf.getMaxLength() != 0) && ((ruleConf.getMaxLength() < result.getMaxLength()))) {
+ result.setMaxLength(ruleConf.getMaxLength());
+ }
+ result.getPrefixesNotPermitted().addAll(ruleConf.getPrefixesNotPermitted());
+ result.getSuffixesNotPermitted().addAll(ruleConf.getSuffixesNotPermitted());
+
+ if (!result.isNonAlphanumericRequired()) {
+ result.setNonAlphanumericRequired(ruleConf.isNonAlphanumericRequired());
+ }
+
+ if (!result.isAlphanumericRequired()) {
+ result.setAlphanumericRequired(ruleConf.isAlphanumericRequired());
+ }
+ if (!result.isDigitRequired()) {
+ result.setDigitRequired(ruleConf.isDigitRequired());
+ }
+
+ if (!result.isLowercaseRequired()) {
+ result.setLowercaseRequired(ruleConf.isLowercaseRequired());
+ }
+ if (!result.isUppercaseRequired()) {
+ result.setUppercaseRequired(ruleConf.isUppercaseRequired());
+ }
+ if (!result.isMustStartWithDigit()) {
+ result.setMustStartWithDigit(ruleConf.isMustStartWithDigit());
+ }
+ if (!result.isMustntStartWithDigit()) {
+ result.setMustntStartWithDigit(ruleConf.isMustntStartWithDigit());
+ }
+ if (!result.isMustEndWithDigit()) {
+ result.setMustEndWithDigit(ruleConf.isMustEndWithDigit());
+ }
+ if (result.isMustntEndWithDigit()) {
+ result.setMustntEndWithDigit(ruleConf.isMustntEndWithDigit());
+ }
+ if (!result.isMustStartWithAlpha()) {
+ result.setMustStartWithAlpha(ruleConf.isMustStartWithAlpha());
+ }
+ if (!result.isMustntStartWithAlpha()) {
+ result.setMustntStartWithAlpha(ruleConf.isMustntStartWithAlpha());
+ }
+ if (!result.isMustStartWithNonAlpha()) {
+ result.setMustStartWithNonAlpha(ruleConf.isMustStartWithNonAlpha());
+ }
+ if (!result.isMustntStartWithNonAlpha()) {
+ result.setMustntStartWithNonAlpha(ruleConf.isMustntStartWithNonAlpha());
+ }
+ if (!result.isMustEndWithNonAlpha()) {
+ result.setMustEndWithNonAlpha(ruleConf.isMustEndWithNonAlpha());
+ }
+ if (!result.isMustntEndWithNonAlpha()) {
+ result.setMustntEndWithNonAlpha(ruleConf.isMustntEndWithNonAlpha());
+ }
+ if (!result.isMustEndWithAlpha()) {
+ result.setMustEndWithAlpha(ruleConf.isMustEndWithAlpha());
+ }
+ if (!result.isMustntEndWithAlpha()) {
+ result.setMustntEndWithAlpha(ruleConf.isMustntEndWithAlpha());
+ }
+ if (!result.isUsernameAllowed()) {
+ result.setUsernameAllowed(ruleConf.isUsernameAllowed());
+ }
+ }
+
+ if (result.getMinLength() == 0) {
+ result.setMinLength(
+ result.getMaxLength() < MIN_LENGTH_IF_ZERO ? result.getMaxLength() : MIN_LENGTH_IF_ZERO);
+ }
+
+ return result;
+ }
+
+ private void check(final DefaultPasswordRuleConf defaultPasswordRuleConf)
+ throws InvalidPasswordRuleConf {
+
+ if (defaultPasswordRuleConf.isMustEndWithAlpha() && defaultPasswordRuleConf.isMustntEndWithAlpha()) {
+ throw new InvalidPasswordRuleConf(
+ "mustEndWithAlpha and mustntEndWithAlpha are both true");
+ }
+ if (defaultPasswordRuleConf.isMustEndWithAlpha() && defaultPasswordRuleConf.isMustEndWithDigit()) {
+ throw new InvalidPasswordRuleConf(
+ "mustEndWithAlpha and mustEndWithDigit are both true");
+ }
+ if (defaultPasswordRuleConf.isMustEndWithDigit() && defaultPasswordRuleConf.isMustntEndWithDigit()) {
+ throw new InvalidPasswordRuleConf(
+ "mustEndWithDigit and mustntEndWithDigit are both true");
+ }
+ if (defaultPasswordRuleConf.isMustEndWithNonAlpha() && defaultPasswordRuleConf.isMustntEndWithNonAlpha()) {
+ throw new InvalidPasswordRuleConf(
+ "mustEndWithNonAlpha and mustntEndWithNonAlpha are both true");
+ }
+ if (defaultPasswordRuleConf.isMustStartWithAlpha() && defaultPasswordRuleConf.isMustntStartWithAlpha()) {
+ throw new InvalidPasswordRuleConf(
+ "mustStartWithAlpha and mustntStartWithAlpha are both true");
+ }
+ if (defaultPasswordRuleConf.isMustStartWithAlpha() && defaultPasswordRuleConf.isMustStartWithDigit()) {
+ throw new InvalidPasswordRuleConf(
+ "mustStartWithAlpha and mustStartWithDigit are both true");
+ }
+ if (defaultPasswordRuleConf.isMustStartWithDigit() && defaultPasswordRuleConf.isMustntStartWithDigit()) {
+ throw new InvalidPasswordRuleConf(
+ "mustStartWithDigit and mustntStartWithDigit are both true");
+ }
+ if (defaultPasswordRuleConf.isMustStartWithNonAlpha() && defaultPasswordRuleConf.isMustntStartWithNonAlpha()) {
+ throw new InvalidPasswordRuleConf(
+ "mustStartWithNonAlpha and mustntStartWithNonAlpha are both true");
+ }
+ if (defaultPasswordRuleConf.getMinLength() > defaultPasswordRuleConf.getMaxLength()) {
+ throw new InvalidPasswordRuleConf(
+ "Minimun length (" + defaultPasswordRuleConf.getMinLength() + ")"
+ + "is greater than maximum length (" + defaultPasswordRuleConf.getMaxLength() + ")");
+ }
+ }
+
+ private String generate(final DefaultPasswordRuleConf ruleConf) {
+ String[] generatedPassword = new String[ruleConf.getMinLength()];
+
+ for (int i = 0; i < generatedPassword.length; i++) {
+ generatedPassword[i] = StringUtils.EMPTY;
+ }
+
+ checkStartChar(generatedPassword, ruleConf);
+
+ checkEndChar(generatedPassword, ruleConf);
+
+ checkRequired(generatedPassword, ruleConf);
+
+ for (int firstEmptyChar = firstEmptyChar(generatedPassword);
+ firstEmptyChar < generatedPassword.length - 1; firstEmptyChar++) {
+
+ generatedPassword[firstEmptyChar] = SecureRandomUtils.generateRandomLetter();
+ }
+
+ checkPrefixAndSuffix(generatedPassword, ruleConf);
+
+ return StringUtils.join(generatedPassword);
+ }
+
+ private void checkStartChar(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
+ if (ruleConf.isMustStartWithAlpha()) {
+ generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
+ }
+ if (ruleConf.isMustStartWithNonAlpha() || ruleConf.isMustStartWithDigit()) {
+ generatedPassword[0] = SecureRandomUtils.generateRandomNumber();
+ }
+ if (ruleConf.isMustntStartWithAlpha()) {
+ generatedPassword[0] = SecureRandomUtils.generateRandomNumber();
+ }
+ if (ruleConf.isMustntStartWithDigit()) {
+ generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
+ }
+ if (ruleConf.isMustntStartWithNonAlpha()) {
+ generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
+ }
+
+ if (StringUtils.EMPTY.equals(generatedPassword[0])) {
+ generatedPassword[0] = SecureRandomUtils.generateRandomLetter();
+ }
+ }
+
+ private void checkEndChar(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
+ if (ruleConf.isMustEndWithAlpha()) {
+ generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
+ }
+ if (ruleConf.isMustEndWithNonAlpha() || ruleConf.isMustEndWithDigit()) {
+ generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomNumber();
+ }
+
+ if (ruleConf.isMustntEndWithAlpha()) {
+ generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomNumber();
+ }
+ if (ruleConf.isMustntEndWithDigit()) {
+ generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
+ }
+ if (ruleConf.isMustntEndWithNonAlpha()) {
+ generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
+ }
+
+ if (StringUtils.EMPTY.equals(generatedPassword[ruleConf.getMinLength() - 1])) {
+ generatedPassword[ruleConf.getMinLength() - 1] = SecureRandomUtils.generateRandomLetter();
+ }
+ }
+
+ private int firstEmptyChar(final String[] generatedPStrings) {
+ int index = 0;
+ while (!generatedPStrings[index].isEmpty()) {
+ index++;
+ }
+ return index;
+ }
+
+ private void checkRequired(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
+ if (ruleConf.isDigitRequired()
+ && !PolicyPattern.DIGIT.matcher(StringUtils.join(generatedPassword)).matches()) {
+
+ generatedPassword[firstEmptyChar(generatedPassword)] = SecureRandomUtils.generateRandomNumber();
+ }
+
+ if (ruleConf.isUppercaseRequired()
+ && !PolicyPattern.ALPHA_UPPERCASE.matcher(StringUtils.join(generatedPassword)).matches()) {
+
+ generatedPassword[firstEmptyChar(generatedPassword)] =
+ SecureRandomUtils.generateRandomLetter().toUpperCase();
+ }
+
+ if (ruleConf.isLowercaseRequired()
+ && !PolicyPattern.ALPHA_LOWERCASE.matcher(StringUtils.join(generatedPassword)).matches()) {
+
+ generatedPassword[firstEmptyChar(generatedPassword)] =
+ SecureRandomUtils.generateRandomLetter().toLowerCase();
+ }
+
+ if (ruleConf.isNonAlphanumericRequired()
+ && !PolicyPattern.NON_ALPHANUMERIC.matcher(StringUtils.join(generatedPassword)).matches()) {
+
+ generatedPassword[firstEmptyChar(generatedPassword)] =
+ SecureRandomUtils.generateRandomSpecialCharacter(SPECIAL_CHARS);
+ }
+ }
+
+ private void checkPrefixAndSuffix(final String[] generatedPassword, final DefaultPasswordRuleConf ruleConf) {
+ for (String prefix : ruleConf.getPrefixesNotPermitted()) {
+ if (StringUtils.join(generatedPassword).startsWith(prefix)) {
+ checkStartChar(generatedPassword, ruleConf);
+ }
+ }
+
+ for (String suffix : ruleConf.getSuffixesNotPermitted()) {
+ if (StringUtils.join(generatedPassword).endsWith(suffix)) {
+ checkEndChar(generatedPassword, ruleConf);
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
new file mode 100644
index 0000000..d99c96c
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/DelegatedAdministrationException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.core.spring.security;
+
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+
+public class DelegatedAdministrationException extends RuntimeException {
+
+ private static final long serialVersionUID = 7540587364235915081L;
+
+ public DelegatedAdministrationException(final AnyTypeKind type, final Long key) {
+ super("Missing entitlement or realm administration for "
+ + (key == null
+ ? "new " + type
+ : type + " " + key));
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/Encryptor.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/Encryptor.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/Encryptor.java
new file mode 100644
index 0000000..a1e8a9e
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/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.core.spring.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<>();
+
+ 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 SECRET_KEY;
+
+ private static Integer SALT_ITERATIONS;
+
+ private static Integer SALT_SIZE_BYTES;
+
+ 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);
+
+ SECRET_KEY = props.getProperty("secretKey");
+ SALT_ITERATIONS = Integer.valueOf(props.getProperty("digester.saltIterations"));
+ SALT_SIZE_BYTES = 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 (SECRET_KEY == null) {
+ SECRET_KEY = DEFAULT_SECRET_KEY;
+ LOG.debug("secretKey not found, reverting to default");
+ }
+ if (SALT_ITERATIONS == null) {
+ SALT_ITERATIONS = DEFAULT_SALT_ITERATIONS;
+ LOG.debug("digester.saltIterations not found, reverting to default");
+ }
+ if (SALT_SIZE_BYTES == null) {
+ SALT_SIZE_BYTES = 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(SECRET_KEY);
+ }
+
+ 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_CHARSET), 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_CHARSET);
+
+ 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_CHARSET);
+
+ final Cipher cipher = Cipher.getInstance(CipherAlgorithm.AES.getAlgorithm());
+ cipher.init(Cipher.DECRYPT_MODE, keySpec);
+
+ value = new String(cipher.doFinal(Base64.decode(encoded)), SyncopeConstants.DEFAULT_CHARSET);
+ }
+
+ 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(SALT_ITERATIONS);
+ digester.setSaltSizeBytes(SALT_SIZE_BYTES);
+ 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/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/MustChangePasswordFilter.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/MustChangePasswordFilter.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/MustChangePasswordFilter.java
new file mode 100644
index 0000000..f9939dd
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/MustChangePasswordFilter.java
@@ -0,0 +1,80 @@
+/*
+ * 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.core.spring.security;
+
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper;
+
+public class MustChangePasswordFilter implements Filter {
+
+ private static final String[] ALLOWED = new String[] {
+ "/users/self", "/users/self/changePassword"
+ };
+
+ @Override
+ public void init(final FilterConfig filterConfig) throws ServletException {
+ // not used
+ }
+
+ @Override
+ public void destroy() {
+ // not used
+ }
+
+ @Override
+ public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
+ throws IOException, ServletException {
+
+ if (request instanceof SecurityContextHolderAwareRequestWrapper) {
+ boolean isMustChangePassword = IterableUtils.matchesAny(
+ SecurityContextHolder.getContext().getAuthentication().getAuthorities(),
+ new Predicate<GrantedAuthority>() {
+
+ @Override
+ public boolean evaluate(final GrantedAuthority authority) {
+ return StandardEntitlement.MUST_CHANGE_PASSWORD.equals(authority.getAuthority());
+ }
+ });
+
+ SecurityContextHolderAwareRequestWrapper wrapper =
+ SecurityContextHolderAwareRequestWrapper.class.cast(request);
+ if (isMustChangePassword && "GET".equalsIgnoreCase(wrapper.getMethod())
+ && !ArrayUtils.contains(ALLOWED, wrapper.getPathInfo())) {
+
+ throw new AccessDeniedException("Please change your password first");
+ }
+ }
+
+ chain.doFilter(request, response);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java
new file mode 100644
index 0000000..ad6b56b
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/PasswordGenerator.java
@@ -0,0 +1,32 @@
+/*
+ * 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.core.spring.security;
+
+import java.util.List;
+import org.apache.syncope.common.lib.policy.PasswordRuleConf;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+
+public interface PasswordGenerator {
+
+ String generate(User user) throws InvalidPasswordRuleConf;
+
+ String generate(List<PasswordRuleConf> ruleConfs) throws InvalidPasswordRuleConf;
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecureRandomUtils.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecureRandomUtils.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecureRandomUtils.java
new file mode 100644
index 0000000..04aad69
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecureRandomUtils.java
@@ -0,0 +1,48 @@
+/*
+ * 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.core.spring.security;
+
+import java.security.SecureRandom;
+
+import org.apache.commons.lang3.RandomStringUtils;
+
+public final class SecureRandomUtils {
+
+ 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(final char[] characters) {
+ return RandomStringUtils.random(1, 0, 0, false, false, characters, RANDOM);
+ }
+
+ private SecureRandomUtils() {
+ // private constructor for static utility class
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAccessDeniedHandler.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAccessDeniedHandler.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAccessDeniedHandler.java
new file mode 100644
index 0000000..888cae9
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAccessDeniedHandler.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.core.spring.security;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.web.access.AccessDeniedHandlerImpl;
+
+/**
+ * Render Spring's {@link AccessDeniedException} as other Syncope errors.
+ */
+public class SyncopeAccessDeniedHandler extends AccessDeniedHandlerImpl {
+
+ @Override
+ public void handle(final HttpServletRequest request, final HttpServletResponse response,
+ final AccessDeniedException accessDeniedException) throws IOException, ServletException {
+
+ response.addHeader(RESTHeaders.ERROR_INFO, accessDeniedException.getMessage());
+
+ super.handle(request, response, accessDeniedException);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetails.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetails.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetails.java
new file mode 100644
index 0000000..c427c48
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetails.java
@@ -0,0 +1,86 @@
+/*
+ * 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.core.spring.security;
+
+import java.io.Serializable;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+
+public class SyncopeAuthenticationDetails implements Serializable {
+
+ private static final long serialVersionUID = -5899959397393502897L;
+
+ private final String remoteAddress;
+
+ private final String sessionId;
+
+ private String domain;
+
+ public SyncopeAuthenticationDetails(final HttpServletRequest request) {
+ this.remoteAddress = request.getRemoteAddr();
+
+ HttpSession session = request.getSession(false);
+ this.sessionId = session == null ? null : session.getId();
+
+ this.domain = request.getHeader(RESTHeaders.DOMAIN);
+ }
+
+ public SyncopeAuthenticationDetails(final String domain) {
+ this.remoteAddress = null;
+ this.sessionId = null;
+ this.domain = domain;
+ }
+
+ public String getRemoteAddress() {
+ return remoteAddress;
+ }
+
+ public String getSessionId() {
+ return sessionId;
+ }
+
+ public String getDomain() {
+ return domain;
+ }
+
+ public void setDomain(final String domain) {
+ this.domain = domain;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return EqualsBuilder.reflectionEquals(this, obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetailsSource.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetailsSource.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetailsSource.java
new file mode 100644
index 0000000..0b2b27c
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetailsSource.java
@@ -0,0 +1,32 @@
+/*
+ * 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.core.spring.security;
+
+import javax.servlet.http.HttpServletRequest;
+import org.springframework.security.authentication.AuthenticationDetailsSource;
+
+public class SyncopeAuthenticationDetailsSource
+ implements AuthenticationDetailsSource<HttpServletRequest, SyncopeAuthenticationDetails> {
+
+ @Override
+ public SyncopeAuthenticationDetails buildDetails(final HttpServletRequest context) {
+ return new SyncopeAuthenticationDetails(context);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationEntryPoint.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationEntryPoint.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationEntryPoint.java
new file mode 100644
index 0000000..7f9ad7b
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationEntryPoint.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.core.spring.security;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
+
+/**
+ * Render Spring's {@link AuthenticationException} as other Syncope errors.
+ */
+public class SyncopeAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
+
+ @Override
+ public void commence(final HttpServletRequest request, final HttpServletResponse response,
+ final AuthenticationException authException) throws IOException, ServletException {
+
+ response.addHeader(RESTHeaders.ERROR_INFO, authException.getMessage());
+
+ super.commence(request, response, authException);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationProvider.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationProvider.java
new file mode 100644
index 0000000..078ebc4
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationProvider.java
@@ -0,0 +1,210 @@
+/*
+ * 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.core.spring.security;
+
+import javax.annotation.Resource;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.core.spring.security.AuthContextUtils.Executable;
+import org.apache.syncope.core.persistence.api.entity.Domain;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.UserDetailsService;
+
+@Configurable
+public class SyncopeAuthenticationProvider implements AuthenticationProvider {
+
+ protected static final Logger LOG = LoggerFactory.getLogger(SyncopeAuthenticationProvider.class);
+
+ @Autowired
+ protected AuthDataAccessor dataAccessor;
+
+ @Autowired
+ protected UserProvisioningManager provisioningManager;
+
+ @Resource(name = "adminUser")
+ protected String adminUser;
+
+ @Resource(name = "anonymousUser")
+ protected String anonymousUser;
+
+ protected String adminPassword;
+
+ protected String adminPasswordAlgorithm;
+
+ protected String anonymousKey;
+
+ protected UserDetailsService userDetailsService;
+
+ protected final Encryptor encryptor = Encryptor.getInstance();
+
+ /**
+ * @param adminPassword the adminPassword to set
+ */
+ public void setAdminPassword(final String adminPassword) {
+ this.adminPassword = adminPassword;
+ }
+
+ /**
+ * @param adminPasswordAlgorithm the adminPasswordAlgorithm to set
+ */
+ public void setAdminPasswordAlgorithm(final String adminPasswordAlgorithm) {
+ this.adminPasswordAlgorithm = adminPasswordAlgorithm;
+ }
+
+ /**
+ * @param anonymousKey the anonymousKey to set
+ */
+ public void setAnonymousKey(final String anonymousKey) {
+ this.anonymousKey = anonymousKey;
+ }
+
+ public void setUserDetailsService(final UserDetailsService syncopeUserDetailsService) {
+ this.userDetailsService = syncopeUserDetailsService;
+ }
+
+ @Override
+ public Authentication authenticate(final Authentication authentication) {
+ String domainKey = SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).getDomain();
+ if (StringUtils.isBlank(domainKey)) {
+ domainKey = SyncopeConstants.MASTER_DOMAIN;
+ }
+ SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).setDomain(domainKey);
+
+ Boolean authenticated;
+ if (anonymousUser.equals(authentication.getName())) {
+ authenticated = authentication.getCredentials().toString().equals(anonymousKey);
+ } else if (adminUser.equals(authentication.getName())) {
+ if (SyncopeConstants.MASTER_DOMAIN.equals(domainKey)) {
+ authenticated = encryptor.verify(
+ authentication.getCredentials().toString(),
+ CipherAlgorithm.valueOf(adminPasswordAlgorithm),
+ adminPassword);
+ } else {
+ final String domainToFind = domainKey;
+ authenticated = AuthContextUtils.execWithAuthContext(
+ SyncopeConstants.MASTER_DOMAIN, new Executable<Boolean>() {
+
+ @Override
+ public Boolean exec() {
+ Domain domain = dataAccessor.findDomain(domainToFind);
+
+ return encryptor.verify(
+ authentication.getCredentials().toString(),
+ domain.getAdminCipherAlgorithm(),
+ domain.getAdminPwd());
+ }
+ });
+ }
+ } else {
+ final Pair<Long, Boolean> authResult =
+ AuthContextUtils.execWithAuthContext(domainKey, new Executable<Pair<Long, Boolean>>() {
+
+ @Override
+ public Pair<Long, Boolean> exec() {
+ return dataAccessor.authenticate(authentication);
+ }
+ });
+ authenticated = authResult.getValue();
+ if (authenticated != null && !authenticated) {
+ AuthContextUtils.execWithAuthContext(domainKey, new Executable<Void>() {
+
+ @Override
+ public Void exec() {
+ provisioningManager.internalSuspend(authResult.getKey());
+ return null;
+ }
+ });
+ }
+ }
+
+ final boolean isAuthenticated = authenticated != null && authenticated;
+ UsernamePasswordAuthenticationToken token;
+ if (isAuthenticated) {
+ token = AuthContextUtils.execWithAuthContext(
+ domainKey, new Executable<UsernamePasswordAuthenticationToken>() {
+
+ @Override
+ public UsernamePasswordAuthenticationToken exec() {
+ UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
+ authentication.getPrincipal(),
+ null,
+ userDetailsService.loadUserByUsername(authentication.getPrincipal().toString()).
+ getAuthorities());
+ token.setDetails(authentication.getDetails());
+
+ dataAccessor.audit(
+ AuditElements.EventCategoryType.REST,
+ AuditElements.AUTHENTICATION_CATEGORY,
+ null,
+ AuditElements.LOGIN_EVENT,
+ Result.SUCCESS,
+ null,
+ isAuthenticated,
+ authentication,
+ "Successfully authenticated, with entitlements: " + token.getAuthorities());
+ return token;
+ }
+ });
+
+ LOG.debug("User {} successfully authenticated, with entitlements {}",
+ authentication.getPrincipal(), token.getAuthorities());
+ } else {
+ AuthContextUtils.execWithAuthContext(domainKey, new Executable<Void>() {
+
+ @Override
+ public Void exec() {
+ dataAccessor.audit(
+ AuditElements.EventCategoryType.REST,
+ AuditElements.AUTHENTICATION_CATEGORY,
+ null,
+ AuditElements.LOGIN_EVENT,
+ Result.FAILURE,
+ null,
+ isAuthenticated,
+ authentication,
+ "User " + authentication.getPrincipal() + " not authenticated");
+ return null;
+ }
+ });
+
+ LOG.debug("User {} not authenticated", authentication.getPrincipal());
+
+ throw new BadCredentialsException("User " + authentication.getPrincipal() + " not authenticated");
+ }
+
+ return token;
+ }
+
+ @Override
+ public boolean supports(final Class<? extends Object> type) {
+ return type.equals(UsernamePasswordAuthenticationToken.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeGrantedAuthority.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeGrantedAuthority.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeGrantedAuthority.java
new file mode 100644
index 0000000..e23902b
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeGrantedAuthority.java
@@ -0,0 +1,90 @@
+/*
+ * 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.core.spring.security;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.commons.collections4.Closure;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.SetUtils;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
+import org.springframework.security.core.GrantedAuthority;
+
+public class SyncopeGrantedAuthority implements GrantedAuthority {
+
+ private static final long serialVersionUID = -5647624636011919735L;
+
+ private final String entitlement;
+
+ private final Set<String> realms = SetUtils.orderedSet(new HashSet<String>());
+
+ public SyncopeGrantedAuthority(final String entitlement) {
+ this.entitlement = entitlement;
+ }
+
+ public SyncopeGrantedAuthority(final String entitlement, final String realm) {
+ this.entitlement = entitlement;
+ this.realms.add(realm);
+ }
+
+ public boolean addRealm(final String newRealm) {
+ return RealmUtils.normalizingAddTo(realms, newRealm);
+ }
+
+ public void addRealms(final Collection<String> newRealms) {
+ IterableUtils.forEach(newRealms, new Closure<String>() {
+
+ @Override
+ public void execute(final String newRealm) {
+ addRealm(newRealm);
+ }
+ });
+ }
+
+ public Set<String> getRealms() {
+ return Collections.unmodifiableSet(realms);
+ }
+
+ @Override
+ public String getAuthority() {
+ return entitlement;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return EqualsBuilder.reflectionEquals(this, obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeUserDetailsService.java
----------------------------------------------------------------------
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeUserDetailsService.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeUserDetailsService.java
new file mode 100644
index 0000000..544fc99
--- /dev/null
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeUserDetailsService.java
@@ -0,0 +1,37 @@
+/*
+ * 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.core.spring.security;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+
+@Configurable
+public class SyncopeUserDetailsService implements UserDetailsService {
+
+ @Autowired
+ protected AuthDataAccessor dataAccessor;
+
+ @Override
+ public UserDetails loadUserByUsername(final String username) {
+ return new User(username, "<PASSWORD_PLACEHOLDER>", dataAccessor.load(username));
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/resources/security.properties
----------------------------------------------------------------------
diff --git a/core/spring/src/main/resources/security.properties b/core/spring/src/main/resources/security.properties
new file mode 100644
index 0000000..6bb5210
--- /dev/null
+++ b/core/spring/src/main/resources/security.properties
@@ -0,0 +1,32 @@
+# 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
+
+passwordGenerator=org.apache.syncope.core.spring.security.DefaultPasswordGenerator
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/main/resources/securityContext.xml
----------------------------------------------------------------------
diff --git a/core/spring/src/main/resources/securityContext.xml b/core/spring/src/main/resources/securityContext.xml
new file mode 100644
index 0000000..0e2072f
--- /dev/null
+++ b/core/spring/src/main/resources/securityContext.xml
@@ -0,0 +1,96 @@
+<?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:security="http://www.springframework.org/schema/security"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/security
+ http://www.springframework.org/schema/security/spring-security.xsd">
+
+ <bean id="adminUser" class="java.lang.String">
+ <constructor-arg value="${adminUser}"/>
+ </bean>
+ <bean id="anonymousUser" class="java.lang.String">
+ <constructor-arg value="${anonymousUser}"/>
+ </bean>
+
+ <bean class="${passwordGenerator}"/>
+ <bean class="org.apache.syncope.core.spring.DefaultRolesPrefixPostProcessor"/>
+
+ <security:global-method-security pre-post-annotations="enabled"/>
+
+ <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
+ <security:filter-chain-map request-matcher="ant">
+ <security:filter-chain pattern="/**" filters="securityContextPersistenceFilter"/>
+ </security:filter-chain-map>
+ </bean>
+
+ <bean id="securityContextRepository" class='org.springframework.security.web.context.NullSecurityContextRepository'/>
+
+ <bean id="securityContextPersistenceFilter"
+ class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
+ <constructor-arg ref="securityContextRepository"/>
+ </bean>
+
+ <bean id="syncopeAuthenticationDetailsSource"
+ class="org.apache.syncope.core.spring.security.SyncopeAuthenticationDetailsSource"/>
+
+ <bean id="mustChangePasswordFilter" class="org.apache.syncope.core.spring.security.MustChangePasswordFilter"/>
+
+ <bean id="syncopeAuthenticationEntryPoint"
+ class="org.apache.syncope.core.spring.security.SyncopeAuthenticationEntryPoint">
+ <property name="realmName" value="Apache Syncope authentication"/>
+ </bean>
+
+ <bean id="syncopeAccessDeniedHandler" class="org.apache.syncope.core.spring.security.SyncopeAccessDeniedHandler"/>
+
+ <security:http security-context-repository-ref="securityContextRepository"
+ use-expressions="false" disable-url-rewriting="false">
+
+ <security:http-basic entry-point-ref="syncopeAuthenticationEntryPoint"
+ authentication-details-source-ref="syncopeAuthenticationDetailsSource"/>
+ <security:anonymous username="${anonymousUser}"/>
+ <security:intercept-url pattern="/**"/>
+
+ <security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="mustChangePasswordFilter"/>
+
+ <security:access-denied-handler ref="syncopeAccessDeniedHandler"/>
+
+ <security:headers disabled="true"/>
+ <security:csrf disabled="true"/>
+ </security:http>
+
+ <bean class="org.apache.syncope.core.spring.security.AuthDataAccessor"/>
+
+ <bean id="syncopeUserDetailsService" class="org.apache.syncope.core.spring.security.SyncopeUserDetailsService"/>
+
+ <bean id="syncopeAuthenticationProvider"
+ class="org.apache.syncope.core.spring.security.SyncopeAuthenticationProvider">
+ <property name="adminPassword" value="${adminPassword}"/>
+ <property name="adminPasswordAlgorithm" value="${adminPasswordAlgorithm}"/>
+ <property name="anonymousKey" value="${anonymousKey}"/>
+ <property name="userDetailsService" ref="syncopeUserDetailsService"/>
+ </bean>
+
+ <security:authentication-manager>
+ <security:authentication-provider ref="syncopeAuthenticationProvider"/>
+ </security:authentication-manager>
+</beans>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java
----------------------------------------------------------------------
diff --git a/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java b/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java
new file mode 100644
index 0000000..4bfa0fa
--- /dev/null
+++ b/core/spring/src/test/java/org/apache/syncope/core/spring/security/EncryptorTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.core.spring.security;
+
+import org.apache.syncope.core.spring.security.Encryptor;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.junit.Test;
+
+/**
+ * Test class to test all encryption algorithms.
+ */
+public class EncryptorTest {
+
+ private final String password = "password";
+
+ private final Encryptor encryptor = Encryptor.getInstance();
+
+ /**
+ * Verify all algorithms.
+ */
+ @Test
+ public void testEncoder() throws Exception {
+ for (CipherAlgorithm cipherAlgorithm : CipherAlgorithm.values()) {
+ final String encPassword = encryptor.encode(password, cipherAlgorithm);
+
+ assertNotNull(encPassword);
+ assertTrue(encryptor.verify(password, cipherAlgorithm, encPassword));
+ assertFalse(encryptor.verify("pass", cipherAlgorithm, encPassword));
+
+ // check that same password encoded with BCRYPT or Salted versions results in different digest
+ if (cipherAlgorithm.equals(CipherAlgorithm.BCRYPT) || cipherAlgorithm.getAlgorithm().startsWith("S-")) {
+ final String encSamePassword = encryptor.encode(password, cipherAlgorithm);
+ assertNotNull(encSamePassword);
+ assertFalse(encSamePassword.equals(encPassword));
+ assertTrue(encryptor.verify(password, cipherAlgorithm, encSamePassword));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java
----------------------------------------------------------------------
diff --git a/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java b/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java
new file mode 100644
index 0000000..02c0ba4
--- /dev/null
+++ b/core/spring/src/test/java/org/apache/syncope/core/spring/security/PasswordGeneratorTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.core.spring.security;
+
+import org.apache.syncope.core.spring.security.DefaultPasswordGenerator;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
+import org.apache.syncope.common.lib.policy.PasswordRuleConf;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
+import org.apache.syncope.core.provisioning.api.utils.policy.PolicyPattern;
+import org.junit.Test;
+
+public class PasswordGeneratorTest {
+
+ private final DefaultPasswordGenerator passwordGenerator = new DefaultPasswordGenerator();
+
+ private DefaultPasswordRuleConf createBaseDefaultPasswordRuleConf() {
+ DefaultPasswordRuleConf baseDefaultPasswordRuleConf = new DefaultPasswordRuleConf();
+ baseDefaultPasswordRuleConf.setAlphanumericRequired(false);
+ baseDefaultPasswordRuleConf.setDigitRequired(false);
+ baseDefaultPasswordRuleConf.setLowercaseRequired(false);
+ baseDefaultPasswordRuleConf.setMaxLength(1000);
+ baseDefaultPasswordRuleConf.setMinLength(8);
+ baseDefaultPasswordRuleConf.setMustEndWithAlpha(false);
+ baseDefaultPasswordRuleConf.setMustEndWithDigit(false);
+ baseDefaultPasswordRuleConf.setMustEndWithNonAlpha(false);
+ baseDefaultPasswordRuleConf.setMustStartWithAlpha(false);
+ baseDefaultPasswordRuleConf.setMustStartWithDigit(false);
+ baseDefaultPasswordRuleConf.setMustStartWithNonAlpha(false);
+ baseDefaultPasswordRuleConf.setMustntEndWithAlpha(false);
+ baseDefaultPasswordRuleConf.setMustntEndWithDigit(false);
+ baseDefaultPasswordRuleConf.setMustntEndWithNonAlpha(false);
+ baseDefaultPasswordRuleConf.setMustntStartWithAlpha(false);
+ baseDefaultPasswordRuleConf.setMustntStartWithDigit(false);
+ baseDefaultPasswordRuleConf.setMustntStartWithNonAlpha(false);
+ baseDefaultPasswordRuleConf.setNonAlphanumericRequired(false);
+ baseDefaultPasswordRuleConf.setUppercaseRequired(false);
+ return baseDefaultPasswordRuleConf;
+ }
+
+ @Test
+ public void startEndWithDigit() throws InvalidPasswordRuleConf {
+ DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
+ pwdRuleConf.setMustStartWithDigit(true);
+
+ DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
+ pwdRuleConf2.setMustEndWithDigit(true);
+
+ List<PasswordRuleConf> ruleConfs = new ArrayList<>();
+ ruleConfs.add(pwdRuleConf);
+ ruleConfs.add(pwdRuleConf2);
+ String generatedPassword = passwordGenerator.generate(ruleConfs);
+ assertTrue(Character.isDigit(generatedPassword.charAt(0)));
+ assertTrue(Character.isDigit(generatedPassword.charAt(generatedPassword.length() - 1)));
+ }
+
+ @Test
+ public void startWithDigitAndWithAlpha() throws InvalidPasswordRuleConf {
+ DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
+ pwdRuleConf.setMustStartWithDigit(true);
+
+ DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
+ pwdRuleConf2.setMustEndWithAlpha(true);
+
+ List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>();
+ pwdRuleConfs.add(pwdRuleConf);
+ pwdRuleConfs.add(pwdRuleConf2);
+ String generatedPassword = passwordGenerator.generate(pwdRuleConfs);
+ assertTrue(Character.isDigit(generatedPassword.charAt(0)));
+ assertTrue(Character.isLetter(generatedPassword.charAt(generatedPassword.length() - 1)));
+ }
+
+ @Test
+ public void passwordWithNonAlpha() throws InvalidPasswordRuleConf {
+ DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
+ pwdRuleConf.setNonAlphanumericRequired(true);
+
+ DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
+ pwdRuleConf2.setMustEndWithAlpha(true);
+
+ List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>();
+ pwdRuleConfs.add(pwdRuleConf);
+ pwdRuleConfs.add(pwdRuleConf2);
+ String generatedPassword = passwordGenerator.generate(pwdRuleConfs);
+ assertTrue(PolicyPattern.NON_ALPHANUMERIC.matcher(generatedPassword).matches());
+ assertTrue(Character.isLetter(generatedPassword.charAt(generatedPassword.length() - 1)));
+ }
+
+ @Test(expected = InvalidPasswordRuleConf.class)
+ public void incopatiblePolicies() throws InvalidPasswordRuleConf {
+ DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
+ pwdRuleConf.setMinLength(12);
+
+ DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
+ pwdRuleConf.setMaxLength(10);
+
+ List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>();
+ pwdRuleConfs.add(pwdRuleConf);
+ pwdRuleConfs.add(pwdRuleConf2);
+ passwordGenerator.generate(pwdRuleConfs);
+ }
+
+ @Test
+ public void issueSYNCOPE678() {
+ String password = null;
+ try {
+ password = passwordGenerator.generate(Collections.<PasswordRuleConf>emptyList());
+ } catch (InvalidPasswordRuleConf e) {
+ fail(e.getMessage());
+ }
+ assertNotNull(password);
+
+ DefaultPasswordRuleConf ppSpec = createBaseDefaultPasswordRuleConf();
+ ppSpec.setMinLength(0);
+ password = null;
+ try {
+ password = passwordGenerator.generate(Collections.<PasswordRuleConf>singletonList(ppSpec));
+ } catch (InvalidPasswordRuleConf e) {
+ fail(e.getMessage());
+ }
+ assertNotNull(password);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/workflow-activiti/pom.xml
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/pom.xml b/core/workflow-activiti/pom.xml
index 07395ef..7a26ca1 100644
--- a/core/workflow-activiti/pom.xml
+++ b/core/workflow-activiti/pom.xml
@@ -68,7 +68,7 @@ under the License.
</dependency>
<dependency>
<groupId>org.apache.syncope.core</groupId>
- <artifactId>syncope-core-misc</artifactId>
+ <artifactId>syncope-core-spring</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
index 494a03e..e91f595 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java
@@ -32,7 +32,7 @@ import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.apache.commons.io.IOUtils;
-import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
+import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
import org.apache.syncope.core.workflow.activiti.spring.DomainProcessEngine;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
index 4436c52..a8a65b6 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
@@ -63,8 +63,8 @@ import org.apache.syncope.common.lib.to.WorkflowFormTO;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.common.lib.types.WorkflowFormPropertyType;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.BeanUtils;
import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
import org.apache.syncope.core.persistence.api.entity.user.User;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
index f851e08..72da026 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
@@ -32,7 +32,7 @@ import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.ProcessEngineImpl;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
/**
* {@link ProcessEngine} delegating actual method invocation to the inner map of {@link ProcessEngine} instances,
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml b/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
index 8070ac2..78c625e 100644
--- a/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
+++ b/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
@@ -25,7 +25,7 @@ under the License.
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
- <bean id="userWorkflowDef" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+ <bean id="userWorkflowDef" class="org.apache.syncope.core.spring.ResourceWithFallbackLoader">
<property name="primary" value="file:${wf.directory}/userWorkflow.bpmn20.xml"/>
<property name="fallback" value="classpath:userWorkflow.bpmn20.xml"/>
</bean>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/deb/core/pom.xml
----------------------------------------------------------------------
diff --git a/deb/core/pom.xml b/deb/core/pom.xml
index 65e5031..b26cc9c 100644
--- a/deb/core/pom.xml
+++ b/deb/core/pom.xml
@@ -156,7 +156,7 @@ under the License.
<filtering>true</filtering>
</resource>
<resource>
- <directory>${basedir}/../../core/misc/src/main/resources</directory>
+ <directory>${basedir}/../../core/spring/src/main/resources</directory>
<includes>
<include>security.properties</include>
</includes>
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
----------------------------------------------------------------------
diff --git a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
index e3401ca..3c72ed2 100644
--- a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
+++ b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java
@@ -32,8 +32,8 @@ import javax.xml.transform.stream.StreamResult;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.CamelEntitlement;
-import org.apache.syncope.core.misc.EntitlementsHolder;
-import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader;
+import org.apache.syncope.core.provisioning.api.EntitlementsHolder;
+import org.apache.syncope.core.spring.ResourceWithFallbackLoader;
import org.apache.syncope.core.persistence.api.DomainsHolder;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
import org.apache.syncope.core.persistence.api.entity.CamelRoute;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
index 1a918a5..2c1fe6d 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelUserProvisioningManager.java
@@ -36,7 +36,7 @@ import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java
index 04b3952..d86e42b 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/SyncopeCamelContext.java
@@ -29,7 +29,7 @@ import org.apache.camel.model.Constants;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.spring.SpringCamelContext;
import org.apache.commons.io.IOUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.CamelRouteDAO;
import org.apache.syncope.core.persistence.api.entity.CamelRoute;
import org.slf4j.Logger;
[14/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/EntityUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/EntityUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/EntityUtils.java
deleted file mode 100644
index e47efc8..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/EntityUtils.java
+++ /dev/null
@@ -1,41 +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.core.misc.utils;
-
-import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.core.persistence.api.entity.Entity;
-
-public final class EntityUtils {
-
- public static <KEY, E extends Entity<KEY>> Transformer<E, KEY> keyTransformer() {
- return new Transformer<E, KEY>() {
-
- @Override
- public KEY transform(final E input) {
- return input.getKey();
- }
- };
- }
-
- /**
- * Private default constructor, for static-only classes.
- */
- private EntityUtils() {
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ExceptionUtils2.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ExceptionUtils2.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ExceptionUtils2.java
deleted file mode 100644
index 76ba64f..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/ExceptionUtils2.java
+++ /dev/null
@@ -1,47 +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.core.misc.utils;
-
-import org.apache.commons.lang3.exception.ExceptionUtils;
-
-public final class ExceptionUtils2 {
-
- /**
- * Uses commons lang's ExceptionUtils to provide a representation of the full stack trace of the given throwable.
- *
- * @param t throwable to build stack trace from
- * @return a string representation of full stack trace of the given throwable
- */
- public static String getFullStackTrace(final Throwable t) {
- StringBuilder result = new StringBuilder();
-
- for (Throwable throwable : ExceptionUtils.getThrowableList(t)) {
- result.append(ExceptionUtils.getMessage(throwable)).append('\n').
- append(ExceptionUtils.getStackTrace(throwable)).append("\n\n");
- }
-
- return result.toString();
- }
-
- /**
- * Private default constructor, for static-only classes.
- */
- private ExceptionUtils2() {
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/FormatUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/FormatUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/FormatUtils.java
deleted file mode 100644
index 131f310..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/FormatUtils.java
+++ /dev/null
@@ -1,121 +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.core.misc.utils;
-
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import org.apache.commons.lang3.time.DateUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-
-/**
- * Utility class for parsing / formatting date and numbers.
- */
-public final class FormatUtils {
-
- private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
-
- @Override
- protected SimpleDateFormat initialValue() {
- SimpleDateFormat sdf = new SimpleDateFormat();
- sdf.applyPattern(SyncopeConstants.DEFAULT_DATE_PATTERN);
- return sdf;
- }
- };
-
- private static final ThreadLocal<DecimalFormat> DECIMAL_FORMAT = new ThreadLocal<DecimalFormat>() {
-
- @Override
- protected DecimalFormat initialValue() {
- DecimalFormat df = new DecimalFormat();
- df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));
- return df;
- }
- };
-
- public static String format(final Date date) {
- return format(date, true);
- }
-
- public static String format(final Date date, final boolean lenient) {
- return format(date, lenient, null);
- }
-
- public static String format(final Date date, final boolean lenient, final String conversionPattern) {
- SimpleDateFormat sdf = DATE_FORMAT.get();
- if (conversionPattern != null) {
- sdf.applyPattern(conversionPattern);
- }
- sdf.setLenient(lenient);
- return sdf.format(date);
- }
-
- public static String format(final long number) {
- return format(number, null);
- }
-
- public static String format(final long number, final String conversionPattern) {
- DecimalFormat df = DECIMAL_FORMAT.get();
- if (conversionPattern != null) {
- df.applyPattern(conversionPattern);
- }
- return df.format(number);
- }
-
- public static String format(final double number) {
- return format(number, null);
- }
-
- public static String format(final double number, final String conversionPattern) {
- DecimalFormat df = DECIMAL_FORMAT.get();
- if (conversionPattern != null) {
- df.applyPattern(conversionPattern);
- }
- return df.format(number);
- }
-
- public static Date parseDate(final String source) throws ParseException {
- return DateUtils.parseDate(source, SyncopeConstants.DATE_PATTERNS);
- }
-
- public static Date parseDate(final String source, final String conversionPattern) throws ParseException {
- SimpleDateFormat sdf = DATE_FORMAT.get();
- sdf.applyPattern(conversionPattern);
- sdf.setLenient(false);
- return sdf.parse(source);
- }
-
- public static Number parseNumber(final String source, final String conversionPattern) throws ParseException {
- DecimalFormat df = DECIMAL_FORMAT.get();
- df.applyPattern(conversionPattern);
- return df.parse(source);
- }
-
- public static void clear() {
- DATE_FORMAT.remove();
- DECIMAL_FORMAT.remove();
- }
-
- private FormatUtils() {
- // private empty constructor
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java
deleted file mode 100644
index b3102af..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/MappingUtils.java
+++ /dev/null
@@ -1,841 +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.core.misc.utils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import org.apache.commons.collections4.ListUtils;
-import org.apache.commons.jexl3.JexlContext;
-import org.apache.commons.jexl3.MapContext;
-import org.apache.commons.lang3.ClassUtils;
-import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.core.misc.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
-import org.apache.syncope.core.misc.security.Encryptor;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
-import org.apache.syncope.core.misc.security.PasswordGenerator;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.Schema;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
-import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.DerAttrHandler;
-import org.apache.syncope.core.provisioning.api.VirAttrHandler;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
-import org.identityconnectors.framework.common.FrameworkUtil;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.AttributeBuilder;
-import org.identityconnectors.framework.common.objects.AttributeUtil;
-import org.identityconnectors.framework.common.objects.Name;
-import org.identityconnectors.framework.common.objects.OperationOptions;
-import org.identityconnectors.framework.common.objects.OperationOptionsBuilder;
-import org.identityconnectors.framework.common.objects.OperationalAttributes;
-import org.identityconnectors.framework.common.objects.Uid;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-@Component
-public class MappingUtils {
-
- private static final Logger LOG = LoggerFactory.getLogger(MappingUtils.class);
-
- private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
-
- @Autowired
- private AnyTypeDAO anyTypeDAO;
-
- @Autowired
- private PlainSchemaDAO plainSchemaDAO;
-
- @Autowired
- private DerSchemaDAO derSchemaDAO;
-
- @Autowired
- private VirSchemaDAO virSchemaDAO;
-
- @Autowired
- private UserDAO userDAO;
-
- @Autowired
- private DerAttrHandler derAttrHandler;
-
- @Autowired
- private VirAttrHandler virAttrHandler;
-
- @Autowired
- private VirAttrCache virAttrCache;
-
- @Autowired
- private PasswordGenerator passwordGenerator;
-
- @Autowired
- private EntityFactory entityFactory;
-
- @Autowired
- private AnyUtilsFactory anyUtilsFactory;
-
- public static MappingItem getConnObjectKeyItem(final Provision provision) {
- Mapping mapping = null;
- if (provision != null) {
- mapping = provision.getMapping();
- }
-
- return mapping == null
- ? null
- : mapping.getConnObjectKeyItem();
- }
-
- private static List<MappingItem> getMappingItems(final Provision provision, final MappingPurpose purpose) {
- List<? extends MappingItem> items = Collections.<MappingItem>emptyList();
- if (provision != null) {
- items = provision.getMapping().getItems();
- }
-
- List<MappingItem> result = new ArrayList<>();
-
- switch (purpose) {
- case SYNCHRONIZATION:
- for (MappingItem item : items) {
- if (MappingPurpose.PROPAGATION != item.getPurpose()
- && MappingPurpose.NONE != item.getPurpose()) {
-
- result.add(item);
- }
- }
- break;
-
- case PROPAGATION:
- for (MappingItem item : items) {
- if (MappingPurpose.SYNCHRONIZATION != item.getPurpose()
- && MappingPurpose.NONE != item.getPurpose()) {
-
- result.add(item);
- }
- }
- break;
-
- case BOTH:
- for (MappingItem item : items) {
- if (MappingPurpose.NONE != item.getPurpose()) {
- result.add(item);
- }
- }
- break;
-
- case NONE:
- for (MappingItem item : items) {
- if (MappingPurpose.NONE == item.getPurpose()) {
- result.add(item);
- }
- }
- break;
-
- default:
- }
-
- return result;
- }
-
- public static List<MappingItem> getBothMappingItems(final Provision provision) {
- return getMappingItems(provision, MappingPurpose.BOTH);
- }
-
- public static List<MappingItem> getPropagationMappingItems(final Provision provision) {
- return getMappingItems(provision, MappingPurpose.PROPAGATION);
- }
-
- public static List<MappingItem> getSyncMappingItems(final Provision provision) {
- return getMappingItems(provision, MappingPurpose.SYNCHRONIZATION);
- }
-
- /**
- * Build __NAME__ for propagation. First look if there ia a defined connObjectLink for the given resource (and in
- * this case evaluate as JEXL); otherwise, take given connObjectKey.
- *
- * @param any given any object
- * @param provision external resource
- * @param connObjectKey connector object key
- * @return the value to be propagated as __NAME__
- */
- public static Name evaluateNAME(final Any<?> any, final Provision provision, final String connObjectKey) {
- if (StringUtils.isBlank(connObjectKey)) {
- // LOG error but avoid to throw exception: leave it to the external resource
- LOG.error("Missing ConnObjectKey for '{}': ", provision.getResource());
- }
-
- // Evaluate connObjectKey expression
- String connObjectLink = provision == null || provision.getMapping() == null
- ? null
- : provision.getMapping().getConnObjectLink();
- String evalConnObjectLink = null;
- if (StringUtils.isNotBlank(connObjectLink)) {
- JexlContext jexlContext = new MapContext();
- JexlUtils.addFieldsToContext(any, jexlContext);
- JexlUtils.addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
- JexlUtils.addDerAttrsToContext(any, jexlContext);
- evalConnObjectLink = JexlUtils.evaluate(connObjectLink, jexlContext);
- }
-
- // If connObjectLink evaluates to an empty string, just use the provided connObjectKey as Name(),
- // otherwise evaluated connObjectLink expression is taken as Name().
- Name name;
- if (StringUtils.isBlank(evalConnObjectLink)) {
- // add connObjectKey as __NAME__ attribute ...
- LOG.debug("Add connObjectKey [{}] as __NAME__", connObjectKey);
- name = new Name(connObjectKey);
- } else {
- LOG.debug("Add connObjectLink [{}] as __NAME__", evalConnObjectLink);
- name = new Name(evalConnObjectLink);
-
- // connObjectKey not propagated: it will be used to set the value for __UID__ attribute
- LOG.debug("connObjectKey will be used just as __UID__ attribute");
- }
-
- return name;
- }
-
- public static List<MappingItemTransformer> getMappingItemTransformers(final MappingItem mappingItem) {
- List<MappingItemTransformer> result = new ArrayList<>();
-
- for (String className : mappingItem.getMappingItemTransformerClassNames()) {
- try {
- Class<?> transformerClass = ClassUtils.getClass(className);
-
- result.add((MappingItemTransformer) ApplicationContextProvider.
- getBeanFactory().
- createBean(transformerClass, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false));
- } catch (Exception e) {
- LOG.error("Could not instantiate {}, ignoring...", className, e);
- }
- }
-
- return result;
- }
-
- /**
- * Build options for requesting all mapped connector attributes.
- *
- * @param mapItems mapping items
- * @return options for requesting all mapped connector attributes
- * @see OperationOptions
- */
- public static OperationOptions buildOperationOptions(final Iterator<? extends MappingItem> mapItems) {
- OperationOptionsBuilder builder = new OperationOptionsBuilder();
-
- Set<String> attrsToGet = new HashSet<>();
- attrsToGet.add(Name.NAME);
- attrsToGet.add(Uid.NAME);
- attrsToGet.add(OperationalAttributes.ENABLE_NAME);
-
- while (mapItems.hasNext()) {
- MappingItem mapItem = mapItems.next();
- if (mapItem.getPurpose() != MappingPurpose.NONE) {
- attrsToGet.add(mapItem.getExtAttrName());
- }
- }
-
- builder.setAttributesToGet(attrsToGet);
- // -------------------------------------
-
- return builder.build();
- }
-
- /**
- * Prepare attributes for sending to a connector instance.
- *
- * @param any given any object
- * @param password clear-text password
- * @param changePwd whether password should be included for propagation attributes or not
- * @param enable whether any object must be enabled or not
- * @param provision provision information
- * @return connObjectLink + prepared attributes
- */
- @Transactional(readOnly = true)
- public Pair<String, Set<Attribute>> prepareAttrs(
- final Any<?> any,
- final String password,
- final boolean changePwd,
- final Boolean enable,
- final Provision provision) {
-
- LOG.debug("Preparing resource attributes for {} with provision {} for attributes {}",
- any, provision, any.getPlainAttrs());
-
- Set<Attribute> attributes = new HashSet<>();
- String connObjectKey = null;
-
- for (MappingItem mappingItem : getMappingItems(provision, MappingPurpose.PROPAGATION)) {
- LOG.debug("Processing schema {}", mappingItem.getIntAttrName());
-
- try {
- Pair<String, Attribute> preparedAttr = prepareAttr(provision, mappingItem, any, password);
-
- if (preparedAttr != null && preparedAttr.getKey() != null) {
- connObjectKey = preparedAttr.getKey();
- }
-
- if (preparedAttr != null && preparedAttr.getValue() != null) {
- Attribute alreadyAdded = AttributeUtil.find(preparedAttr.getValue().getName(), attributes);
-
- if (alreadyAdded == null) {
- attributes.add(preparedAttr.getValue());
- } else {
- attributes.remove(alreadyAdded);
-
- Set<Object> values = new HashSet<>(alreadyAdded.getValue());
- values.addAll(preparedAttr.getValue().getValue());
-
- attributes.add(AttributeBuilder.build(preparedAttr.getValue().getName(), values));
- }
- }
- } catch (Exception e) {
- LOG.debug("Attribute '{}' processing failed", mappingItem.getIntAttrName(), e);
- }
- }
-
- Attribute connObjectKeyExtAttr =
- AttributeUtil.find(getConnObjectKeyItem(provision).getExtAttrName(), attributes);
- if (connObjectKeyExtAttr != null) {
- attributes.remove(connObjectKeyExtAttr);
- attributes.add(AttributeBuilder.build(getConnObjectKeyItem(provision).getExtAttrName(), connObjectKey));
- }
- attributes.add(evaluateNAME(any, provision, connObjectKey));
-
- if (enable != null) {
- attributes.add(AttributeBuilder.buildEnabled(enable));
- }
- if (!changePwd) {
- Attribute pwdAttr = AttributeUtil.find(OperationalAttributes.PASSWORD_NAME, attributes);
- if (pwdAttr != null) {
- attributes.remove(pwdAttr);
- }
- }
-
- return new ImmutablePair<>(connObjectKey, attributes);
- }
-
- /**
- * Prepare an attribute to be sent to a connector instance.
- *
- * @param provision external resource
- * @param mapItem mapping item for the given attribute
- * @param any any object
- * @param password clear-text password
- * @return connObjectKey + prepared attribute
- */
- private Pair<String, Attribute> prepareAttr(
- final Provision provision, final MappingItem mapItem, final Any<?> any, final String password) {
-
- List<Any<?>> anys = new ArrayList<>();
-
- switch (mapItem.getIntMappingType().getAnyTypeKind()) {
- case USER:
- if (any instanceof User) {
- anys.add(any);
- }
- break;
-
- case GROUP:
- if (any instanceof User) {
- for (Group group : userDAO.findAllGroups((User) any)) {
- anys.add(group);
- }
- } else if (any instanceof Group) {
- anys.add(any);
- }
- break;
-
- case ANY_OBJECT:
- if (any instanceof AnyObject) {
- anys.add(any);
- }
- break;
-
- default:
- }
-
- Schema schema = null;
- boolean readOnlyVirSchema = false;
- AttrSchemaType schemaType;
- Pair<String, Attribute> result;
-
- switch (mapItem.getIntMappingType()) {
- case UserPlainSchema:
- case GroupPlainSchema:
- case AnyObjectPlainSchema:
- schema = plainSchemaDAO.find(mapItem.getIntAttrName());
- schemaType = schema == null ? AttrSchemaType.String : schema.getType();
- break;
-
- case UserVirtualSchema:
- case GroupVirtualSchema:
- case AnyObjectVirtualSchema:
- schema = virSchemaDAO.find(mapItem.getIntAttrName());
- readOnlyVirSchema = (schema != null && schema.isReadonly());
- schemaType = AttrSchemaType.String;
- break;
-
- default:
- schemaType = AttrSchemaType.String;
- }
-
- String extAttrName = mapItem.getExtAttrName();
-
- List<PlainAttrValue> values = getIntValues(provision, mapItem, anys);
-
- LOG.debug("Define mapping for: "
- + "\n* ExtAttrName " + extAttrName
- + "\n* is connObjectKey " + mapItem.isConnObjectKey()
- + "\n* is password " + (mapItem.isPassword() || mapItem.getIntMappingType() == IntMappingType.Password)
- + "\n* mandatory condition " + mapItem.getMandatoryCondition()
- + "\n* Schema " + mapItem.getIntAttrName()
- + "\n* IntMappingType " + mapItem.getIntMappingType().toString()
- + "\n* ClassType " + schemaType.getType().getName()
- + "\n* Values " + values);
-
- if (readOnlyVirSchema) {
- result = null;
- } else {
- List<Object> objValues = new ArrayList<>();
-
- for (PlainAttrValue value : values) {
- if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) {
- objValues.add(value.getValue());
- } else {
- objValues.add(value.getValueAsString());
- }
- }
-
- if (mapItem.isConnObjectKey()) {
- result = new ImmutablePair<>(objValues.iterator().next().toString(), null);
- } else if (mapItem.isPassword() && any instanceof User) {
- String passwordAttrValue = password;
- if (StringUtils.isBlank(passwordAttrValue)) {
- User user = (User) any;
- if (user.canDecodePassword()) {
- try {
- passwordAttrValue = ENCRYPTOR.decode(user.getPassword(), user.getCipherAlgorithm());
- } catch (Exception e) {
- LOG.error("Could not decode password for {}", user, e);
- }
- } else if (provision.getResource().isRandomPwdIfNotProvided()) {
- try {
- passwordAttrValue = passwordGenerator.generate(user);
- } catch (InvalidPasswordRuleConf e) {
- LOG.error("Could not generate policy-compliant random password for {}", user, e);
- }
- }
- }
-
- if (passwordAttrValue == null) {
- result = null;
- } else {
- result = new ImmutablePair<>(
- null, AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()));
- }
- } else if ((schema != null && schema.isMultivalue())
- || anyUtilsFactory.getInstance(any).getAnyTypeKind()
- != mapItem.getIntMappingType().getAnyTypeKind()) {
-
- result = new ImmutablePair<>(
- null, AttributeBuilder.build(extAttrName, objValues));
- } else {
- result = new ImmutablePair<>(
- null, objValues.isEmpty()
- ? AttributeBuilder.build(extAttrName)
- : AttributeBuilder.build(extAttrName, objValues.iterator().next()));
- }
- }
-
- return result;
- }
-
- private String getGroupOwnerValue(final Provision provision, final Any<?> any) {
- Pair<String, Attribute> preparedAttr = prepareAttr(provision, getConnObjectKeyItem(provision), any, null);
- String connObjectKey = preparedAttr.getKey();
-
- return evaluateNAME(any, provision, connObjectKey).getNameValue();
- }
-
- /**
- * Get attribute values for the given {@link MappingItem} and any objects.
- *
- * @param provision provision information
- * @param mappingItem mapping item
- * @param anys any objects
- * @return attribute values.
- */
- @Transactional(readOnly = true)
- public List<PlainAttrValue> getIntValues(final Provision provision,
- final MappingItem mappingItem, final List<Any<?>> anys) {
-
- LOG.debug("Get attributes for '{}' and mapping type '{}'", anys, mappingItem.getIntMappingType());
-
- boolean transform = true;
-
- List<PlainAttrValue> values = new ArrayList<>();
- switch (mappingItem.getIntMappingType()) {
- case UserPlainSchema:
- case GroupPlainSchema:
- case AnyObjectPlainSchema:
- for (Any<?> any : anys) {
- PlainAttr<?> attr = any.getPlainAttr(mappingItem.getIntAttrName());
- if (attr != null) {
- if (attr.getUniqueValue() != null) {
- PlainAttrUniqueValue value = SerializationUtils.clone(attr.getUniqueValue());
- value.setAttr(null);
- values.add(value);
- } else if (attr.getValues() != null) {
- for (PlainAttrValue value : attr.getValues()) {
- PlainAttrValue shadow = SerializationUtils.clone(value);
- shadow.setAttr(null);
- values.add(shadow);
- }
- }
- }
-
- LOG.debug("Retrieved attribute {}"
- + "\n* IntAttrName {}"
- + "\n* IntMappingType {}"
- + "\n* Attribute values {}",
- attr, mappingItem.getIntAttrName(), mappingItem.getIntMappingType(), values);
- }
-
- break;
-
- case UserDerivedSchema:
- case GroupDerivedSchema:
- case AnyObjectDerivedSchema:
- DerSchema derSchema = derSchemaDAO.find(mappingItem.getIntAttrName());
- if (derSchema != null) {
- for (Any<?> any : anys) {
- String value = derAttrHandler.getValue(any, derSchema);
- if (value != null) {
- AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
- PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
- attrValue.setStringValue(value);
- values.add(attrValue);
-
- LOG.debug("Retrieved values for {}"
- + "\n* IntAttrName {}"
- + "\n* IntMappingType {}"
- + "\n* Attribute values {}",
- derSchema.getKey(), mappingItem.getIntAttrName(), mappingItem.getIntMappingType(),
- values);
- }
- }
- }
- break;
-
- case UserVirtualSchema:
- case GroupVirtualSchema:
- case AnyObjectVirtualSchema:
- // virtual attributes don't get transformed
- transform = false;
-
- VirSchema virSchema = virSchemaDAO.find(mappingItem.getIntAttrName());
- if (virSchema != null) {
- for (Any<?> any : anys) {
- LOG.debug("Expire entry cache {}-{}", any.getKey(), mappingItem.getIntAttrName());
- virAttrCache.expire(any.getType().getKey(), any.getKey(), mappingItem.getIntAttrName());
-
- AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
- for (String value : virAttrHandler.getValues(any, virSchema)) {
- PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
- attrValue.setStringValue(value);
- values.add(attrValue);
- }
-
- LOG.debug("Retrieved values for {}"
- + "\n* IntAttrName {}"
- + "\n* IntMappingType {}"
- + "\n* Attribute values {}",
- virSchema.getKey(), mappingItem.getIntAttrName(), mappingItem.getIntMappingType(),
- values);
- }
- }
- break;
-
- case UserKey:
- case GroupKey:
- case AnyObjectKey:
- for (Any<?> any : anys) {
- AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
- PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
- attrValue.setStringValue(any.getKey().toString());
- values.add(attrValue);
- }
- break;
-
- case Username:
- for (Any<?> any : anys) {
- if (any instanceof User) {
- UPlainAttrValue attrValue = entityFactory.newEntity(UPlainAttrValue.class);
- attrValue.setStringValue(((User) any).getUsername());
- values.add(attrValue);
- }
- }
- break;
-
- case GroupName:
- for (Any<?> any : anys) {
- if (any instanceof Group) {
- GPlainAttrValue attrValue = entityFactory.newEntity(GPlainAttrValue.class);
- attrValue.setStringValue(((Group) any).getName());
- values.add(attrValue);
- }
- }
- break;
-
- case GroupOwnerSchema:
- Mapping uMapping = provision.getAnyType().equals(anyTypeDAO.findUser())
- ? provision.getMapping()
- : null;
- Mapping gMapping = provision.getAnyType().equals(anyTypeDAO.findGroup())
- ? provision.getMapping()
- : null;
-
- for (Any<?> any : anys) {
- if (any instanceof Group) {
- Group group = (Group) any;
- String groupOwnerValue = null;
- if (group.getUserOwner() != null && uMapping != null) {
- groupOwnerValue = getGroupOwnerValue(provision, group.getUserOwner());
- }
- if (group.getGroupOwner() != null && gMapping != null) {
- groupOwnerValue = getGroupOwnerValue(provision, group.getGroupOwner());
- }
-
- if (StringUtils.isNotBlank(groupOwnerValue)) {
- GPlainAttrValue attrValue = entityFactory.newEntity(GPlainAttrValue.class);
- attrValue.setStringValue(groupOwnerValue);
- values.add(attrValue);
- }
- }
- }
- break;
-
- default:
- }
-
- LOG.debug("Values for propagation: {}", values);
-
- List<PlainAttrValue> transformed = values;
- if (transform) {
- for (MappingItemTransformer transformer : getMappingItemTransformers(mappingItem)) {
- transformed = transformer.beforePropagation(transformed);
- }
- LOG.debug("Transformed values for propagation: {}", values);
- } else {
- LOG.debug("No transformation occurred");
- }
-
- return transformed;
- }
-
- /**
- * Get connObjectKey internal value.
- *
- * @param any any object
- * @param provision provision information
- * @return connObjectKey internal value
- */
- @Transactional(readOnly = true)
- public String getConnObjectKeyValue(final Any<?> any, final Provision provision) {
- List<PlainAttrValue> values = getIntValues(provision, provision.getMapping().getConnObjectKeyItem(),
- Collections.<Any<?>>singletonList(any));
- return values == null || values.isEmpty()
- ? null
- : values.get(0).getValueAsString();
- }
-
- /**
- * Set attribute values, according to the given {@link MappingItem}, to any object from attribute received from
- * connector.
- *
- * @param <T> any object
- * @param mappingItem mapping item
- * @param attr attribute received from connector
- * @param anyTO any object
- * @param anyUtils any utils
- */
- @Transactional(readOnly = true)
- public <T extends AnyTO> void setIntValues(
- final MappingItem mappingItem, final Attribute attr, final T anyTO, final AnyUtils anyUtils) {
-
- List<Object> values = null;
- if (attr != null) {
- values = attr.getValue();
- for (MappingItemTransformer transformer : getMappingItemTransformers(mappingItem)) {
- values = transformer.beforeSync(values);
- }
- }
- values = ListUtils.emptyIfNull(values);
-
- switch (mappingItem.getIntMappingType()) {
- case UserKey:
- case GroupKey:
- case AnyObjectKey:
- break;
-
- case Password:
- if (anyTO instanceof UserTO && !values.isEmpty()) {
- ((UserTO) anyTO).setPassword(ConnObjectUtils.getPassword(values.get(0)));
- }
- break;
-
- case Username:
- if (anyTO instanceof UserTO) {
- ((UserTO) anyTO).setUsername(values.isEmpty() || values.get(0) == null
- ? null
- : values.get(0).toString());
- }
- break;
-
- case GroupName:
- if (anyTO instanceof GroupTO) {
- ((GroupTO) anyTO).setName(values.isEmpty() || values.get(0) == null
- ? null
- : values.get(0).toString());
- }
- break;
-
- case GroupOwnerSchema:
- if (anyTO instanceof GroupTO && attr != null) {
- // using a special attribute (with schema "", that will be ignored) for carrying the
- // GroupOwnerSchema value
- AttrTO attrTO = new AttrTO();
- attrTO.setSchema(StringUtils.EMPTY);
- if (values.isEmpty() || values.get(0) == null) {
- attrTO.getValues().add(StringUtils.EMPTY);
- } else {
- attrTO.getValues().add(values.get(0).toString());
- }
-
- ((GroupTO) anyTO).getPlainAttrs().add(attrTO);
- }
- break;
-
- case UserPlainSchema:
- case GroupPlainSchema:
- case AnyObjectPlainSchema:
- AttrTO attrTO = new AttrTO();
- attrTO.setSchema(mappingItem.getIntAttrName());
-
- PlainSchema schema = plainSchemaDAO.find(mappingItem.getIntAttrName());
-
- for (Object value : values) {
- AttrSchemaType schemaType = schema == null ? AttrSchemaType.String : schema.getType();
- if (value != null) {
- PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
- switch (schemaType) {
- case String:
- attrValue.setStringValue(value.toString());
- break;
-
- case Binary:
- attrValue.setBinaryValue((byte[]) value);
- break;
-
- default:
- try {
- attrValue.parseValue(schema, value.toString());
- } catch (ParsingValidationException e) {
- LOG.error("While parsing provided value {}", value, e);
- attrValue.setStringValue(value.toString());
- schemaType = AttrSchemaType.String;
- }
- break;
- }
- attrTO.getValues().add(attrValue.getValueAsString(schemaType));
- }
- }
-
- anyTO.getPlainAttrs().add(attrTO);
- break;
-
- case UserDerivedSchema:
- case GroupDerivedSchema:
- case AnyObjectDerivedSchema:
- attrTO = new AttrTO();
- attrTO.setSchema(mappingItem.getIntAttrName());
- anyTO.getDerAttrs().add(attrTO);
- break;
-
- case UserVirtualSchema:
- case GroupVirtualSchema:
- case AnyObjectVirtualSchema:
- attrTO = new AttrTO();
- attrTO.setSchema(mappingItem.getIntAttrName());
-
- // virtual attributes don't get transformed, iterate over original attr.getValue()
- for (Object value : (attr == null || attr.getValue() == null)
- ? Collections.emptyList() : attr.getValue()) {
-
- if (value != null) {
- attrTO.getValues().add(value.toString());
- }
- }
-
- anyTO.getVirAttrs().add(attrTO);
- break;
-
- default:
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/RealmUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/RealmUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/RealmUtils.java
deleted file mode 100644
index f3c0a46..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/RealmUtils.java
+++ /dev/null
@@ -1,63 +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.core.misc.utils;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-public final class RealmUtils {
-
- public static String getGroupOwnerRealm(final String realmPath, final Long groupKey) {
- return realmPath + "@" + groupKey;
- }
-
- public static boolean normalizingAddTo(final Set<String> realms, final String newRealm) {
- boolean dontAdd = false;
- Set<String> toRemove = new HashSet<>();
- for (String realm : realms) {
- if (newRealm.startsWith(realm)) {
- dontAdd = true;
- } else if (realm.startsWith(newRealm)) {
- toRemove.add(realm);
- }
- }
-
- realms.removeAll(toRemove);
- if (!dontAdd) {
- realms.add(newRealm);
- }
- return !dontAdd;
- }
-
- public static Set<String> normalize(final Collection<String> realms) {
- Set<String> normalized = new HashSet<>();
- if (realms != null) {
- for (String realm : realms) {
- normalizingAddTo(normalized, realm);
- }
- }
-
- return normalized;
- }
-
- private RealmUtils() {
- // empty constructor for static utility class
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java
deleted file mode 100644
index e09e0e2..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/utils/TemplateUtils.java
+++ /dev/null
@@ -1,224 +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.core.misc.utils;
-
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.to.RelationshipTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-@Component
-public class TemplateUtils {
-
- @Autowired
- private UserDAO userDAO;
-
- @Autowired
- private GroupDAO groupDAO;
-
- private AttrTO evaluateAttr(final AnyTO anyTO, final AttrTO template) {
- AttrTO result = new AttrTO();
- result.setSchema(template.getSchema());
-
- if (template.getValues() != null && !template.getValues().isEmpty()) {
- for (String value : template.getValues()) {
- String evaluated = JexlUtils.evaluate(value, anyTO);
- if (StringUtils.isNotBlank(evaluated)) {
- result.getValues().add(evaluated);
- }
- }
- }
-
- return result;
- }
-
- private void fill(final AnyTO anyTO, final AnyTO template) {
- if (template.getRealm() != null) {
- anyTO.setRealm(template.getRealm());
- }
-
- Map<String, AttrTO> currentAttrMap = anyTO.getPlainAttrMap();
- for (AttrTO templatePlainAttr : template.getPlainAttrs()) {
- if (!templatePlainAttr.getValues().isEmpty()
- && (!currentAttrMap.containsKey(templatePlainAttr.getSchema())
- || currentAttrMap.get(templatePlainAttr.getSchema()).getValues().isEmpty())) {
-
- anyTO.getPlainAttrs().add(evaluateAttr(anyTO, templatePlainAttr));
- }
- }
-
- currentAttrMap = anyTO.getDerAttrMap();
- for (AttrTO templateDerAttr : template.getDerAttrs()) {
- if (!currentAttrMap.containsKey(templateDerAttr.getSchema())) {
- anyTO.getDerAttrs().add(templateDerAttr);
- }
- }
-
- currentAttrMap = anyTO.getVirAttrMap();
- for (AttrTO templateVirAttr : template.getVirAttrs()) {
- if (!templateVirAttr.getValues().isEmpty()
- && (!currentAttrMap.containsKey(templateVirAttr.getSchema())
- || currentAttrMap.get(templateVirAttr.getSchema()).getValues().isEmpty())) {
-
- anyTO.getVirAttrs().add(evaluateAttr(anyTO, templateVirAttr));
- }
- }
-
- for (String resource : template.getResources()) {
- anyTO.getResources().add(resource);
- }
-
- anyTO.getAuxClasses().addAll(template.getAuxClasses());
- }
-
- private void fillRelationships(final Map<Pair<String, Long>, RelationshipTO> anyRelMap,
- final List<RelationshipTO> anyRels, final List<RelationshipTO> templateRels) {
-
- for (RelationshipTO memb : templateRels) {
- if (!anyRelMap.containsKey(Pair.of(memb.getRightType(), memb.getRightKey()))) {
- anyRels.add(memb);
- }
- }
- }
-
- private void fillMemberships(final Map<Long, MembershipTO> anyMembMap,
- final List<MembershipTO> anyMembs, final List<MembershipTO> templateMembs) {
-
- for (MembershipTO memb : templateMembs) {
- if (!anyMembMap.containsKey(memb.getRightKey())) {
- anyMembs.add(memb);
- }
- }
- }
-
- @Transactional(readOnly = true)
- public <T extends AnyTO> void apply(final T anyTO, final AnyTemplate anyTemplate) {
- if (anyTemplate != null) {
- AnyTO template = anyTemplate.get();
- fill(anyTO, template);
-
- if (template instanceof AnyObjectTO) {
- fillRelationships(((AnyObjectTO) anyTO).getRelationshipMap(),
- ((AnyObjectTO) anyTO).getRelationships(), ((AnyObjectTO) template).getRelationships());
- fillMemberships(((AnyObjectTO) anyTO).getMembershipMap(),
- ((AnyObjectTO) anyTO).getMemberships(), ((AnyObjectTO) template).getMemberships());
- } else if (template instanceof UserTO) {
- if (StringUtils.isNotBlank(((UserTO) template).getUsername())) {
- String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), anyTO);
- if (StringUtils.isNotBlank(evaluated)) {
- ((UserTO) anyTO).setUsername(evaluated);
- }
- }
-
- if (StringUtils.isNotBlank(((UserTO) template).getPassword())) {
- String evaluated = JexlUtils.evaluate(((UserTO) template).getPassword(), anyTO);
- if (StringUtils.isNotBlank(evaluated)) {
- ((UserTO) anyTO).setPassword(evaluated);
- }
- }
-
- fillRelationships(((UserTO) anyTO).getRelationshipMap(),
- ((UserTO) anyTO).getRelationships(), ((UserTO) template).getRelationships());
- fillMemberships(((UserTO) anyTO).getMembershipMap(),
- ((UserTO) anyTO).getMemberships(), ((UserTO) template).getMemberships());
- } else if (template instanceof GroupTO) {
- if (StringUtils.isNotBlank(((GroupTO) template).getName())) {
- String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), anyTO);
- if (StringUtils.isNotBlank(evaluated)) {
- ((GroupTO) anyTO).setName(evaluated);
- }
- }
-
- if (((GroupTO) template).getUserOwner() != null) {
- final User userOwner = userDAO.find(((GroupTO) template).getUserOwner());
- if (userOwner != null) {
- ((GroupTO) anyTO).setUserOwner(userOwner.getKey());
- }
- }
- if (((GroupTO) template).getGroupOwner() != null) {
- final Group groupOwner = groupDAO.find(((GroupTO) template).getGroupOwner());
- if (groupOwner != null) {
- ((GroupTO) anyTO).setGroupOwner(groupOwner.getKey());
- }
- }
- }
- }
- }
-
- public void check(final Map<String, AnyTO> templates, final ClientExceptionType clientExceptionType) {
- SyncopeClientException sce = SyncopeClientException.build(clientExceptionType);
-
- for (Map.Entry<String, AnyTO> entry : templates.entrySet()) {
- for (AttrTO attrTO : entry.getValue().getPlainAttrs()) {
- if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
- sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
- }
- }
-
- for (AttrTO attrTO : entry.getValue().getVirAttrs()) {
- if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
- sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
- }
- }
-
- if (entry.getValue() instanceof UserTO) {
- UserTO template = (UserTO) entry.getValue();
- if (StringUtils.isNotBlank(template.getUsername())
- && !JexlUtils.isExpressionValid(template.getUsername())) {
-
- sce.getElements().add("Invalid JEXL: " + template.getUsername());
- }
- if (StringUtils.isNotBlank(template.getPassword())
- && !JexlUtils.isExpressionValid(template.getPassword())) {
-
- sce.getElements().add("Invalid JEXL: " + template.getPassword());
- }
- } else if (entry.getValue() instanceof GroupTO) {
- GroupTO template = (GroupTO) entry.getValue();
- if (StringUtils.isNotBlank(template.getName())
- && !JexlUtils.isExpressionValid(template.getName())) {
-
- sce.getElements().add("Invalid JEXL: " + template.getName());
- }
- }
- }
-
- if (!sce.isEmpty()) {
- throw sce;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/resources/security.properties
----------------------------------------------------------------------
diff --git a/core/misc/src/main/resources/security.properties b/core/misc/src/main/resources/security.properties
deleted file mode 100644
index 73db510..0000000
--- a/core/misc/src/main/resources/security.properties
+++ /dev/null
@@ -1,32 +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.
-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
-
-passwordGenerator=org.apache.syncope.core.misc.security.DefaultPasswordGenerator
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/resources/securityContext.xml
----------------------------------------------------------------------
diff --git a/core/misc/src/main/resources/securityContext.xml b/core/misc/src/main/resources/securityContext.xml
deleted file mode 100644
index 222d64a..0000000
--- a/core/misc/src/main/resources/securityContext.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?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:security="http://www.springframework.org/schema/security"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/security
- http://www.springframework.org/schema/security/spring-security.xsd">
-
- <bean id="adminUser" class="java.lang.String">
- <constructor-arg value="${adminUser}"/>
- </bean>
- <bean id="anonymousUser" class="java.lang.String">
- <constructor-arg value="${anonymousUser}"/>
- </bean>
-
- <bean class="${passwordGenerator}"/>
- <bean class="org.apache.syncope.core.misc.spring.DefaultRolesPrefixPostProcessor"/>
-
- <security:global-method-security pre-post-annotations="enabled"/>
-
- <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
- <security:filter-chain-map request-matcher="ant">
- <security:filter-chain pattern="/**" filters="securityContextPersistenceFilter"/>
- </security:filter-chain-map>
- </bean>
-
- <bean id="securityContextRepository" class='org.springframework.security.web.context.NullSecurityContextRepository'/>
-
- <bean id="securityContextPersistenceFilter"
- class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
- <constructor-arg ref="securityContextRepository"/>
- </bean>
-
- <bean id="syncopeAuthenticationDetailsSource"
- class="org.apache.syncope.core.misc.security.SyncopeAuthenticationDetailsSource"/>
-
- <bean id="mustChangePasswordFilter" class="org.apache.syncope.core.misc.security.MustChangePasswordFilter"/>
-
- <bean id="syncopeAuthenticationEntryPoint"
- class="org.apache.syncope.core.misc.security.SyncopeAuthenticationEntryPoint">
- <property name="realmName" value="Apache Syncope authentication"/>
- </bean>
-
- <bean id="syncopeAccessDeniedHandler" class="org.apache.syncope.core.misc.security.SyncopeAccessDeniedHandler"/>
-
- <security:http security-context-repository-ref="securityContextRepository"
- use-expressions="false" disable-url-rewriting="false">
-
- <security:http-basic entry-point-ref="syncopeAuthenticationEntryPoint"
- authentication-details-source-ref="syncopeAuthenticationDetailsSource"/>
- <security:anonymous username="${anonymousUser}"/>
- <security:intercept-url pattern="/**"/>
-
- <security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="mustChangePasswordFilter"/>
-
- <security:access-denied-handler ref="syncopeAccessDeniedHandler"/>
-
- <security:headers disabled="true"/>
- <security:csrf disabled="true"/>
- </security:http>
-
- <bean class="org.apache.syncope.core.misc.security.AuthDataAccessor"/>
-
- <bean id="syncopeUserDetailsService" class="org.apache.syncope.core.misc.security.SyncopeUserDetailsService"/>
-
- <bean id="syncopeAuthenticationProvider" class="org.apache.syncope.core.misc.security.SyncopeAuthenticationProvider">
- <property name="adminPassword" value="${adminPassword}"/>
- <property name="adminPasswordAlgorithm" value="${adminPasswordAlgorithm}"/>
- <property name="anonymousKey" value="${anonymousKey}"/>
- <property name="userDetailsService" ref="syncopeUserDetailsService"/>
- </bean>
-
- <security:authentication-manager>
- <security:authentication-provider ref="syncopeAuthenticationProvider"/>
- </security:authentication-manager>
-</beans>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/main/resources/utilsContext.xml
----------------------------------------------------------------------
diff --git a/core/misc/src/main/resources/utilsContext.xml b/core/misc/src/main/resources/utilsContext.xml
deleted file mode 100644
index 7b2c9b3..0000000
--- a/core/misc/src/main/resources/utilsContext.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?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.core.misc.AuditManager"/>
-
- <context:component-scan base-package="org.apache.syncope.core.misc.utils"/>
-
-</beans>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
----------------------------------------------------------------------
diff --git a/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java b/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
deleted file mode 100644
index 189b575..0000000
--- a/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
+++ /dev/null
@@ -1,226 +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.core.misc.search;
-
-import static org.junit.Assert.assertEquals;
-
-import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
-import org.apache.syncope.common.lib.search.GroupFiqlSearchConditionBuilder;
-import org.apache.syncope.common.lib.search.SpecialAttr;
-import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
-import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
-import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
-import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
-import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
-import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
-import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
-import org.junit.Test;
-
-public class SearchCondConverterTest {
-
- @Test
- public void eq() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("rossini").query();
- assertEquals("username==rossini", fiqlExpression);
-
- AnyCond attrCond = new AnyCond(AttributeCond.Type.EQ);
- attrCond.setSchema("username");
- attrCond.setExpression("rossini");
- SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
-
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
- }
-
- @Test
- public void like() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("username").equalTo("ros*").query();
- assertEquals("username==ros*", fiqlExpression);
-
- AttributeCond attrCond = new AnyCond(AttributeCond.Type.LIKE);
- attrCond.setSchema("username");
- attrCond.setExpression("ros%");
- SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
-
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
- }
-
- @Test
- public void isNull() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").nullValue().query();
- assertEquals("loginDate==" + SpecialAttr.NULL, fiqlExpression);
-
- AttributeCond attrCond = new AttributeCond(AttributeCond.Type.ISNULL);
- attrCond.setSchema("loginDate");
- SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
-
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
- }
-
- @Test
- public void isNotNull() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().is("loginDate").notNullValue().query();
- assertEquals("loginDate!=" + SpecialAttr.NULL, fiqlExpression);
-
- AttributeCond attrCond = new AttributeCond(AttributeCond.Type.ISNOTNULL);
- attrCond.setSchema("loginDate");
- SearchCond simpleCond = SearchCond.getLeafCond(attrCond);
-
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
- }
-
- @Test
- public void relationships() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().inRelationships(1L).query();
- assertEquals(SpecialAttr.RELATIONSHIPS + "==1", fiqlExpression);
-
- RelationshipCond relationshipCond = new RelationshipCond();
- relationshipCond.setAnyObjectKey(1L);
- SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
-
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
- }
-
- @Test
- public void relationshipTypes() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().inRelationshipTypes("type1").query();
- assertEquals(SpecialAttr.RELATIONSHIP_TYPES + "==type1", fiqlExpression);
-
- RelationshipTypeCond relationshipCond = new RelationshipTypeCond();
- relationshipCond.setRelationshipTypeKey("type1");
- SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
-
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
-
- fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").inRelationshipTypes("neighborhood").query();
- assertEquals(
- SpecialAttr.RELATIONSHIP_TYPES + "==neighborhood;" + SpecialAttr.TYPE + "==PRINTER",
- fiqlExpression);
- }
-
- @Test
- public void groups() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().inGroups(1L).query();
- assertEquals(SpecialAttr.GROUPS + "==1", fiqlExpression);
-
- MembershipCond groupCond = new MembershipCond();
- groupCond.setGroupKey(1L);
- SearchCond simpleCond = SearchCond.getLeafCond(groupCond);
-
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
- }
-
- @Test
- public void roles() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().inRoles("User reviewer").query();
- assertEquals(SpecialAttr.ROLES + "==User reviewer", fiqlExpression);
-
- RoleCond roleCond = new RoleCond();
- roleCond.setRoleKey("User reviewer");
- SearchCond simpleCond = SearchCond.getLeafCond(roleCond);
-
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
- }
-
- @Test
- public void resources() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().hasResources("resource-ldap").query();
- assertEquals(SpecialAttr.RESOURCES + "==resource-ldap", fiqlExpression);
-
- ResourceCond resCond = new ResourceCond();
- resCond.setResourceName("resource-ldap");
- SearchCond simpleCond = SearchCond.getLeafCond(resCond);
-
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
- }
-
- @Test
- public void assignable() {
- String fiqlExpression = new GroupFiqlSearchConditionBuilder().isAssignable().query();
- assertEquals(SpecialAttr.ASSIGNABLE + "==" + SpecialAttr.NULL, fiqlExpression);
-
- AssignableCond assignableCond = new AssignableCond();
- assignableCond.setRealmFullPath("/even/two");
- SearchCond simpleCond = SearchCond.getLeafCond(assignableCond);
-
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression, "/even/two"));
- }
-
- @Test
- public void type() {
- String fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").query();
- assertEquals(SpecialAttr.TYPE + "==PRINTER", fiqlExpression);
-
- AnyTypeCond acond = new AnyTypeCond();
- acond.setAnyTypeName("PRINTER");
- SearchCond simpleCond = SearchCond.getLeafCond(acond);
-
- assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
- }
-
- @Test
- public void and() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
- is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query();
- assertEquals("fullname==*o*;fullname==*i*", fiqlExpression);
-
- AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
- fullnameLeafCond1.setSchema("fullname");
- fullnameLeafCond1.setExpression("%o%");
- AttributeCond fullnameLeafCond2 = new AttributeCond(AttributeCond.Type.LIKE);
- fullnameLeafCond2.setSchema("fullname");
- fullnameLeafCond2.setExpression("%i%");
- SearchCond andCond = SearchCond.getAndCond(
- SearchCond.getLeafCond(fullnameLeafCond1),
- SearchCond.getLeafCond(fullnameLeafCond2));
-
- assertEquals(andCond, SearchCondConverter.convert(fiqlExpression));
- }
-
- @Test
- public void or() {
- String fiqlExpression = new UserFiqlSearchConditionBuilder().
- is("fullname").equalTo("*o*", "*i*", "*ini").query();
- assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
- fiqlExpression = new UserFiqlSearchConditionBuilder().
- is("fullname").equalTo("*o*").or("fullname").equalTo("*i*").or("fullname").equalTo("*ini").query();
- assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
-
- AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
- fullnameLeafCond1.setSchema("fullname");
- fullnameLeafCond1.setExpression("%o%");
- AttributeCond fullnameLeafCond2 = new AttributeCond(AttributeCond.Type.LIKE);
- fullnameLeafCond2.setSchema("fullname");
- fullnameLeafCond2.setExpression("%i%");
- AttributeCond fullnameLeafCond3 = new AttributeCond(AttributeCond.Type.LIKE);
- fullnameLeafCond3.setSchema("fullname");
- fullnameLeafCond3.setExpression("%ini");
- SearchCond orCond = SearchCond.getOrCond(
- SearchCond.getLeafCond(fullnameLeafCond1),
- SearchCond.getOrCond(
- SearchCond.getLeafCond(fullnameLeafCond2),
- SearchCond.getLeafCond(fullnameLeafCond3)));
-
- assertEquals(orCond, SearchCondConverter.convert(fiqlExpression));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/test/java/org/apache/syncope/core/misc/security/EncryptorTest.java
----------------------------------------------------------------------
diff --git a/core/misc/src/test/java/org/apache/syncope/core/misc/security/EncryptorTest.java b/core/misc/src/test/java/org/apache/syncope/core/misc/security/EncryptorTest.java
deleted file mode 100644
index 98e8061..0000000
--- a/core/misc/src/test/java/org/apache/syncope/core/misc/security/EncryptorTest.java
+++ /dev/null
@@ -1,58 +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.core.misc.security;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.junit.Test;
-
-/**
- * Test class to test all encryption algorithms.
- */
-public class EncryptorTest {
-
- private final String password = "password";
-
- private final Encryptor encryptor = Encryptor.getInstance();
-
- /**
- * Verify all algorithms.
- */
- @Test
- public void testEncoder() throws Exception {
- for (CipherAlgorithm cipherAlgorithm : CipherAlgorithm.values()) {
- final String encPassword = encryptor.encode(password, cipherAlgorithm);
-
- assertNotNull(encPassword);
- assertTrue(encryptor.verify(password, cipherAlgorithm, encPassword));
- assertFalse(encryptor.verify("pass", cipherAlgorithm, encPassword));
-
- // check that same password encoded with BCRYPT or Salted versions results in different digest
- if (cipherAlgorithm.equals(CipherAlgorithm.BCRYPT) || cipherAlgorithm.getAlgorithm().startsWith("S-")) {
- final String encSamePassword = encryptor.encode(password, cipherAlgorithm);
- assertNotNull(encSamePassword);
- assertFalse(encSamePassword.equals(encPassword));
- assertTrue(encryptor.verify(password, cipherAlgorithm, encSamePassword));
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/misc/src/test/java/org/apache/syncope/core/misc/security/PasswordGeneratorTest.java
----------------------------------------------------------------------
diff --git a/core/misc/src/test/java/org/apache/syncope/core/misc/security/PasswordGeneratorTest.java b/core/misc/src/test/java/org/apache/syncope/core/misc/security/PasswordGeneratorTest.java
deleted file mode 100644
index 536fa60..0000000
--- a/core/misc/src/test/java/org/apache/syncope/core/misc/security/PasswordGeneratorTest.java
+++ /dev/null
@@ -1,144 +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.core.misc.security;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
-import org.apache.syncope.common.lib.policy.PasswordRuleConf;
-import org.apache.syncope.core.misc.policy.InvalidPasswordRuleConf;
-import org.apache.syncope.core.misc.policy.PolicyPattern;
-import org.junit.Test;
-
-public class PasswordGeneratorTest {
-
- private final DefaultPasswordGenerator passwordGenerator = new DefaultPasswordGenerator();
-
- private DefaultPasswordRuleConf createBaseDefaultPasswordRuleConf() {
- DefaultPasswordRuleConf baseDefaultPasswordRuleConf = new DefaultPasswordRuleConf();
- baseDefaultPasswordRuleConf.setAlphanumericRequired(false);
- baseDefaultPasswordRuleConf.setDigitRequired(false);
- baseDefaultPasswordRuleConf.setLowercaseRequired(false);
- baseDefaultPasswordRuleConf.setMaxLength(1000);
- baseDefaultPasswordRuleConf.setMinLength(8);
- baseDefaultPasswordRuleConf.setMustEndWithAlpha(false);
- baseDefaultPasswordRuleConf.setMustEndWithDigit(false);
- baseDefaultPasswordRuleConf.setMustEndWithNonAlpha(false);
- baseDefaultPasswordRuleConf.setMustStartWithAlpha(false);
- baseDefaultPasswordRuleConf.setMustStartWithDigit(false);
- baseDefaultPasswordRuleConf.setMustStartWithNonAlpha(false);
- baseDefaultPasswordRuleConf.setMustntEndWithAlpha(false);
- baseDefaultPasswordRuleConf.setMustntEndWithDigit(false);
- baseDefaultPasswordRuleConf.setMustntEndWithNonAlpha(false);
- baseDefaultPasswordRuleConf.setMustntStartWithAlpha(false);
- baseDefaultPasswordRuleConf.setMustntStartWithDigit(false);
- baseDefaultPasswordRuleConf.setMustntStartWithNonAlpha(false);
- baseDefaultPasswordRuleConf.setNonAlphanumericRequired(false);
- baseDefaultPasswordRuleConf.setUppercaseRequired(false);
- return baseDefaultPasswordRuleConf;
- }
-
- @Test
- public void startEndWithDigit() throws InvalidPasswordRuleConf {
- DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
- pwdRuleConf.setMustStartWithDigit(true);
-
- DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
- pwdRuleConf2.setMustEndWithDigit(true);
-
- List<PasswordRuleConf> ruleConfs = new ArrayList<>();
- ruleConfs.add(pwdRuleConf);
- ruleConfs.add(pwdRuleConf2);
- String generatedPassword = passwordGenerator.generate(ruleConfs);
- assertTrue(Character.isDigit(generatedPassword.charAt(0)));
- assertTrue(Character.isDigit(generatedPassword.charAt(generatedPassword.length() - 1)));
- }
-
- @Test
- public void startWithDigitAndWithAlpha() throws InvalidPasswordRuleConf {
- DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
- pwdRuleConf.setMustStartWithDigit(true);
-
- DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
- pwdRuleConf2.setMustEndWithAlpha(true);
-
- List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>();
- pwdRuleConfs.add(pwdRuleConf);
- pwdRuleConfs.add(pwdRuleConf2);
- String generatedPassword = passwordGenerator.generate(pwdRuleConfs);
- assertTrue(Character.isDigit(generatedPassword.charAt(0)));
- assertTrue(Character.isLetter(generatedPassword.charAt(generatedPassword.length() - 1)));
- }
-
- @Test
- public void passwordWithNonAlpha() throws InvalidPasswordRuleConf {
- DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
- pwdRuleConf.setNonAlphanumericRequired(true);
-
- DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
- pwdRuleConf2.setMustEndWithAlpha(true);
-
- List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>();
- pwdRuleConfs.add(pwdRuleConf);
- pwdRuleConfs.add(pwdRuleConf2);
- String generatedPassword = passwordGenerator.generate(pwdRuleConfs);
- assertTrue(PolicyPattern.NON_ALPHANUMERIC.matcher(generatedPassword).matches());
- assertTrue(Character.isLetter(generatedPassword.charAt(generatedPassword.length() - 1)));
- }
-
- @Test(expected = InvalidPasswordRuleConf.class)
- public void incopatiblePolicies() throws InvalidPasswordRuleConf {
- DefaultPasswordRuleConf pwdRuleConf = createBaseDefaultPasswordRuleConf();
- pwdRuleConf.setMinLength(12);
-
- DefaultPasswordRuleConf pwdRuleConf2 = createBaseDefaultPasswordRuleConf();
- pwdRuleConf.setMaxLength(10);
-
- List<PasswordRuleConf> pwdRuleConfs = new ArrayList<>();
- pwdRuleConfs.add(pwdRuleConf);
- pwdRuleConfs.add(pwdRuleConf2);
- passwordGenerator.generate(pwdRuleConfs);
- }
-
- @Test
- public void issueSYNCOPE678() {
- String password = null;
- try {
- password = passwordGenerator.generate(Collections.<PasswordRuleConf>emptyList());
- } catch (InvalidPasswordRuleConf e) {
- fail(e.getMessage());
- }
- assertNotNull(password);
-
- DefaultPasswordRuleConf ppSpec = createBaseDefaultPasswordRuleConf();
- ppSpec.setMinLength(0);
- password = null;
- try {
- password = passwordGenerator.generate(Collections.<PasswordRuleConf>singletonList(ppSpec));
- } catch (InvalidPasswordRuleConf e) {
- fail(e.getMessage());
- }
- assertNotNull(password);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/persistence-api/pom.xml
----------------------------------------------------------------------
diff --git a/core/persistence-api/pom.xml b/core/persistence-api/pom.xml
index 10745e7..b06a192 100644
--- a/core/persistence-api/pom.xml
+++ b/core/persistence-api/pom.xml
@@ -61,6 +61,19 @@ under the License.
<artifactId>syncope-common-lib</artifactId>
<version>${project.version}</version>
</dependency>
+
+ <!-- TEST -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
[10/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditEntry.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditEntry.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditEntry.java
new file mode 100644
index 0000000..4b8279f
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditEntry.java
@@ -0,0 +1,77 @@
+/*
+ * 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.core.provisioning.java;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+
+public class AuditEntry extends AbstractBaseBean {
+
+ private static final long serialVersionUID = -2299082316063743582L;
+
+ private final String who;
+
+ private final AuditLoggerName logger;
+
+ private final Object before;
+
+ private final Object output;
+
+ private final Object[] input;
+
+ @JsonCreator
+ public AuditEntry(
+ @JsonProperty("who") final String who,
+ @JsonProperty("logger") final AuditLoggerName logger,
+ @JsonProperty("before") final Object before,
+ @JsonProperty("output") final Object output,
+ @JsonProperty("input") final Object[] input) {
+
+ super();
+
+ this.who = who;
+ this.logger = logger;
+ this.before = before;
+ this.output = output;
+ this.input = input;
+ }
+
+ public String getWho() {
+ return who;
+ }
+
+ public AuditLoggerName getLogger() {
+ return logger;
+ }
+
+ public Object getBefore() {
+ return before;
+ }
+
+ public Object getOutput() {
+ return output;
+ }
+
+ public Object[] getInput() {
+ return input;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.java
new file mode 100644
index 0000000..b692472
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.java
@@ -0,0 +1,81 @@
+/*
+ * 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.core.provisioning.java;
+
+import org.apache.syncope.core.provisioning.api.AuditManager;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+import org.apache.syncope.common.lib.types.LoggerLevel;
+import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class AuditManagerImpl implements AuditManager {
+
+ @Autowired
+ private LoggerDAO loggerDAO;
+
+ public static String getDomainAuditLoggerName(final String domain) {
+ return LoggerType.AUDIT.getPrefix() + "." + domain;
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public void audit(
+ final AuditElements.EventCategoryType type,
+ final String category,
+ final String subcategory,
+ final String event,
+ final Result result,
+ final Object before,
+ final Object output,
+ final Object... input) {
+
+ Throwable throwable = null;
+ if (output instanceof Throwable) {
+ throwable = (Throwable) output;
+ }
+
+ AuditEntry auditEntry = new AuditEntry(
+ AuthContextUtils.getUsername(),
+ new AuditLoggerName(type, category, subcategory, event, result),
+ before,
+ throwable == null ? output : throwable.getMessage(),
+ input);
+
+ org.apache.syncope.core.persistence.api.entity.Logger syncopeLogger =
+ loggerDAO.find(auditEntry.getLogger().toLoggerName());
+ if (syncopeLogger != null && syncopeLogger.getLevel() == LoggerLevel.DEBUG) {
+ Logger logger = LoggerFactory.getLogger(getDomainAuditLoggerName(AuthContextUtils.getDomain()));
+ if (throwable == null) {
+ logger.debug(POJOHelper.serialize(auditEntry));
+ } else {
+ logger.debug(POJOHelper.serialize(auditEntry), throwable);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java
index 40ff432..7e103bb 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnIdBundleManagerImpl.java
@@ -35,7 +35,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
-import org.apache.syncope.core.provisioning.api.URIUtils;
+import org.apache.syncope.core.provisioning.api.utils.URIUtils;
import org.identityconnectors.common.IOUtil;
import org.identityconnectors.common.security.GuardedString;
import org.identityconnectors.framework.api.APIConfiguration;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
index 3454985..4e7f9e9 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java
@@ -30,15 +30,15 @@ import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Transformer;
import org.apache.syncope.common.lib.types.ConnConfProperty;
import org.apache.syncope.common.lib.types.ConnectorCapability;
-import org.apache.syncope.core.misc.utils.MappingUtils;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
-import org.apache.syncope.core.provisioning.api.ConnPoolConfUtils;
+import org.apache.syncope.core.provisioning.api.utils.ConnPoolConfUtils;
import org.apache.syncope.core.provisioning.api.Connector;
import org.apache.syncope.core.provisioning.api.TimeoutException;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.provisioning.api.syncpull.ReconciliationFilterBuilder;
import org.identityconnectors.common.security.GuardedByteArray;
import org.identityconnectors.common.security.GuardedString;
import org.identityconnectors.framework.api.APIConfiguration;
@@ -66,7 +66,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ClassUtils;
-import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder;
public class ConnectorFacadeProxy implements Connector {
@@ -481,7 +480,7 @@ public class ConnectorFacadeProxy implements Connector {
}
}, new ArrayList<SortKey>(orderBy.size())));
- builder.setAttributesToGet(MappingUtils.buildOperationOptions(mapItems).getAttributesToGet());
+ builder.setAttributesToGet(MappingManagerImpl.buildOperationOptions(mapItems).getAttributesToGet());
search(objectClass, filter, handler, builder.build());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
index 1ecc163..de2fa29 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java
@@ -26,8 +26,8 @@ import java.util.Set;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.syncope.common.lib.types.ConnConfProperty;
import org.apache.syncope.common.lib.types.ConnectorCapability;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
index f2b489f..0cc4100 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
@@ -38,7 +38,7 @@ import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.provisioning.api.VirAttrHandler;
import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
import org.springframework.beans.factory.annotation.Autowired;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
index 831e41f..08c55a5 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
@@ -43,7 +43,7 @@ import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.provisioning.api.VirAttrHandler;
import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
index d9028af..cd3fc5c 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
@@ -47,9 +47,9 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationException
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.provisioning.api.VirAttrHandler;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
+import org.apache.syncope.core.provisioning.api.syncpull.ProvisioningReport;
import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java
index ccff795..f827f46 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java
@@ -24,7 +24,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.commons.jexl3.JexlContext;
import org.apache.commons.jexl3.MapContext;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.DerSchema;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
new file mode 100644
index 0000000..7c97448
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
@@ -0,0 +1,847 @@
+/*
+ * 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.core.provisioning.java;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.collections4.ListUtils;
+import org.apache.commons.jexl3.JexlContext;
+import org.apache.commons.jexl3.MapContext;
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.provisioning.api.utils.policy.InvalidPasswordRuleConf;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
+import org.apache.syncope.core.spring.security.PasswordGenerator;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.Schema;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.DerAttrHandler;
+import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
+import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.identityconnectors.framework.common.FrameworkUtil;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.identityconnectors.framework.common.objects.AttributeUtil;
+import org.identityconnectors.framework.common.objects.Name;
+import org.identityconnectors.framework.common.objects.OperationOptions;
+import org.identityconnectors.framework.common.objects.OperationOptionsBuilder;
+import org.identityconnectors.framework.common.objects.OperationalAttributes;
+import org.identityconnectors.framework.common.objects.Uid;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class MappingManagerImpl implements MappingManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MappingManager.class);
+
+ private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
+ @Autowired
+ private AnyTypeDAO anyTypeDAO;
+
+ @Autowired
+ private PlainSchemaDAO plainSchemaDAO;
+
+ @Autowired
+ private DerSchemaDAO derSchemaDAO;
+
+ @Autowired
+ private VirSchemaDAO virSchemaDAO;
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Autowired
+ private DerAttrHandler derAttrHandler;
+
+ @Autowired
+ private VirAttrHandler virAttrHandler;
+
+ @Autowired
+ private VirAttrCache virAttrCache;
+
+ @Autowired
+ private PasswordGenerator passwordGenerator;
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ @Autowired
+ private AnyUtilsFactory anyUtilsFactory;
+
+ public static MappingItem getConnObjectKeyItem(final Provision provision) {
+ Mapping mapping = null;
+ if (provision != null) {
+ mapping = provision.getMapping();
+ }
+
+ return mapping == null
+ ? null
+ : mapping.getConnObjectKeyItem();
+ }
+
+ private static List<MappingItem> getMappingItems(final Provision provision, final MappingPurpose purpose) {
+ List<? extends MappingItem> items = Collections.<MappingItem>emptyList();
+ if (provision != null) {
+ items = provision.getMapping().getItems();
+ }
+
+ List<MappingItem> result = new ArrayList<>();
+
+ switch (purpose) {
+ case SYNCHRONIZATION:
+ for (MappingItem item : items) {
+ if (MappingPurpose.PROPAGATION != item.getPurpose()
+ && MappingPurpose.NONE != item.getPurpose()) {
+
+ result.add(item);
+ }
+ }
+ break;
+
+ case PROPAGATION:
+ for (MappingItem item : items) {
+ if (MappingPurpose.SYNCHRONIZATION != item.getPurpose()
+ && MappingPurpose.NONE != item.getPurpose()) {
+
+ result.add(item);
+ }
+ }
+ break;
+
+ case BOTH:
+ for (MappingItem item : items) {
+ if (MappingPurpose.NONE != item.getPurpose()) {
+ result.add(item);
+ }
+ }
+ break;
+
+ case NONE:
+ for (MappingItem item : items) {
+ if (MappingPurpose.NONE == item.getPurpose()) {
+ result.add(item);
+ }
+ }
+ break;
+
+ default:
+ }
+
+ return result;
+ }
+
+ public static List<MappingItem> getBothMappingItems(final Provision provision) {
+ return getMappingItems(provision, MappingPurpose.BOTH);
+ }
+
+ public static List<MappingItem> getPropagationMappingItems(final Provision provision) {
+ return getMappingItems(provision, MappingPurpose.PROPAGATION);
+ }
+
+ public static List<MappingItem> getSyncMappingItems(final Provision provision) {
+ return getMappingItems(provision, MappingPurpose.SYNCHRONIZATION);
+ }
+
+ /**
+ * Build __NAME__ for propagation. First look if there ia a defined connObjectLink for the given resource (and in
+ * this case evaluate as JEXL); otherwise, take given connObjectKey.
+ *
+ * @param any given any object
+ * @param provision external resource
+ * @param connObjectKey connector object key
+ * @return the value to be propagated as __NAME__
+ */
+ public static Name evaluateNAME(final Any<?> any, final Provision provision, final String connObjectKey) {
+ if (StringUtils.isBlank(connObjectKey)) {
+ // LOG error but avoid to throw exception: leave it to the external resource
+ LOG.error("Missing ConnObjectKey for '{}': ", provision.getResource());
+ }
+
+ // Evaluate connObjectKey expression
+ String connObjectLink = provision == null || provision.getMapping() == null
+ ? null
+ : provision.getMapping().getConnObjectLink();
+ String evalConnObjectLink = null;
+ if (StringUtils.isNotBlank(connObjectLink)) {
+ JexlContext jexlContext = new MapContext();
+ JexlUtils.addFieldsToContext(any, jexlContext);
+ JexlUtils.addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
+ JexlUtils.addDerAttrsToContext(any, jexlContext);
+ evalConnObjectLink = JexlUtils.evaluate(connObjectLink, jexlContext);
+ }
+
+ // If connObjectLink evaluates to an empty string, just use the provided connObjectKey as Name(),
+ // otherwise evaluated connObjectLink expression is taken as Name().
+ Name name;
+ if (StringUtils.isBlank(evalConnObjectLink)) {
+ // add connObjectKey as __NAME__ attribute ...
+ LOG.debug("Add connObjectKey [{}] as __NAME__", connObjectKey);
+ name = new Name(connObjectKey);
+ } else {
+ LOG.debug("Add connObjectLink [{}] as __NAME__", evalConnObjectLink);
+ name = new Name(evalConnObjectLink);
+
+ // connObjectKey not propagated: it will be used to set the value for __UID__ attribute
+ LOG.debug("connObjectKey will be used just as __UID__ attribute");
+ }
+
+ return name;
+ }
+
+ public static List<MappingItemTransformer> getMappingItemTransformers(final MappingItem mappingItem) {
+ List<MappingItemTransformer> result = new ArrayList<>();
+
+ for (String className : mappingItem.getMappingItemTransformerClassNames()) {
+ try {
+ Class<?> transformerClass = ClassUtils.getClass(className);
+
+ result.add((MappingItemTransformer) ApplicationContextProvider.
+ getBeanFactory().
+ createBean(transformerClass, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false));
+ } catch (Exception e) {
+ LOG.error("Could not instantiate {}, ignoring...", className, e);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Build options for requesting all mapped connector attributes.
+ *
+ * @param mapItems mapping items
+ * @return options for requesting all mapped connector attributes
+ * @see OperationOptions
+ */
+ public static OperationOptions buildOperationOptions(final Iterator<? extends MappingItem> mapItems) {
+ OperationOptionsBuilder builder = new OperationOptionsBuilder();
+
+ Set<String> attrsToGet = new HashSet<>();
+ attrsToGet.add(Name.NAME);
+ attrsToGet.add(Uid.NAME);
+ attrsToGet.add(OperationalAttributes.ENABLE_NAME);
+
+ while (mapItems.hasNext()) {
+ MappingItem mapItem = mapItems.next();
+ if (mapItem.getPurpose() != MappingPurpose.NONE) {
+ attrsToGet.add(mapItem.getExtAttrName());
+ }
+ }
+
+ builder.setAttributesToGet(attrsToGet);
+ // -------------------------------------
+
+ return builder.build();
+ }
+
+ /**
+ * Prepare attributes for sending to a connector instance.
+ *
+ * @param any given any object
+ * @param password clear-text password
+ * @param changePwd whether password should be included for propagation attributes or not
+ * @param enable whether any object must be enabled or not
+ * @param provision provision information
+ * @return connObjectLink + prepared attributes
+ */
+ @Transactional(readOnly = true)
+ @Override
+ public Pair<String, Set<Attribute>> prepareAttrs(
+ final Any<?> any,
+ final String password,
+ final boolean changePwd,
+ final Boolean enable,
+ final Provision provision) {
+
+ LOG.debug("Preparing resource attributes for {} with provision {} for attributes {}",
+ any, provision, any.getPlainAttrs());
+
+ Set<Attribute> attributes = new HashSet<>();
+ String connObjectKey = null;
+
+ for (MappingItem mappingItem : getMappingItems(provision, MappingPurpose.PROPAGATION)) {
+ LOG.debug("Processing schema {}", mappingItem.getIntAttrName());
+
+ try {
+ Pair<String, Attribute> preparedAttr = prepareAttr(provision, mappingItem, any, password);
+
+ if (preparedAttr != null && preparedAttr.getKey() != null) {
+ connObjectKey = preparedAttr.getKey();
+ }
+
+ if (preparedAttr != null && preparedAttr.getValue() != null) {
+ Attribute alreadyAdded = AttributeUtil.find(preparedAttr.getValue().getName(), attributes);
+
+ if (alreadyAdded == null) {
+ attributes.add(preparedAttr.getValue());
+ } else {
+ attributes.remove(alreadyAdded);
+
+ Set<Object> values = new HashSet<>(alreadyAdded.getValue());
+ values.addAll(preparedAttr.getValue().getValue());
+
+ attributes.add(AttributeBuilder.build(preparedAttr.getValue().getName(), values));
+ }
+ }
+ } catch (Exception e) {
+ LOG.debug("Attribute '{}' processing failed", mappingItem.getIntAttrName(), e);
+ }
+ }
+
+ Attribute connObjectKeyExtAttr =
+ AttributeUtil.find(getConnObjectKeyItem(provision).getExtAttrName(), attributes);
+ if (connObjectKeyExtAttr != null) {
+ attributes.remove(connObjectKeyExtAttr);
+ attributes.add(AttributeBuilder.build(getConnObjectKeyItem(provision).getExtAttrName(), connObjectKey));
+ }
+ attributes.add(evaluateNAME(any, provision, connObjectKey));
+
+ if (enable != null) {
+ attributes.add(AttributeBuilder.buildEnabled(enable));
+ }
+ if (!changePwd) {
+ Attribute pwdAttr = AttributeUtil.find(OperationalAttributes.PASSWORD_NAME, attributes);
+ if (pwdAttr != null) {
+ attributes.remove(pwdAttr);
+ }
+ }
+
+ return new ImmutablePair<>(connObjectKey, attributes);
+ }
+
+ /**
+ * Prepare an attribute to be sent to a connector instance.
+ *
+ * @param provision external resource
+ * @param mapItem mapping item for the given attribute
+ * @param any any object
+ * @param password clear-text password
+ * @return connObjectKey + prepared attribute
+ */
+ private Pair<String, Attribute> prepareAttr(
+ final Provision provision, final MappingItem mapItem, final Any<?> any, final String password) {
+
+ List<Any<?>> anys = new ArrayList<>();
+
+ switch (mapItem.getIntMappingType().getAnyTypeKind()) {
+ case USER:
+ if (any instanceof User) {
+ anys.add(any);
+ }
+ break;
+
+ case GROUP:
+ if (any instanceof User) {
+ for (Group group : userDAO.findAllGroups((User) any)) {
+ anys.add(group);
+ }
+ } else if (any instanceof Group) {
+ anys.add(any);
+ }
+ break;
+
+ case ANY_OBJECT:
+ if (any instanceof AnyObject) {
+ anys.add(any);
+ }
+ break;
+
+ default:
+ }
+
+ Schema schema = null;
+ boolean readOnlyVirSchema = false;
+ AttrSchemaType schemaType;
+ Pair<String, Attribute> result;
+
+ switch (mapItem.getIntMappingType()) {
+ case UserPlainSchema:
+ case GroupPlainSchema:
+ case AnyObjectPlainSchema:
+ schema = plainSchemaDAO.find(mapItem.getIntAttrName());
+ schemaType = schema == null ? AttrSchemaType.String : schema.getType();
+ break;
+
+ case UserVirtualSchema:
+ case GroupVirtualSchema:
+ case AnyObjectVirtualSchema:
+ schema = virSchemaDAO.find(mapItem.getIntAttrName());
+ readOnlyVirSchema = (schema != null && schema.isReadonly());
+ schemaType = AttrSchemaType.String;
+ break;
+
+ default:
+ schemaType = AttrSchemaType.String;
+ }
+
+ String extAttrName = mapItem.getExtAttrName();
+
+ List<PlainAttrValue> values = getIntValues(provision, mapItem, anys);
+
+ LOG.debug("Define mapping for: "
+ + "\n* ExtAttrName " + extAttrName
+ + "\n* is connObjectKey " + mapItem.isConnObjectKey()
+ + "\n* is password " + (mapItem.isPassword() || mapItem.getIntMappingType() == IntMappingType.Password)
+ + "\n* mandatory condition " + mapItem.getMandatoryCondition()
+ + "\n* Schema " + mapItem.getIntAttrName()
+ + "\n* IntMappingType " + mapItem.getIntMappingType().toString()
+ + "\n* ClassType " + schemaType.getType().getName()
+ + "\n* Values " + values);
+
+ if (readOnlyVirSchema) {
+ result = null;
+ } else {
+ List<Object> objValues = new ArrayList<>();
+
+ for (PlainAttrValue value : values) {
+ if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) {
+ objValues.add(value.getValue());
+ } else {
+ objValues.add(value.getValueAsString());
+ }
+ }
+
+ if (mapItem.isConnObjectKey()) {
+ result = new ImmutablePair<>(objValues.iterator().next().toString(), null);
+ } else if (mapItem.isPassword() && any instanceof User) {
+ String passwordAttrValue = password;
+ if (StringUtils.isBlank(passwordAttrValue)) {
+ User user = (User) any;
+ if (user.canDecodePassword()) {
+ try {
+ passwordAttrValue = ENCRYPTOR.decode(user.getPassword(), user.getCipherAlgorithm());
+ } catch (Exception e) {
+ LOG.error("Could not decode password for {}", user, e);
+ }
+ } else if (provision.getResource().isRandomPwdIfNotProvided()) {
+ try {
+ passwordAttrValue = passwordGenerator.generate(user);
+ } catch (InvalidPasswordRuleConf e) {
+ LOG.error("Could not generate policy-compliant random password for {}", user, e);
+ }
+ }
+ }
+
+ if (passwordAttrValue == null) {
+ result = null;
+ } else {
+ result = new ImmutablePair<>(
+ null, AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()));
+ }
+ } else if ((schema != null && schema.isMultivalue())
+ || anyUtilsFactory.getInstance(any).getAnyTypeKind()
+ != mapItem.getIntMappingType().getAnyTypeKind()) {
+
+ result = new ImmutablePair<>(
+ null, AttributeBuilder.build(extAttrName, objValues));
+ } else {
+ result = new ImmutablePair<>(
+ null, objValues.isEmpty()
+ ? AttributeBuilder.build(extAttrName)
+ : AttributeBuilder.build(extAttrName, objValues.iterator().next()));
+ }
+ }
+
+ return result;
+ }
+
+ private String getGroupOwnerValue(final Provision provision, final Any<?> any) {
+ Pair<String, Attribute> preparedAttr = prepareAttr(provision, getConnObjectKeyItem(provision), any, null);
+ String connObjectKey = preparedAttr.getKey();
+
+ return evaluateNAME(any, provision, connObjectKey).getNameValue();
+ }
+
+ /**
+ * Get attribute values for the given {@link MappingItem} and any objects.
+ *
+ * @param provision provision information
+ * @param mappingItem mapping item
+ * @param anys any objects
+ * @return attribute values.
+ */
+ @Transactional(readOnly = true)
+ @Override
+ public List<PlainAttrValue> getIntValues(final Provision provision,
+ final MappingItem mappingItem, final List<Any<?>> anys) {
+
+ LOG.debug("Get attributes for '{}' and mapping type '{}'", anys, mappingItem.getIntMappingType());
+
+ boolean transform = true;
+
+ List<PlainAttrValue> values = new ArrayList<>();
+ switch (mappingItem.getIntMappingType()) {
+ case UserPlainSchema:
+ case GroupPlainSchema:
+ case AnyObjectPlainSchema:
+ for (Any<?> any : anys) {
+ PlainAttr<?> attr = any.getPlainAttr(mappingItem.getIntAttrName());
+ if (attr != null) {
+ if (attr.getUniqueValue() != null) {
+ PlainAttrUniqueValue value = SerializationUtils.clone(attr.getUniqueValue());
+ value.setAttr(null);
+ values.add(value);
+ } else if (attr.getValues() != null) {
+ for (PlainAttrValue value : attr.getValues()) {
+ PlainAttrValue shadow = SerializationUtils.clone(value);
+ shadow.setAttr(null);
+ values.add(shadow);
+ }
+ }
+ }
+
+ LOG.debug("Retrieved attribute {}"
+ + "\n* IntAttrName {}"
+ + "\n* IntMappingType {}"
+ + "\n* Attribute values {}",
+ attr, mappingItem.getIntAttrName(), mappingItem.getIntMappingType(), values);
+ }
+
+ break;
+
+ case UserDerivedSchema:
+ case GroupDerivedSchema:
+ case AnyObjectDerivedSchema:
+ DerSchema derSchema = derSchemaDAO.find(mappingItem.getIntAttrName());
+ if (derSchema != null) {
+ for (Any<?> any : anys) {
+ String value = derAttrHandler.getValue(any, derSchema);
+ if (value != null) {
+ AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+ PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
+ attrValue.setStringValue(value);
+ values.add(attrValue);
+
+ LOG.debug("Retrieved values for {}"
+ + "\n* IntAttrName {}"
+ + "\n* IntMappingType {}"
+ + "\n* Attribute values {}",
+ derSchema.getKey(), mappingItem.getIntAttrName(), mappingItem.getIntMappingType(),
+ values);
+ }
+ }
+ }
+ break;
+
+ case UserVirtualSchema:
+ case GroupVirtualSchema:
+ case AnyObjectVirtualSchema:
+ // virtual attributes don't get transformed
+ transform = false;
+
+ VirSchema virSchema = virSchemaDAO.find(mappingItem.getIntAttrName());
+ if (virSchema != null) {
+ for (Any<?> any : anys) {
+ LOG.debug("Expire entry cache {}-{}", any.getKey(), mappingItem.getIntAttrName());
+ virAttrCache.expire(any.getType().getKey(), any.getKey(), mappingItem.getIntAttrName());
+
+ AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+ for (String value : virAttrHandler.getValues(any, virSchema)) {
+ PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
+ attrValue.setStringValue(value);
+ values.add(attrValue);
+ }
+
+ LOG.debug("Retrieved values for {}"
+ + "\n* IntAttrName {}"
+ + "\n* IntMappingType {}"
+ + "\n* Attribute values {}",
+ virSchema.getKey(), mappingItem.getIntAttrName(), mappingItem.getIntMappingType(),
+ values);
+ }
+ }
+ break;
+
+ case UserKey:
+ case GroupKey:
+ case AnyObjectKey:
+ for (Any<?> any : anys) {
+ AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+ PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
+ attrValue.setStringValue(any.getKey().toString());
+ values.add(attrValue);
+ }
+ break;
+
+ case Username:
+ for (Any<?> any : anys) {
+ if (any instanceof User) {
+ UPlainAttrValue attrValue = entityFactory.newEntity(UPlainAttrValue.class);
+ attrValue.setStringValue(((User) any).getUsername());
+ values.add(attrValue);
+ }
+ }
+ break;
+
+ case GroupName:
+ for (Any<?> any : anys) {
+ if (any instanceof Group) {
+ GPlainAttrValue attrValue = entityFactory.newEntity(GPlainAttrValue.class);
+ attrValue.setStringValue(((Group) any).getName());
+ values.add(attrValue);
+ }
+ }
+ break;
+
+ case GroupOwnerSchema:
+ Mapping uMapping = provision.getAnyType().equals(anyTypeDAO.findUser())
+ ? provision.getMapping()
+ : null;
+ Mapping gMapping = provision.getAnyType().equals(anyTypeDAO.findGroup())
+ ? provision.getMapping()
+ : null;
+
+ for (Any<?> any : anys) {
+ if (any instanceof Group) {
+ Group group = (Group) any;
+ String groupOwnerValue = null;
+ if (group.getUserOwner() != null && uMapping != null) {
+ groupOwnerValue = getGroupOwnerValue(provision, group.getUserOwner());
+ }
+ if (group.getGroupOwner() != null && gMapping != null) {
+ groupOwnerValue = getGroupOwnerValue(provision, group.getGroupOwner());
+ }
+
+ if (StringUtils.isNotBlank(groupOwnerValue)) {
+ GPlainAttrValue attrValue = entityFactory.newEntity(GPlainAttrValue.class);
+ attrValue.setStringValue(groupOwnerValue);
+ values.add(attrValue);
+ }
+ }
+ }
+ break;
+
+ default:
+ }
+
+ LOG.debug("Values for propagation: {}", values);
+
+ List<PlainAttrValue> transformed = values;
+ if (transform) {
+ for (MappingItemTransformer transformer : getMappingItemTransformers(mappingItem)) {
+ transformed = transformer.beforePropagation(transformed);
+ }
+ LOG.debug("Transformed values for propagation: {}", values);
+ } else {
+ LOG.debug("No transformation occurred");
+ }
+
+ return transformed;
+ }
+
+ /**
+ * Get connObjectKey internal value.
+ *
+ * @param any any object
+ * @param provision provision information
+ * @return connObjectKey internal value
+ */
+ @Transactional(readOnly = true)
+ @Override
+ public String getConnObjectKeyValue(final Any<?> any, final Provision provision) {
+ List<PlainAttrValue> values = getIntValues(provision, provision.getMapping().getConnObjectKeyItem(),
+ Collections.<Any<?>>singletonList(any));
+ return values == null || values.isEmpty()
+ ? null
+ : values.get(0).getValueAsString();
+ }
+
+ /**
+ * Set attribute values, according to the given {@link MappingItem}, to any object from attribute received from
+ * connector.
+ *
+ * @param <T> any object
+ * @param mappingItem mapping item
+ * @param attr attribute received from connector
+ * @param anyTO any object
+ * @param anyUtils any utils
+ */
+ @Transactional(readOnly = true)
+ @Override
+ public <T extends AnyTO> void setIntValues(
+ final MappingItem mappingItem, final Attribute attr, final T anyTO, final AnyUtils anyUtils) {
+
+ List<Object> values = null;
+ if (attr != null) {
+ values = attr.getValue();
+ for (MappingItemTransformer transformer : getMappingItemTransformers(mappingItem)) {
+ values = transformer.beforeSync(values);
+ }
+ }
+ values = ListUtils.emptyIfNull(values);
+
+ switch (mappingItem.getIntMappingType()) {
+ case UserKey:
+ case GroupKey:
+ case AnyObjectKey:
+ break;
+
+ case Password:
+ if (anyTO instanceof UserTO && !values.isEmpty()) {
+ ((UserTO) anyTO).setPassword(ConnObjectUtils.getPassword(values.get(0)));
+ }
+ break;
+
+ case Username:
+ if (anyTO instanceof UserTO) {
+ ((UserTO) anyTO).setUsername(values.isEmpty() || values.get(0) == null
+ ? null
+ : values.get(0).toString());
+ }
+ break;
+
+ case GroupName:
+ if (anyTO instanceof GroupTO) {
+ ((GroupTO) anyTO).setName(values.isEmpty() || values.get(0) == null
+ ? null
+ : values.get(0).toString());
+ }
+ break;
+
+ case GroupOwnerSchema:
+ if (anyTO instanceof GroupTO && attr != null) {
+ // using a special attribute (with schema "", that will be ignored) for carrying the
+ // GroupOwnerSchema value
+ AttrTO attrTO = new AttrTO();
+ attrTO.setSchema(StringUtils.EMPTY);
+ if (values.isEmpty() || values.get(0) == null) {
+ attrTO.getValues().add(StringUtils.EMPTY);
+ } else {
+ attrTO.getValues().add(values.get(0).toString());
+ }
+
+ ((GroupTO) anyTO).getPlainAttrs().add(attrTO);
+ }
+ break;
+
+ case UserPlainSchema:
+ case GroupPlainSchema:
+ case AnyObjectPlainSchema:
+ AttrTO attrTO = new AttrTO();
+ attrTO.setSchema(mappingItem.getIntAttrName());
+
+ PlainSchema schema = plainSchemaDAO.find(mappingItem.getIntAttrName());
+
+ for (Object value : values) {
+ AttrSchemaType schemaType = schema == null ? AttrSchemaType.String : schema.getType();
+ if (value != null) {
+ PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
+ switch (schemaType) {
+ case String:
+ attrValue.setStringValue(value.toString());
+ break;
+
+ case Binary:
+ attrValue.setBinaryValue((byte[]) value);
+ break;
+
+ default:
+ try {
+ attrValue.parseValue(schema, value.toString());
+ } catch (ParsingValidationException e) {
+ LOG.error("While parsing provided value {}", value, e);
+ attrValue.setStringValue(value.toString());
+ schemaType = AttrSchemaType.String;
+ }
+ break;
+ }
+ attrTO.getValues().add(attrValue.getValueAsString(schemaType));
+ }
+ }
+
+ anyTO.getPlainAttrs().add(attrTO);
+ break;
+
+ case UserDerivedSchema:
+ case GroupDerivedSchema:
+ case AnyObjectDerivedSchema:
+ attrTO = new AttrTO();
+ attrTO.setSchema(mappingItem.getIntAttrName());
+ anyTO.getDerAttrs().add(attrTO);
+ break;
+
+ case UserVirtualSchema:
+ case GroupVirtualSchema:
+ case AnyObjectVirtualSchema:
+ attrTO = new AttrTO();
+ attrTO.setSchema(mappingItem.getIntAttrName());
+
+ // virtual attributes don't get transformed, iterate over original attr.getValue()
+ for (Object value : (attr == null || attr.getValue() == null)
+ ? Collections.emptyList() : attr.getValue()) {
+
+ if (value != null) {
+ attrTO.getValues().add(value.toString());
+ }
+ }
+
+ anyTO.getVirAttrs().add(attrTO);
+ break;
+
+ default:
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
index ca50635..b65cc79 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
@@ -27,7 +27,6 @@ import java.util.Map;
import java.util.Set;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.core.misc.utils.MappingUtils;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
@@ -36,6 +35,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.provisioning.api.Connector;
import org.apache.syncope.core.provisioning.api.ConnectorFactory;
+import org.apache.syncope.core.provisioning.api.MappingManager;
import org.apache.syncope.core.provisioning.api.VirAttrHandler;
import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
@@ -60,7 +60,7 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
private VirAttrCache virAttrCache;
@Autowired
- private MappingUtils mappingUtils;
+ private MappingManager mappingManager;
@Autowired
private AnyUtilsFactory anyUtilsFactory;
@@ -97,9 +97,9 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
for (Map.Entry<Provision, Set<VirSchema>> entry : toRead.entrySet()) {
LOG.debug("About to read from {}: {}", entry.getKey(), entry.getValue());
- String connObjectKey = MappingUtils.getConnObjectKeyItem(entry.getKey()) == null
+ String connObjectKey = MappingManagerImpl.getConnObjectKeyItem(entry.getKey()) == null
? null
- : mappingUtils.getConnObjectKeyValue(any, entry.getKey());
+ : mappingManager.getConnObjectKeyValue(any, entry.getKey());
if (StringUtils.isBlank(connObjectKey)) {
LOG.error("No ConnObjectKey found for {}, ignoring...", entry.getKey());
} else {
@@ -110,10 +110,9 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
Connector connector = connFactory.getConnector(entry.getKey().getResource());
try {
- ConnectorObject connectorObject = connector.getObject(
- entry.getKey().getObjectClass(),
+ ConnectorObject connectorObject = connector.getObject(entry.getKey().getObjectClass(),
new Uid(connObjectKey),
- MappingUtils.buildOperationOptions(linkingMappingItems.iterator()));
+ MappingManagerImpl.buildOperationOptions(linkingMappingItems.iterator()));
if (connectorObject == null) {
LOG.debug("No read from {} about {}", entry.getKey(), connObjectKey);
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 3d96cfc..56e0d71 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -59,10 +59,10 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
@@ -83,6 +83,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.provisioning.api.DerAttrHandler;
+import org.apache.syncope.core.provisioning.api.MappingManager;
import org.apache.syncope.core.provisioning.api.VirAttrHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -155,7 +156,7 @@ abstract class AbstractAnyDataBinder {
protected ConnObjectUtils connObjectUtils;
@Autowired
- protected MappingUtils mappingUtils;
+ protected MappingManager mappingManager;
protected void setRealm(final Any<?> any, final AnyPatch anyPatch) {
if (anyPatch.getRealm() != null && StringUtils.isNotBlank(anyPatch.getRealm().getValue())) {
@@ -232,7 +233,7 @@ abstract class AbstractAnyDataBinder {
&& (item.getPurpose() == MappingPurpose.PROPAGATION
|| item.getPurpose() == MappingPurpose.BOTH)) {
- List<PlainAttrValue> values = mappingUtils.getIntValues(
+ List<PlainAttrValue> values = mappingManager.getIntValues(
provision, item, Collections.<Any<?>>singletonList(any));
if (values.isEmpty() && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), any)) {
missingAttrNames.add(item.getIntAttrName());
@@ -351,7 +352,8 @@ abstract class AbstractAnyDataBinder {
}
for (ExternalResource resource : resources) {
- for (MappingItem mapItem : MappingUtils.getPropagationMappingItems(resource.getProvision(any.getType()))) {
+ for (MappingItem mapItem : MappingManagerImpl.getPropagationMappingItems(resource.
+ getProvision(any.getType()))) {
if (schema.getKey().equals(mapItem.getIntAttrName())
&& mapItem.getIntMappingType() == anyUtils.plainIntMappingType()) {
@@ -574,14 +576,14 @@ abstract class AbstractAnyDataBinder {
for (ExternalResource resource : iterable) {
Provision provision = resource.getProvision(any.getType());
if (provision != null && provision.getMapping() != null) {
- MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
+ MappingItem connObjectKeyItem = MappingManagerImpl.getConnObjectKeyItem(provision);
if (connObjectKeyItem == null) {
throw new NotFoundException(
"ConnObjectKey mapping for " + any.getType().getKey() + " " + any.getKey()
+ " on resource '" + resource.getKey() + "'");
}
- String connObjectKey = mappingUtils.getConnObjectKeyValue(any, provision);
+ String connObjectKey = mappingManager.getConnObjectKeyValue(any, provision);
if (connObjectKey != null) {
connObjectKeys.put(resource.getKey(), connObjectKey);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index 1c889f6..7d12f6f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -40,8 +40,8 @@ import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.PatchOperation;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.misc.spring.BeanUtils;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.spring.BeanUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
index 00935f7..5d277b3 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConfigurationDataBinderImpl.java
@@ -27,7 +27,7 @@ import org.apache.commons.jexl3.MapContext;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.AttrTO;
import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException;
import org.apache.syncope.core.persistence.api.dao.ConfDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
index d4a6b08..9129900 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
@@ -33,11 +33,11 @@ import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
-import org.apache.syncope.core.provisioning.api.ConnPoolConfUtils;
+import org.apache.syncope.core.provisioning.api.utils.ConnPoolConfUtils;
import org.identityconnectors.framework.api.ConfigurationProperties;
import org.identityconnectors.framework.api.ConfigurationProperty;
import org.identityconnectors.framework.impl.api.ConfigurationPropertyImpl;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
index a51729b..ba94507 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
@@ -37,7 +37,7 @@ import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.AnyType;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
index 1c11b36..eb0c328 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
@@ -28,7 +28,7 @@ import org.apache.syncope.common.lib.to.NotificationTO;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.Notification;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.MailTemplateDAO;
import org.apache.syncope.core.persistence.api.entity.AnyAbout;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
index c1c3254..42de46f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
@@ -25,7 +25,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.core.misc.utils.TemplateUtils;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java
index 1bf5dc9..7b12665 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java
@@ -31,7 +31,7 @@ import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
import org.apache.syncope.core.persistence.api.entity.Report;
import org.apache.syncope.core.persistence.api.entity.ReportExec;
import org.apache.syncope.core.provisioning.api.job.JobNamer;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
import org.apache.syncope.core.persistence.api.dao.ReportTemplateDAO;
import org.apache.syncope.core.persistence.api.entity.ReportTemplate;
import org.quartz.Scheduler;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
index 5f0decf..97aa6f2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
@@ -42,10 +42,10 @@ import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
import org.apache.syncope.core.persistence.api.entity.policy.SyncPolicy;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
import org.apache.syncope.core.persistence.api.entity.AnyType;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
index 1bef90e..a95b60d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RoleDataBinderImpl.java
@@ -23,7 +23,7 @@ import org.apache.commons.collections4.Transformer;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.RoleTO;
import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
index dc8a957..ac28f14 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java
@@ -31,8 +31,8 @@ import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
import org.apache.syncope.core.persistence.api.entity.DerSchema;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.misc.spring.BeanUtils;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.spring.BeanUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SecurityQuestionDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SecurityQuestionDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SecurityQuestionDataBinderImpl.java
index 34523f2..ed971eb 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SecurityQuestionDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SecurityQuestionDataBinderImpl.java
@@ -22,7 +22,7 @@ import org.apache.syncope.core.provisioning.api.data.SecurityQuestionDataBinder;
import org.apache.syncope.common.lib.to.SecurityQuestionTO;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
index fb7b268..e262521 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java
@@ -37,7 +37,7 @@ import org.apache.syncope.common.lib.types.JobType;
import org.apache.syncope.common.lib.types.MatchingRule;
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.misc.utils.TemplateUtils;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
@@ -51,7 +51,7 @@ import org.apache.syncope.core.persistence.api.entity.task.Task;
import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
import org.apache.syncope.core.provisioning.api.job.JobNamer;
-import org.apache.syncope.core.misc.spring.BeanUtils;
+import org.apache.syncope.core.spring.BeanUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.entity.AnyType;
@@ -59,8 +59,8 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.AnyTemplate;
import org.apache.syncope.core.persistence.api.entity.task.AnyTemplateSyncTask;
-import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
-import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
+import org.apache.syncope.core.provisioning.java.syncpull.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.syncpull.SyncJobDelegate;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index 36b3b77..94686aa 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -53,10 +53,10 @@ import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.Encryptor;
-import org.apache.syncope.core.misc.spring.BeanUtils;
-import org.apache.syncope.core.misc.utils.EntityUtils;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.spring.BeanUtils;
+import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.RoleDAO;
import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/ClassFreeUberspect.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/ClassFreeUberspect.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/ClassFreeUberspect.java
new file mode 100644
index 0000000..aec38b8
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/ClassFreeUberspect.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.core.provisioning.java.jexl;
+
+import org.apache.commons.jexl3.internal.introspection.Uberspect;
+import org.apache.commons.jexl3.introspection.JexlMethod;
+import org.apache.commons.jexl3.introspection.JexlPropertyGet;
+
+class ClassFreeUberspect extends Uberspect {
+
+ ClassFreeUberspect() {
+ super(null, null);
+ }
+
+ @Override
+ public JexlPropertyGet getPropertyGet(final Object obj, final Object identifier) {
+ return "class".equals(identifier) ? null : super.getPropertyGet(obj, identifier);
+ }
+
+ @Override
+ public JexlMethod getMethod(final Object obj, final String method, final Object... args) {
+ return "getClass".equals(method) ? null : super.getMethod(obj, method, args);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/EmptyClassLoader.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/EmptyClassLoader.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/EmptyClassLoader.java
new file mode 100644
index 0000000..037113e
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/EmptyClassLoader.java
@@ -0,0 +1,36 @@
+/*
+ * 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.core.provisioning.java.jexl;
+
+/**
+ * A class loader that will throw {@link ClassNotFoundException} for every class name.
+ */
+class EmptyClassLoader extends ClassLoader {
+
+ @Override
+ public Class<?> loadClass(final String name) throws ClassNotFoundException {
+ throw new ClassNotFoundException("This classloader won't attemp to load " + name);
+ }
+
+ @Override
+ protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+ throw new ClassNotFoundException("This classloader won't attemp to load " + name);
+ }
+
+}
[07/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
deleted file mode 100644
index 9c6294a..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPMembershipSyncActions.java
+++ /dev/null
@@ -1,335 +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.core.provisioning.java.sync;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.MembershipPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.MembershipTO;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.user.UMembership;
-import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
-import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
-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.OperationOptionsBuilder;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-/**
- * Simple action for synchronizing LDAP groups memberships to Syncope group memberships, when the same resource is
- * configured for both users and groups.
- *
- * @see org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions
- */
-public class LDAPMembershipSyncActions extends DefaultSyncActions {
-
- protected static final Logger LOG = LoggerFactory.getLogger(LDAPMembershipSyncActions.class);
-
- @Autowired
- protected AnyTypeDAO anyTypeDAO;
-
- @Autowired
- protected UserDAO userDAO;
-
- @Autowired
- protected GroupDAO groupDAO;
-
- @Autowired
- protected UserWorkflowAdapter uwfAdapter;
-
- @Autowired
- protected PropagationManager propagationManager;
-
- @Autowired
- private PropagationTaskExecutor taskExecutor;
-
- @Autowired
- private NotificationManager notificationManager;
-
- @Autowired
- private AuditManager auditManager;
-
- @Autowired
- private SyncUtils syncUtils;
-
- protected Map<Long, Long> membersBeforeGroupUpdate = Collections.<Long, Long>emptyMap();
-
- /**
- * Allows easy subclassing for the ConnId AD connector bundle.
- *
- * @param connector A Connector instance to query for the groupMemberAttribute property name
- * @return the name of the attribute used to keep track of group memberships
- */
- protected String getGroupMembershipAttrName(final Connector connector) {
- ConnConfProperty groupMembership = IterableUtils.find(connector.getConnInstance().getConf(),
- new Predicate<ConnConfProperty>() {
-
- @Override
- public boolean evaluate(final ConnConfProperty property) {
- return "groupMemberAttribute".equals(property.getSchema().getName())
- && property.getValues() != null && !property.getValues().isEmpty();
- }
- });
-
- return groupMembership == null
- ? "uniquemember"
- : (String) groupMembership.getValues().get(0);
- }
-
- /**
- * Keep track of members of the group being updated <b>before</b> actual update takes place. This is not needed on
- * <ul> <li>beforeProvision() - because the synchronizing group does not exist yet on Syncope</li>
- * <li>beforeDelete() - because group delete cascades as membership removal for all users involved</li> </ul>
- *
- * {@inheritDoc}
- */
- @Override
- public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
- final ProvisioningProfile<?, ?> profile,
- final SyncDelta delta, final A any, final M anyPatch) throws JobExecutionException {
-
- if (any instanceof GroupTO) {
- // search for all users assigned to given group
- Group group = groupDAO.find(any.getKey());
- if (group != null) {
- List<UMembership> membs = groupDAO.findUMemberships(group);
- // save memberships before group update takes place
- membersBeforeGroupUpdate = new HashMap<>(membs.size());
- for (UMembership memb : membs) {
- membersBeforeGroupUpdate.put(memb.getLeftEnd().getKey(), memb.getKey());
- }
- }
- }
-
- return super.beforeUpdate(profile, delta, any, anyPatch);
- }
-
- /**
- * Build UserPatch for adding membership to given user, for given group.
- *
- * @param userKey user to be assigned membership to given group
- * @param groupTO group for adding membership
- * @return UserPatch for user update
- */
- protected UserPatch getUserPatch(final Long userKey, final GroupTO groupTO) {
- UserPatch userPatch = new UserPatch();
- // no actual modification takes place when user has already the group assigned
- if (membersBeforeGroupUpdate.containsKey(userKey)) {
- membersBeforeGroupUpdate.remove(userKey);
- } else {
- userPatch.setKey(userKey);
-
- userPatch.getMemberships().add(
- new MembershipPatch.Builder().
- operation(PatchOperation.ADD_REPLACE).
- membershipTO(new MembershipTO.Builder().group(groupTO.getKey(), null).build()).
- build());
- }
-
- return userPatch;
- }
-
- /**
- * Read values of attribute returned by getGroupMembershipAttrName(); if not present in the given delta, perform an
- * additional read on the underlying connector.
- *
- * @param delta representing the synchronizing group
- * @param connector associated to the current resource
- * @return value of attribute returned by
- * {@link #getGroupMembershipAttrName}
- */
- protected List<Object> getMembAttrValues(final SyncDelta delta, final Connector connector) {
- List<Object> result = Collections.<Object>emptyList();
- String groupMemberName = getGroupMembershipAttrName(connector);
-
- // first, try to read the configured attribute from delta, returned by the ongoing synchronization
- Attribute membAttr = delta.getObject().getAttributeByName(groupMemberName);
- // if not found, perform an additional read on the underlying connector for the same connector object
- if (membAttr == null) {
- OperationOptionsBuilder oob = new OperationOptionsBuilder();
- oob.setAttributesToGet(groupMemberName);
- ConnectorObject remoteObj = connector.getObject(ObjectClass.GROUP, delta.getUid(), oob.build());
- if (remoteObj == null) {
- LOG.debug("Object for '{}' not found", delta.getUid().getUidValue());
- } else {
- membAttr = remoteObj.getAttributeByName(groupMemberName);
- }
- }
- if (membAttr != null && membAttr.getValue() != null) {
- result = membAttr.getValue();
- }
-
- return result;
- }
-
- /**
- * Perform actual modifications (i.e. membership add / remove) for the given group on the given resource.
- *
- * @param userPatch modifications to perform on the user
- * @param resourceName resource to be propagated for changes
- */
- protected void userUpdate(final UserPatch userPatch, final String resourceName) {
- if (userPatch.getKey() == 0) {
- return;
- }
-
- Result result;
-
- WorkflowResult<Pair<UserPatch, Boolean>> updated = null;
-
- try {
- updated = uwfAdapter.update(userPatch);
-
- List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
- updated, false, Collections.singleton(resourceName));
-
- taskExecutor.execute(tasks);
- result = Result.SUCCESS;
- } catch (PropagationException e) {
- result = Result.FAILURE;
- LOG.error("Could not propagate {}", userPatch, e);
- } catch (Exception e) {
- result = Result.FAILURE;
- LOG.error("Could not perform update {}", userPatch, e);
- }
-
- notificationManager.createTasks(
- AuditElements.EventCategoryType.SYNCHRONIZATION,
- this.getClass().getSimpleName(),
- null,
- "update",
- result,
- null, // searching for before object is too much expensive ...
- updated == null ? null : updated.getResult().getKey(),
- userPatch,
- resourceName);
-
- auditManager.audit(
- AuditElements.EventCategoryType.SYNCHRONIZATION,
- this.getClass().getSimpleName(),
- null,
- "update",
- result,
- null, // searching for before object is too much expensive ...
- updated == null ? null : updated.getResult().getKey(),
- userPatch,
- resourceName);
- }
-
- /**
- * Synchronize Syncope memberships with the situation read on the external resource's group.
- *
- * @param profile sync profile
- * @param delta representing the synchronizing group
- * @param groupTO group after modification performed by the handler
- * @throws JobExecutionException if anything goes wrong
- */
- protected void synchronizeMemberships(
- final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final GroupTO groupTO)
- throws JobExecutionException {
-
- ProvisioningTask task = profile.getTask();
- ExternalResource resource = task.getResource();
- Connector connector = profile.getConnector();
-
- for (Object membValue : getMembAttrValues(delta, connector)) {
- Long userKey = syncUtils.findMatchingAnyKey(
- anyTypeDAO.findUser(),
- membValue.toString(),
- profile.getTask().getResource(),
- profile.getConnector());
- if (userKey != null) {
- UserPatch userPatch = getUserPatch(userKey, groupTO);
- userUpdate(userPatch, resource.getKey());
- }
- }
-
- // finally remove any residual membership that was present before group update but not any more
- for (Map.Entry<Long, Long> member : membersBeforeGroupUpdate.entrySet()) {
- UserPatch userPatch = new UserPatch();
- userPatch.setKey(member.getKey());
-
- userPatch.getMemberships().add(
- new MembershipPatch.Builder().
- operation(PatchOperation.DELETE).
- membershipTO(new MembershipTO.Builder().group(groupTO.getKey(), null).build()).
- build());
-
- userUpdate(userPatch, resource.getKey());
- }
- }
-
- /**
- * Synchronize membership at group synchronization time (because SyncJob first synchronize users then groups).
- * {@inheritDoc}
- */
- @Override
- public <A extends AnyTO> void after(
- final ProvisioningProfile<?, ?> profile,
- final SyncDelta delta,
- final A any,
- final ProvisioningReport result) throws JobExecutionException {
-
- if (!(profile.getTask() instanceof SyncTask)) {
- return;
- }
-
- if (!(any instanceof GroupTO)
- || profile.getTask().getResource().getProvision(anyTypeDAO.findUser()) == null
- || profile.getTask().getResource().getProvision(anyTypeDAO.findUser()).getMapping() == null) {
-
- super.after(profile, delta, any, result);
- } else {
- synchronizeMemberships(profile, delta, (GroupTO) any);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPPasswordSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPPasswordSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPPasswordSyncActions.java
deleted file mode 100644
index 3f08704..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/LDAPPasswordSyncActions.java
+++ /dev/null
@@ -1,124 +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.core.provisioning.java.sync;
-
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.UserTO;
-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.user.User;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.crypto.codec.Base64;
-import org.springframework.security.crypto.codec.Hex;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * A SyncActions implementation which allows the ability to import passwords from an LDAP backend
- * that are hashed.
- */
-public class LDAPPasswordSyncActions extends DefaultSyncActions {
-
- protected static final Logger LOG = LoggerFactory.getLogger(LDAPPasswordSyncActions.class);
-
- @Autowired
- private UserDAO userDAO;
-
- private String encodedPassword;
-
- private CipherAlgorithm cipher;
-
- @Transactional(readOnly = true)
- @Override
- public <A extends AnyTO> SyncDelta beforeProvision(
- final ProvisioningProfile<?, ?> profile,
- final SyncDelta delta,
- final A any) throws JobExecutionException {
-
- if (any instanceof UserTO) {
- String password = ((UserTO) any).getPassword();
- parseEncodedPassword(password);
- }
-
- return delta;
- }
-
- @Transactional(readOnly = true)
- @Override
- public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
- final ProvisioningProfile<?, ?> profile,
- final SyncDelta delta,
- final A any,
- final M anyPatch) throws JobExecutionException {
-
- if (anyPatch instanceof UserPatch) {
- PasswordPatch modPassword = ((UserPatch) anyPatch).getPassword();
- parseEncodedPassword(modPassword == null ? null : modPassword.getValue());
- }
-
- return delta;
- }
-
- private void parseEncodedPassword(final String password) {
- if (password != null && password.startsWith("{")) {
- int closingBracketIndex = password.indexOf('}');
- String digest = password.substring(1, password.indexOf('}'));
- if (digest != null) {
- digest = digest.toUpperCase();
- }
- try {
- encodedPassword = password.substring(closingBracketIndex + 1);
- cipher = CipherAlgorithm.valueOf(digest);
- } catch (IllegalArgumentException e) {
- LOG.error("Cipher algorithm not allowed: {}", digest, e);
- encodedPassword = null;
- }
- }
- }
-
- @Transactional(readOnly = true)
- @Override
- public <A extends AnyTO> void after(
- final ProvisioningProfile<?, ?> profile,
- final SyncDelta delta,
- final A any,
- final ProvisioningReport result) throws JobExecutionException {
-
- if (any instanceof UserTO && encodedPassword != null && cipher != null) {
- User syncopeUser = userDAO.find(any.getKey());
- if (syncopeUser != null) {
- byte[] encodedPasswordBytes = Base64.decode(encodedPassword.getBytes());
- char[] encodedHex = Hex.encode(encodedPasswordBytes);
- String encodedHexStr = new String(encodedHex).toUpperCase();
-
- syncopeUser.setEncodedPassword(encodedHexStr, cipher);
- }
- encodedPassword = null;
- cipher = null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PlainAttrsSyncCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PlainAttrsSyncCorrelationRule.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PlainAttrsSyncCorrelationRule.java
deleted file mode 100644
index 14ba28e..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PlainAttrsSyncCorrelationRule.java
+++ /dev/null
@@ -1,115 +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.core.provisioning.java.sync;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
-import org.apache.syncope.core.provisioning.api.sync.SyncCorrelationRule;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-
-public class PlainAttrsSyncCorrelationRule implements SyncCorrelationRule {
-
- private final List<String> plainSchemaNames;
-
- private final Provision provision;
-
- public PlainAttrsSyncCorrelationRule(final String[] plainSchemaNames, final Provision provision) {
- this.plainSchemaNames = Arrays.asList(plainSchemaNames);
- this.provision = provision;
- }
-
- @Override
- public SearchCond getSearchCond(final ConnectorObject connObj) {
- Map<String, MappingItem> mappingItems = new HashMap<>();
- for (MappingItem item : MappingUtils.getSyncMappingItems(provision)) {
- mappingItems.put(item.getIntAttrName(), item);
- }
-
- // search for anys by attribute(s) specified in the policy
- SearchCond searchCond = null;
-
- for (String schema : plainSchemaNames) {
- Attribute attr = mappingItems.get(schema) == null
- ? null
- : connObj.getAttributeByName(mappingItems.get(schema).getExtAttrName());
- if (attr == null) {
- throw new IllegalArgumentException(
- "Connector object does not contains the attributes to perform the search: " + schema);
- }
-
- List<Object> values = attr.getValue();
- for (MappingItemTransformer transformer
- : MappingUtils.getMappingItemTransformers(mappingItems.get(schema))) {
-
- values = transformer.beforeSync(values);
- }
-
- AttributeCond.Type type;
- String expression = null;
-
- if (values == null || values.isEmpty() || (values.size() == 1 && values.get(0) == null)) {
- type = AttributeCond.Type.ISNULL;
- } else {
- type = AttributeCond.Type.EQ;
- expression = values.size() > 1
- ? values.toString()
- : values.get(0).toString();
- }
-
- SearchCond nodeCond;
- // users: just key or username can be selected
- // groups: just key or name can be selected
- // any objects: just key can be selected
- if ("key".equalsIgnoreCase(schema)
- || "username".equalsIgnoreCase(schema) || "name".equalsIgnoreCase(schema)) {
-
- AnyCond cond = new AnyCond();
- cond.setSchema(schema);
- cond.setType(type);
- cond.setExpression(expression);
-
- nodeCond = SearchCond.getLeafCond(cond);
- } else {
- AttributeCond cond = new AttributeCond();
- cond.setSchema(schema);
- cond.setType(type);
- cond.setExpression(expression);
-
- nodeCond = SearchCond.getLeafCond(cond);
- }
-
- searchCond = searchCond == null
- ? nodeCond
- : SearchCond.getAndCond(searchCond, nodeCond);
- }
-
- return searchCond;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java
deleted file mode 100644
index ba70634..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PushJobDelegate.java
+++ /dev/null
@@ -1,206 +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.core.provisioning.java.sync;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.dao.AnyDAO;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.sync.AnyObjectPushResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.GroupPushResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.UserPushResultHandler;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-
-public class PushJobDelegate extends AbstractProvisioningJobDelegate<PushTask> {
-
- private static final int PAGE_SIZE = 1000;
-
- /**
- * User DAO.
- */
- @Autowired
- private UserDAO userDAO;
-
- /**
- * Search DAO.
- */
- @Autowired
- private AnySearchDAO searchDAO;
-
- /**
- * Group DAO.
- */
- @Autowired
- private GroupDAO groupDAO;
-
- @Autowired
- private AnyObjectDAO anyObjectDAO;
-
- private AnyDAO<?> getAnyDAO(final AnyTypeKind anyTypeKind) {
- AnyDAO<?> result;
- switch (anyTypeKind) {
- case USER:
- result = userDAO;
- break;
-
- case GROUP:
- result = groupDAO;
- break;
-
- case ANY_OBJECT:
- default:
- result = anyObjectDAO;
- }
-
- return result;
- }
-
- protected void handle(
- final List<? extends Any<?>> anys,
- final SyncopePushResultHandler handler,
- final ExternalResource resource)
- throws JobExecutionException {
-
- for (Any<?> any : anys) {
- try {
- handler.handle(any.getKey());
- } catch (Exception e) {
- LOG.warn("Failure pushing '{}' on '{}'", any, resource, e);
- throw new JobExecutionException("While pushing " + any + " on " + resource, e);
- }
- }
- }
-
- @Override
- protected String doExecuteProvisioning(
- final PushTask pushTask,
- final Connector connector,
- final boolean dryRun) throws JobExecutionException {
-
- LOG.debug("Executing push on {}", pushTask.getResource());
-
- List<PushActions> actions = new ArrayList<>();
- for (String className : pushTask.getActionsClassNames()) {
- try {
- Class<?> actionsClass = Class.forName(className);
-
- PushActions syncActions = (PushActions) ApplicationContextProvider.getBeanFactory().
- createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
- actions.add(syncActions);
- } catch (Exception e) {
- LOG.info("Class '{}' not found", className, e);
- }
- }
-
- ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
- profile.setDryRun(dryRun);
- profile.setResAct(null);
-
- AnyObjectPushResultHandler ahandler =
- (AnyObjectPushResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(AnyObjectPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- ahandler.setProfile(profile);
-
- UserPushResultHandler uhandler =
- (UserPushResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- uhandler.setProfile(profile);
-
- GroupPushResultHandler ghandler =
- (GroupPushResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- ghandler.setProfile(profile);
-
- if (!profile.isDryRun()) {
- for (PushActions action : actions) {
- action.beforeAll(profile);
- }
- }
-
- for (Provision provision : pushTask.getResource().getProvisions()) {
- if (provision.getMapping() != null) {
- AnyDAO<?> anyDAO = getAnyDAO(provision.getAnyType().getKind());
-
- SyncopePushResultHandler handler;
- switch (provision.getAnyType().getKind()) {
- case USER:
- handler = uhandler;
- break;
-
- case GROUP:
- handler = ghandler;
- break;
-
- case ANY_OBJECT:
- default:
- handler = ahandler;
- }
-
- String filter = pushTask.getFilter(provision.getAnyType()) == null
- ? null
- : pushTask.getFilter(provision.getAnyType()).getFIQLCond();
- if (StringUtils.isBlank(filter)) {
- handle(anyDAO.findAll(), handler, pushTask.getResource());
- } else {
- int count = anyDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
- for (int page = 1; page <= (count / PAGE_SIZE) + 1; page++) {
- List<? extends Any<?>> anys = searchDAO.search(
- SyncopeConstants.FULL_ADMIN_REALMS,
- SearchCondConverter.convert(filter),
- page,
- PAGE_SIZE,
- Collections.<OrderByClause>emptyList(),
- provision.getAnyType().getKind());
- handle(anys, handler, pushTask.getResource());
- }
- }
- }
- }
-
- if (!profile.isDryRun()) {
- for (PushActions action : actions) {
- action.afterAll(profile);
- }
- }
-
- String result = createReport(profile.getResults(), pushTask.getResource().getSyncTraceLevel(), dryRun);
- LOG.debug("Sync result: {}", result);
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
deleted file mode 100644
index cf0f020..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncJobDelegate.java
+++ /dev/null
@@ -1,251 +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.core.provisioning.java.sync;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.apache.commons.collections4.IteratorUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.policy.SyncPolicySpec;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.sync.AnyObjectSyncResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.GroupSyncResultHandler;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-import org.apache.syncope.core.provisioning.api.sync.UserSyncResultHandler;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
-import org.identityconnectors.framework.common.objects.SyncToken;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder;
-
-public class SyncJobDelegate extends AbstractProvisioningJobDelegate<SyncTask> {
-
- @Autowired
- private UserDAO userDAO;
-
- @Autowired
- private GroupDAO groupDAO;
-
- @Autowired
- private VirSchemaDAO virSchemaDAO;
-
- @Autowired
- protected SyncUtils syncUtils;
-
- protected void setGroupOwners(final GroupSyncResultHandler ghandler) {
- for (Map.Entry<Long, String> entry : ghandler.getGroupOwnerMap().entrySet()) {
- Group group = groupDAO.find(entry.getKey());
- if (group == null) {
- throw new NotFoundException("Group " + entry.getKey());
- }
-
- if (StringUtils.isBlank(entry.getValue())) {
- group.setGroupOwner(null);
- group.setUserOwner(null);
- } else {
- Long userKey = syncUtils.findMatchingAnyKey(
- anyTypeDAO.findUser(),
- entry.getValue(),
- ghandler.getProfile().getTask().getResource(),
- ghandler.getProfile().getConnector());
-
- if (userKey == null) {
- Long groupKey = syncUtils.findMatchingAnyKey(
- anyTypeDAO.findGroup(),
- entry.getValue(),
- ghandler.getProfile().getTask().getResource(),
- ghandler.getProfile().getConnector());
-
- if (groupKey != null) {
- group.setGroupOwner(groupDAO.find(groupKey));
- }
- } else {
- group.setUserOwner(userDAO.find(userKey));
- }
- }
-
- groupDAO.save(group);
- }
- }
-
- @Override
- protected String doExecuteProvisioning(
- final SyncTask syncTask,
- final Connector connector,
- final boolean dryRun) throws JobExecutionException {
-
- LOG.debug("Executing sync on {}", syncTask.getResource());
-
- List<SyncActions> actions = new ArrayList<>();
- for (String className : syncTask.getActionsClassNames()) {
- try {
- Class<?> actionsClass = Class.forName(className);
- SyncActions syncActions = (SyncActions) ApplicationContextProvider.getBeanFactory().
- createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
-
- actions.add(syncActions);
- } catch (Exception e) {
- LOG.warn("Class '{}' not found", className, e);
- }
- }
-
- ProvisioningProfile<SyncTask, SyncActions> profile = new ProvisioningProfile<>(connector, syncTask);
- profile.getActions().addAll(actions);
- profile.setDryRun(dryRun);
- profile.setResAct(getSyncPolicySpec(syncTask).getConflictResolutionAction());
-
- // Prepare handler for SyncDelta objects (any objects)
- AnyObjectSyncResultHandler ahandler = (AnyObjectSyncResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(AnyObjectSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- ahandler.setProfile(profile);
-
- // Prepare handler for SyncDelta objects (users)
- UserSyncResultHandler uhandler = (UserSyncResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(UserSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- uhandler.setProfile(profile);
-
- // Prepare handler for SyncDelta objects (groups)
- GroupSyncResultHandler ghandler = (GroupSyncResultHandler) ApplicationContextProvider.getBeanFactory().
- createBean(GroupSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- ghandler.setProfile(profile);
-
- if (!profile.isDryRun()) {
- for (SyncActions action : actions) {
- action.beforeAll(profile);
- }
- }
-
- for (Provision provision : syncTask.getResource().getProvisions()) {
- if (provision.getMapping() != null) {
- SyncResultsHandler handler;
- switch (provision.getAnyType().getKind()) {
- case USER:
- handler = uhandler;
- break;
-
- case GROUP:
- handler = ghandler;
- break;
-
- case ANY_OBJECT:
- default:
- handler = ahandler;
- }
-
- try {
- Set<MappingItem> linkinMappingItems = new HashSet<>();
- for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) {
- linkinMappingItems.add(virSchema.asLinkingMappingItem());
- }
- Iterator<MappingItem> mapItems = IteratorUtils.chainedIterator(
- provision.getMapping().getItems().iterator(),
- linkinMappingItems.iterator());
-
- switch (syncTask.getSyncMode()) {
- case INCREMENTAL:
- SyncToken latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass());
- connector.sync(
- provision.getObjectClass(),
- provision.getSyncToken(),
- handler,
- MappingUtils.buildOperationOptions(mapItems));
- if (!dryRun) {
- provision.setSyncToken(latestSyncToken);
- resourceDAO.save(provision.getResource());
- }
- break;
-
- case FILTERED_RECONCILIATION:
- ReconciliationFilterBuilder filterBuilder =
- (ReconciliationFilterBuilder) ApplicationContextProvider.getBeanFactory().
- createBean(Class.forName(syncTask.getReconciliationFilterBuilderClassName()),
- AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
- connector.filteredReconciliation(
- provision.getObjectClass(),
- filterBuilder,
- handler,
- MappingUtils.buildOperationOptions(mapItems));
- break;
-
- case FULL_RECONCILIATION:
- default:
- connector.fullReconciliation(
- provision.getObjectClass(),
- handler,
- MappingUtils.buildOperationOptions(mapItems));
- break;
- }
- } catch (Throwable t) {
- throw new JobExecutionException("While syncing from connector", t);
- }
- }
- }
-
- try {
- setGroupOwners(ghandler);
- } catch (Exception e) {
- LOG.error("While setting group owners", e);
- }
-
- if (!profile.isDryRun()) {
- for (SyncActions action : actions) {
- action.afterAll(profile);
- }
- }
-
- String result = createReport(profile.getResults(), syncTask.getResource().getSyncTraceLevel(), dryRun);
-
- LOG.debug("Sync result: {}", result);
-
- return result;
- }
-
- private SyncPolicySpec getSyncPolicySpec(final ProvisioningTask task) {
- SyncPolicySpec syncPolicySpec;
-
- if (task instanceof SyncTask) {
- syncPolicySpec = task.getResource().getSyncPolicy() == null
- ? null
- : task.getResource().getSyncPolicy().getSpecification();
- } else {
- syncPolicySpec = null;
- }
-
- // step required because the call <policy>.getSpecification() could return a null value
- return syncPolicySpec == null ? new SyncPolicySpec() : syncPolicySpec;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
deleted file mode 100644
index 17749d1..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
+++ /dev/null
@@ -1,318 +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.core.provisioning.java.sync;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.policy.SyncPolicySpec;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
-import org.apache.syncope.core.persistence.api.dao.AnyDAO;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
-import org.apache.syncope.core.provisioning.api.sync.SyncCorrelationRule;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.AttributeUtil;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.Name;
-import org.identityconnectors.framework.common.objects.OperationalAttributes;
-import org.identityconnectors.framework.common.objects.ResultsHandler;
-import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional(readOnly = true)
-@Component
-public class SyncUtils {
-
- private static final Logger LOG = LoggerFactory.getLogger(SyncUtils.class);
-
- /**
- * Schema DAO.
- */
- @Autowired
- private PlainSchemaDAO plainSchemaDAO;
-
- /**
- * Any Object DAO.
- */
- @Autowired
- private AnyObjectDAO anyObjectDAO;
-
- /**
- * User DAO.
- */
- @Autowired
- private UserDAO userDAO;
-
- /**
- * Group DAO.
- */
- @Autowired
- private GroupDAO groupDAO;
-
- /**
- * Search DAO.
- */
- @Autowired
- private AnySearchDAO searchDAO;
-
- @Autowired
- private AnyUtilsFactory anyUtilsFactory;
-
- public Long findMatchingAnyKey(
- final AnyType anyType,
- final String name,
- final ExternalResource resource,
- final Connector connector) {
-
- Provision provision = resource.getProvision(anyType);
- if (provision == null) {
- return null;
- }
-
- Long result = null;
-
- AnyUtils anyUtils = anyUtilsFactory.getInstance(anyType.getKind());
-
- final List<ConnectorObject> found = new ArrayList<>();
- connector.search(
- provision.getObjectClass(),
- new EqualsFilter(new Name(name)),
- new ResultsHandler() {
-
- @Override
- public boolean handle(final ConnectorObject obj) {
- return found.add(obj);
- }
- },
- MappingUtils.buildOperationOptions(MappingUtils.getSyncMappingItems(provision).iterator()));
-
- if (found.isEmpty()) {
- LOG.debug("No {} found on {} with __NAME__ {}", provision.getObjectClass(), resource, name);
- } else {
- if (found.size() > 1) {
- LOG.warn("More than one {} found on {} with __NAME__ {} - taking first only",
- provision.getObjectClass(), resource, name);
- }
-
- ConnectorObject connObj = found.iterator().next();
- try {
- List<Long> anyKeys = findExisting(connObj.getUid().getUidValue(), connObj, provision, anyUtils);
- if (anyKeys.isEmpty()) {
- LOG.debug("No matching {} found for {}, aborting", anyUtils.getAnyTypeKind(), connObj);
- } else {
- if (anyKeys.size() > 1) {
- LOG.warn("More than one {} found {} - taking first only", anyUtils.getAnyTypeKind(), anyKeys);
- }
-
- result = anyKeys.iterator().next();
- }
- } catch (IllegalArgumentException e) {
- LOG.warn(e.getMessage());
- }
- }
-
- return result;
- }
-
- private AnyDAO<?> getAnyDAO(final MappingItem connObjectKeyItem) {
- return AnyTypeKind.USER == connObjectKeyItem.getIntMappingType().getAnyTypeKind()
- ? userDAO
- : AnyTypeKind.ANY_OBJECT == connObjectKeyItem.getIntMappingType().getAnyTypeKind()
- ? anyObjectDAO
- : groupDAO;
- }
-
- private List<Long> findByConnObjectKeyItem(
- final String uid, final Provision provision, final AnyUtils anyUtils) {
-
- List<Long> result = new ArrayList<>();
-
- MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
-
- String transfUid = uid;
- for (MappingItemTransformer transformer : MappingUtils.getMappingItemTransformers(connObjectKeyItem)) {
- List<Object> output = transformer.beforeSync(Collections.<Object>singletonList(transfUid));
- if (output != null && !output.isEmpty()) {
- transfUid = output.get(0).toString();
- }
- }
-
- switch (connObjectKeyItem.getIntMappingType()) {
- case UserPlainSchema:
- case GroupPlainSchema:
- case AnyObjectPlainSchema:
- PlainAttrValue value = anyUtils.newPlainAttrValue();
-
- PlainSchema schema = plainSchemaDAO.find(connObjectKeyItem.getIntAttrName());
- if (schema == null) {
- value.setStringValue(transfUid);
- } else {
- try {
- value.parseValue(schema, transfUid);
- } catch (ParsingValidationException e) {
- LOG.error("While parsing provided __UID__ {}", transfUid, e);
- value.setStringValue(transfUid);
- }
- }
-
- List<? extends Any<?>> anys =
- getAnyDAO(connObjectKeyItem).findByAttrValue(connObjectKeyItem.getIntAttrName(), value);
- for (Any<?> any : anys) {
- result.add(any.getKey());
- }
- break;
-
- case UserDerivedSchema:
- case GroupDerivedSchema:
- case AnyObjectDerivedSchema:
- anys = getAnyDAO(connObjectKeyItem).findByDerAttrValue(connObjectKeyItem.getIntAttrName(), transfUid);
- for (Any<?> any : anys) {
- result.add(any.getKey());
- }
- break;
-
- case UserKey:
- case GroupKey:
- case AnyObjectKey:
- Any<?> any = getAnyDAO(connObjectKeyItem).find(Long.parseLong(transfUid));
- if (any != null) {
- result.add(any.getKey());
- }
- break;
-
- case Username:
- User user = userDAO.find(transfUid);
- if (user != null) {
- result.add(user.getKey());
- }
- break;
-
- case GroupName:
- Group group = groupDAO.find(transfUid);
- if (group != null) {
- result.add(group.getKey());
- }
- break;
-
- default:
- LOG.error("Invalid connObjectKey type '{}'", connObjectKeyItem.getIntMappingType());
- }
-
- return result;
- }
-
- private List<Long> findByCorrelationRule(
- final ConnectorObject connObj, final SyncCorrelationRule rule, final AnyTypeKind type) {
-
- List<Long> result = new ArrayList<>();
- for (Any<?> any : searchDAO.search(rule.getSearchCond(connObj), type)) {
- result.add(any.getKey());
- }
-
- return result;
- }
-
- private SyncCorrelationRule getCorrelationRule(final Provision provision, final SyncPolicySpec policySpec) {
- SyncCorrelationRule result = null;
-
- String syncCorrelationRule = policySpec.getCorrelationRules().get(provision.getAnyType().getKey());
- if (StringUtils.isNotBlank(syncCorrelationRule)) {
- if (syncCorrelationRule.charAt(0) == '[') {
- result = new PlainAttrsSyncCorrelationRule(
- POJOHelper.deserialize(syncCorrelationRule, String[].class), provision);
- } else {
- try {
- result = (SyncCorrelationRule) Class.forName(syncCorrelationRule).newInstance();
- } catch (Exception e) {
- LOG.error("Failure instantiating correlation rule class '{}'", syncCorrelationRule, e);
- }
- }
- }
-
- return result;
- }
-
- /**
- * Find any objects based on mapped uid value (or previous uid value, if updated).
- *
- * @param uid for finding by connObjectKey
- * @param connObj for finding by attribute value
- * @param provision external resource
- * @param anyUtils any util
- * @return list of matching users / groups
- */
- public List<Long> findExisting(
- final String uid,
- final ConnectorObject connObj,
- final Provision provision,
- final AnyUtils anyUtils) {
-
- SyncPolicySpec syncPolicySpec = null;
- if (provision.getResource().getSyncPolicy() != null) {
- syncPolicySpec = provision.getResource().getSyncPolicy().getSpecification();
- }
-
- SyncCorrelationRule syncRule = null;
- if (syncPolicySpec != null) {
- syncRule = getCorrelationRule(provision, syncPolicySpec);
- }
-
- return syncRule == null
- ? findByConnObjectKeyItem(uid, provision, anyUtils)
- : findByCorrelationRule(connObj, syncRule, anyUtils.getAnyTypeKind());
- }
-
- public Boolean readEnabled(final ConnectorObject connectorObject, final ProvisioningTask task) {
- Boolean enabled = null;
- if (task.isSyncStatus()) {
- Attribute status = AttributeUtil.find(OperationalAttributes.ENABLE_NAME, connectorObject.getAttributes());
- if (status != null && status.getValue() != null && !status.getValue().isEmpty()) {
- enabled = (Boolean) status.getValue().get(0);
- }
- }
-
- return enabled;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
deleted file mode 100644
index 03865d7..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserPushResultHandlerImpl.java
+++ /dev/null
@@ -1,96 +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.core.provisioning.java.sync;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.sync.UserPushResultHandler;
-
-public class UserPushResultHandlerImpl extends AbstractPushResultHandler implements UserPushResultHandler {
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.USER);
- }
-
- @Override
- protected void provision(final Any<?> any, final Boolean enabled) {
- AnyTO before = getAnyTO(any.getKey());
-
- List<String> noPropResources = new ArrayList<>(before.getResources());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
- taskExecutor.execute(propagationManager.getUserCreateTasks(
- before.getKey(),
- null,
- enabled,
- propByRes,
- before.getVirAttrs(),
- noPropResources));
- }
-
- @Override
- protected String getName(final Any<?> any) {
- return User.class.cast(any).getUsername();
- }
-
- @Override
- protected Any<?> getAny(final long key) {
- try {
- return userDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving user {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final long key) {
- return userDataBinder.getUserTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final long key) {
- UserPatch patch = new UserPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<Long> update(final AnyPatch patch) {
- WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
- return new WorkflowResult<>(
- update.getResult().getLeft().getKey(), update.getPropByRes(), update.getPerformedTasks());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
deleted file mode 100644
index 2a222d0..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
+++ /dev/null
@@ -1,133 +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.core.provisioning.java.sync;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.sync.UserSyncResultHandler;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-
-public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler implements UserSyncResultHandler {
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.USER);
- }
-
- @Override
- protected String getName(final AnyTO anyTO) {
- return UserTO.class.cast(anyTO).getUsername();
- }
-
- @Override
- protected ProvisioningManager<?, ?> getProvisioningManager() {
- return userProvisioningManager;
- }
-
- @Override
- protected Any<?> getAny(final long key) {
- try {
- return userDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving user {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final long key) {
- return userDataBinder.getUserTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final long key) {
- UserPatch patch = new UserPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<Long> update(final AnyPatch patch) {
- WorkflowResult<Pair<UserPatch, Boolean>> update = uwfAdapter.update((UserPatch) patch);
- return new WorkflowResult<>(
- update.getResult().getLeft().getKey(), update.getPropByRes(), update.getPerformedTasks());
- }
-
- @Override
- protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningReport result) {
- UserTO userTO = UserTO.class.cast(anyTO);
-
- Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
- Map.Entry<Long, List<PropagationStatus>> created =
- userProvisioningManager.create(userTO, true, true, enabled,
- Collections.singleton(profile.getTask().getResource().getKey()), true);
-
- result.setKey(created.getKey());
- result.setName(getName(anyTO));
-
- return getAnyTO(created.getKey());
- }
-
- @Override
- protected AnyTO doUpdate(
- final AnyTO before,
- final AnyPatch anyPatch,
- final SyncDelta delta,
- final ProvisioningReport result) {
-
- UserPatch userPatch = UserPatch.class.cast(anyPatch);
- Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
-
- Map.Entry<Long, List<PropagationStatus>> updated = userProvisioningManager.update(
- userPatch,
- result,
- enabled,
- Collections.singleton(profile.getTask().getResource().getKey()),
- true);
-
- return getAnyTO(updated.getKey());
- }
-
- @Override
- protected void doDelete(final AnyTypeKind kind, final Long key) {
- try {
- userProvisioningManager.delete(
- key, Collections.<String>singleton(profile.getTask().getResource().getKey()), true);
- } catch (Exception e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate user " + key, e);
- }
-
- uwfAdapter.delete(key);
- }
-}
[08/17] syncope git commit: Further refactoring as per SYNCOPE-620
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
deleted file mode 100644
index 2c5bbb9..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncResultHandler.java
+++ /dev/null
@@ -1,797 +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.core.provisioning.java.sync;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.StringPatchItem;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.MatchingRule;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-import org.apache.syncope.core.misc.security.DelegatedAdministrationException;
-import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
-import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
-import org.apache.syncope.core.provisioning.api.sync.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.sync.SyncopeSyncResultHandler;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncDeltaType;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional(rollbackFor = Throwable.class)
-public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHandler<SyncTask, SyncActions>
- implements SyncopeSyncResultHandler {
-
- @Autowired
- protected SyncUtils syncUtilities;
-
- @Autowired
- protected VirSchemaDAO virSchemaDAO;
-
- @Autowired
- protected VirAttrCache virAttrCache;
-
- protected abstract String getName(AnyTO anyTO);
-
- protected abstract ProvisioningManager<?, ?> getProvisioningManager();
-
- protected abstract AnyTO doCreate(AnyTO anyTO, SyncDelta delta, ProvisioningReport result);
-
- protected AnyTO doLink(final AnyTO before, final boolean unlink) {
- AnyPatch patch = newPatch(before.getKey());
- patch.setKey(before.getKey());
- patch.getResources().add(new StringPatchItem.Builder().
- operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE).
- value(profile.getTask().getResource().getKey()).build());
-
- return getAnyTO(update(patch).getResult());
- }
-
- protected abstract AnyTO doUpdate(AnyTO before, AnyPatch anyPatch, SyncDelta delta, ProvisioningReport result);
-
- protected void doDeprovision(final AnyTypeKind kind, final Long key, final boolean unlink) {
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
- taskExecutor.execute(propagationManager.getDeleteTasks(
- kind,
- key,
- propByRes,
- null));
-
- if (unlink) {
- AnyPatch anyObjectPatch = newPatch(key);
- anyObjectPatch.getResources().add(new StringPatchItem.Builder().
- operation(PatchOperation.DELETE).
- value(profile.getTask().getResource().getKey()).build());
- }
- }
-
- protected void doDelete(final AnyTypeKind kind, final Long key) {
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.DELETE, profile.getTask().getResource().getKey());
- try {
- taskExecutor.execute(propagationManager.getDeleteTasks(
- kind,
- key,
- propByRes,
- null));
- } catch (Exception e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate anyObject " + key, e);
- }
-
- getProvisioningManager().delete(key, true);
- }
-
- @Override
- public boolean handle(final SyncDelta delta) {
- Provision provision = null;
- try {
- provision = profile.getTask().getResource().getProvision(delta.getObject().getObjectClass());
- if (provision == null) {
- throw new JobExecutionException("No provision found on " + profile.getTask().getResource() + " for "
- + delta.getObject().getObjectClass());
- }
-
- doHandle(delta, provision);
- return true;
- } catch (IgnoreProvisionException e) {
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.NONE);
- result.setAnyType(provision == null
- ? getAnyUtils().getAnyTypeKind().name() : provision.getAnyType().getKey());
- result.setStatus(ProvisioningReport.Status.IGNORE);
- result.setKey(0L);
- result.setName(delta.getObject().getName().getNameValue());
- profile.getResults().add(result);
-
- LOG.warn("Ignoring during synchronization", e);
- return true;
- } catch (JobExecutionException e) {
- LOG.error("Synchronization failed", e);
- return false;
- }
- }
-
- protected List<ProvisioningReport> assign(
- final SyncDelta delta, final Provision provision, final AnyUtils anyUtils)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("SyncTask not configured for create");
- return Collections.<ProvisioningReport>emptyList();
- }
-
- AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
-
- anyTO.getResources().add(profile.getTask().getResource().getKey());
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.CREATE);
- result.setAnyType(provision.getAnyType().getKey());
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setName(getName(anyTO));
-
- if (profile.isDryRun()) {
- result.setKey(0L);
- } else {
- SyncDelta actionedDelta = delta;
- for (SyncActions action : profile.getActions()) {
- actionedDelta = action.beforeAssign(this.getProfile(), actionedDelta, anyTO);
- }
-
- create(anyTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.ASSIGN), result);
- }
-
- return Collections.singletonList(result);
- }
-
- protected List<ProvisioningReport> provision(
- final SyncDelta delta, final Provision provision, final AnyUtils anyUtils)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("SyncTask not configured for create");
- return Collections.<ProvisioningReport>emptyList();
- }
-
- AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.CREATE);
- result.setAnyType(provision.getAnyType().getKey());
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setName(getName(anyTO));
-
- if (profile.isDryRun()) {
- result.setKey(0L);
- } else {
- SyncDelta actionedDelta = delta;
- for (SyncActions action : profile.getActions()) {
- actionedDelta = action.beforeProvision(this.getProfile(), actionedDelta, anyTO);
- }
-
- create(anyTO, actionedDelta, UnmatchingRule.toEventName(UnmatchingRule.PROVISION), result);
- }
-
- return Collections.singletonList(result);
- }
-
- private void create(
- final AnyTO anyTO,
- final SyncDelta delta,
- final String operation,
- final ProvisioningReport result)
- throws JobExecutionException {
-
- Object output;
- Result resultStatus;
-
- try {
- AnyTO actual = doCreate(anyTO, delta, result);
- result.setName(getName(actual));
- output = actual;
- resultStatus = Result.SUCCESS;
-
- for (SyncActions action : profile.getActions()) {
- action.after(this.getProfile(), delta, actual, result);
- }
- } catch (IgnoreProvisionException e) {
- throw e;
- } catch (PropagationException e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate {} {}", anyTO.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
-
- for (SyncActions action : profile.getActions()) {
- action.onError(this.getProfile(), delta, result, e);
- }
- } catch (Exception e) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not create {} {} ", anyTO.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
-
- for (SyncActions action : profile.getActions()) {
- action.onError(this.getProfile(), delta, result, e);
- }
- }
-
- audit(operation, resultStatus, null, output, delta);
- }
-
- protected List<ProvisioningReport> update(final SyncDelta delta, final List<Long> anys,
- final Provision provision) throws JobExecutionException {
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("SyncTask not configured for update");
- return Collections.<ProvisioningReport>emptyList();
- }
-
- LOG.debug("About to update {}", anys);
-
- List<ProvisioningReport> results = new ArrayList<>();
-
- SyncDelta workingDelta = delta;
- for (Long key : anys) {
- LOG.debug("About to update {}", key);
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.UPDATE);
- result.setAnyType(provision.getAnyType().getKey());
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setKey(key);
-
- AnyTO before = getAnyTO(key);
- if (before == null) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
- } else {
- result.setName(getName(before));
- }
-
- Result resultStatus;
- Object output;
- if (!profile.isDryRun()) {
- if (before == null) {
- resultStatus = Result.FAILURE;
- output = null;
- } else {
- try {
- AnyPatch anyPatch = connObjectUtils.getAnyPatch(
- before.getKey(),
- workingDelta.getObject(),
- before,
- profile.getTask(),
- provision,
- getAnyUtils());
-
- for (SyncActions action : profile.getActions()) {
- workingDelta = action.beforeUpdate(this.getProfile(), workingDelta, before, anyPatch);
- }
-
- AnyTO updated = doUpdate(before, anyPatch, workingDelta, result);
-
- for (SyncActions action : profile.getActions()) {
- action.after(this.getProfile(), workingDelta, updated, result);
- }
-
- output = updated;
- resultStatus = Result.SUCCESS;
- result.setName(getName(updated));
- LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
- } catch (IgnoreProvisionException e) {
- throw e;
- } catch (PropagationException e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate {} {}",
- provision.getAnyType().getKey(), workingDelta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
-
- for (SyncActions action : profile.getActions()) {
- action.onError(this.getProfile(), workingDelta, result, e);
- }
- } catch (Exception e) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not update {} {}",
- provision.getAnyType().getKey(), workingDelta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
-
- for (SyncActions action : profile.getActions()) {
- action.onError(this.getProfile(), workingDelta, result, e);
- }
- }
- }
- audit(MatchingRule.toEventName(MatchingRule.UPDATE), resultStatus, before, output, workingDelta);
- }
- results.add(result);
- }
- return results;
- }
-
- protected List<ProvisioningReport> deprovision(
- final SyncDelta delta,
- final List<Long> anys,
- final Provision provision,
- final boolean unlink)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("SyncTask not configured for update");
- return Collections.<ProvisioningReport>emptyList();
- }
-
- LOG.debug("About to update {}", anys);
-
- final List<ProvisioningReport> updResults = new ArrayList<>();
-
- for (Long key : anys) {
- LOG.debug("About to unassign resource {}", key);
-
- Object output;
- Result resultStatus;
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.DELETE);
- result.setAnyType(provision.getAnyType().getKey());
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setKey(key);
-
- AnyTO before = getAnyTO(key);
-
- if (before == null) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
- }
-
- if (!profile.isDryRun()) {
- if (before == null) {
- resultStatus = Result.FAILURE;
- output = null;
- } else {
- result.setName(getName(before));
-
- try {
- if (unlink) {
- for (SyncActions action : profile.getActions()) {
- action.beforeUnassign(this.getProfile(), delta, before);
- }
- } else {
- for (SyncActions action : profile.getActions()) {
- action.beforeDeprovision(this.getProfile(), delta, before);
- }
- }
-
- doDeprovision(provision.getAnyType().getKind(), key, unlink);
- output = getAnyTO(key);
-
- for (SyncActions action : profile.getActions()) {
- action.after(this.getProfile(), delta, AnyTO.class.cast(output), result);
- }
-
- resultStatus = Result.SUCCESS;
- LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
- } catch (IgnoreProvisionException e) {
- throw e;
- } catch (PropagationException e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate {} {}",
- provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
-
- for (SyncActions action : profile.getActions()) {
- action.onError(this.getProfile(), delta, result, e);
- }
- } catch (Exception e) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not update {} {}",
- provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
-
- for (SyncActions action : profile.getActions()) {
- action.onError(this.getProfile(), delta, result, e);
- }
- }
- }
- audit(unlink
- ? MatchingRule.toEventName(MatchingRule.UNASSIGN)
- : MatchingRule.toEventName(MatchingRule.DEPROVISION), resultStatus, before, output, delta);
- }
- updResults.add(result);
- }
-
- return updResults;
- }
-
- protected List<ProvisioningReport> link(
- final SyncDelta delta,
- final List<Long> anys,
- final Provision provision,
- final boolean unlink)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("SyncTask not configured for update");
- return Collections.<ProvisioningReport>emptyList();
- }
-
- LOG.debug("About to update {}", anys);
-
- final List<ProvisioningReport> updResults = new ArrayList<>();
-
- for (Long key : anys) {
- LOG.debug("About to unassign resource {}", key);
-
- Object output;
- Result resultStatus;
-
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.NONE);
- result.setAnyType(provision.getAnyType().getKey());
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- result.setKey(key);
-
- AnyTO before = getAnyTO(key);
-
- if (before == null) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
- }
-
- if (!profile.isDryRun()) {
- if (before == null) {
- resultStatus = Result.FAILURE;
- output = null;
- } else {
- result.setName(getName(before));
-
- try {
- if (unlink) {
- for (SyncActions action : profile.getActions()) {
- action.beforeUnlink(this.getProfile(), delta, before);
- }
- } else {
- for (SyncActions action : profile.getActions()) {
- action.beforeLink(this.getProfile(), delta, before);
- }
- }
-
- output = doLink(before, unlink);
-
- for (SyncActions action : profile.getActions()) {
- action.after(this.getProfile(), delta, AnyTO.class.cast(output), result);
- }
-
- resultStatus = Result.SUCCESS;
- LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
- } catch (IgnoreProvisionException e) {
- throw e;
- } catch (PropagationException e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate {} {}",
- provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
-
- for (SyncActions action : profile.getActions()) {
- action.onError(this.getProfile(), delta, result, e);
- }
- } catch (Exception e) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not update {} {}",
- provision.getAnyType().getKey(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
-
- for (SyncActions action : profile.getActions()) {
- action.onError(this.getProfile(), delta, result, e);
- }
- }
- }
- audit(unlink ? MatchingRule.toEventName(MatchingRule.UNLINK)
- : MatchingRule.toEventName(MatchingRule.LINK), resultStatus, before, output, delta);
- }
- updResults.add(result);
- }
-
- return updResults;
- }
-
- protected List<ProvisioningReport> delete(
- final SyncDelta delta,
- final List<Long> anys,
- final Provision provision)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformDelete()) {
- LOG.debug("SyncTask not configured for delete");
- return Collections.<ProvisioningReport>emptyList();
- }
-
- LOG.debug("About to delete {}", anys);
-
- List<ProvisioningReport> delResults = new ArrayList<>();
-
- SyncDelta workingDelta = delta;
- for (Long key : anys) {
- Object output;
- Result resultStatus = Result.FAILURE;
-
- ProvisioningReport result = new ProvisioningReport();
-
- try {
- AnyTO before = getAnyTO(key);
-
- result.setKey(key);
- result.setName(getName(before));
- result.setOperation(ResourceOperation.DELETE);
- result.setAnyType(provision.getAnyType().getKey());
- result.setStatus(ProvisioningReport.Status.SUCCESS);
-
- if (!profile.isDryRun()) {
- for (SyncActions action : profile.getActions()) {
- workingDelta = action.beforeDelete(this.getProfile(), workingDelta, before);
- }
-
- try {
- doDelete(provision.getAnyType().getKind(), key);
- output = null;
- resultStatus = Result.SUCCESS;
-
- for (SyncActions action : profile.getActions()) {
- action.after(this.getProfile(), workingDelta, before, result);
- }
- } catch (IgnoreProvisionException e) {
- throw e;
- } catch (Exception e) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), key, e);
- output = e;
-
- for (SyncActions action : profile.getActions()) {
- action.onError(this.getProfile(), workingDelta, result, e);
- }
- }
-
- audit(ResourceOperation.DELETE.name().toLowerCase(), resultStatus, before, output, workingDelta);
- }
-
- delResults.add(result);
- } catch (NotFoundException e) {
- LOG.error("Could not find {} {}", provision.getAnyType().getKey(), key, e);
- } catch (DelegatedAdministrationException e) {
- LOG.error("Not allowed to read {} {}", provision.getAnyType().getKey(), key, e);
- } catch (Exception e) {
- LOG.error("Could not delete {} {}", provision.getAnyType().getKey(), key, e);
- }
- }
-
- return delResults;
- }
-
- private List<ProvisioningReport> ignore(
- final SyncDelta delta,
- final Provision provision,
- final boolean matching)
- throws JobExecutionException {
-
- LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
-
- final List<ProvisioningReport> ignoreResults = new ArrayList<>();
- ProvisioningReport result = new ProvisioningReport();
-
- result.setKey(null);
- result.setName(delta.getObject().getUid().getUidValue());
- result.setOperation(ResourceOperation.NONE);
- result.setAnyType(provision.getAnyType().getKey());
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- ignoreResults.add(result);
-
- if (!profile.isDryRun()) {
- audit(matching
- ? MatchingRule.toEventName(MatchingRule.IGNORE)
- : UnmatchingRule.toEventName(UnmatchingRule.IGNORE), Result.SUCCESS, null, null, delta);
- }
-
- return ignoreResults;
- }
-
- /**
- * Look into SyncDelta and take necessary profile.getActions() (create / update / delete) on any object(s).
- *
- * @param delta returned by the underlying profile.getConnector()
- * @param provision provisioning info
- * @throws JobExecutionException in case of synchronization failure.
- */
- protected void doHandle(final SyncDelta delta, final Provision provision) throws JobExecutionException {
- AnyUtils anyUtils = getAnyUtils();
-
- LOG.debug("Process {} for {} as {}",
- delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
-
- String uid = delta.getPreviousUid() == null
- ? delta.getUid().getUidValue()
- : delta.getPreviousUid().getUidValue();
-
- try {
- List<Long> anyKeys = syncUtilities.findExisting(uid, delta.getObject(), provision, anyUtils);
- LOG.debug("Match(es) found for {} as {}: {}",
- delta.getUid().getUidValue(), delta.getObject().getObjectClass(), anyKeys);
-
- if (anyKeys.size() > 1) {
- switch (profile.getResAct()) {
- case IGNORE:
- throw new IllegalStateException("More than one match " + anyKeys);
-
- case FIRSTMATCH:
- anyKeys = anyKeys.subList(0, 1);
- break;
-
- case LASTMATCH:
- anyKeys = anyKeys.subList(anyKeys.size() - 1, anyKeys.size());
- break;
-
- default:
- // keep anyKeys unmodified
- }
- }
-
- if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
- if (anyKeys.isEmpty()) {
- switch (profile.getTask().getUnmatchingRule()) {
- case ASSIGN:
- profile.getResults().addAll(assign(delta, provision, anyUtils));
- break;
-
- case PROVISION:
- profile.getResults().addAll(provision(delta, provision, anyUtils));
- break;
-
- case IGNORE:
- profile.getResults().addAll(ignore(delta, provision, false));
- break;
-
- default:
- // do nothing
- }
- } else {
- // update VirAttrCache
- for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) {
- Attribute attr = delta.getObject().getAttributeByName(virSchema.getExtAttrName());
- for (Long anyKey : anyKeys) {
- if (attr == null) {
- virAttrCache.expire(
- provision.getAnyType().getKey(),
- anyKey,
- virSchema.getKey());
- } else {
- VirAttrCacheValue cacheValue = new VirAttrCacheValue();
- cacheValue.setValues(attr.getValue());
- virAttrCache.put(
- provision.getAnyType().getKey(),
- anyKey,
- virSchema.getKey(),
- cacheValue);
- }
- }
- }
-
- switch (profile.getTask().getMatchingRule()) {
- case UPDATE:
- profile.getResults().addAll(update(delta, anyKeys, provision));
- break;
-
- case DEPROVISION:
- profile.getResults().addAll(deprovision(delta, anyKeys, provision, false));
- break;
-
- case UNASSIGN:
- profile.getResults().addAll(deprovision(delta, anyKeys, provision, true));
- break;
-
- case LINK:
- profile.getResults().addAll(link(delta, anyKeys, provision, false));
- break;
-
- case UNLINK:
- profile.getResults().addAll(link(delta, anyKeys, provision, true));
- break;
-
- case IGNORE:
- profile.getResults().addAll(ignore(delta, provision, true));
- break;
-
- default:
- // do nothing
- }
- }
- } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
- if (anyKeys.isEmpty()) {
- LOG.debug("No match found for deletion");
- } else {
- profile.getResults().addAll(delete(delta, anyKeys, provision));
- }
- }
- } catch (IllegalStateException | IllegalArgumentException e) {
- LOG.warn(e.getMessage());
- }
- }
-
- private void audit(
- final String event,
- final Result result,
- final Object before,
- final Object output,
- final Object... input) {
-
- notificationManager.createTasks(AuditElements.EventCategoryType.SYNCHRONIZATION,
- getAnyUtils().getAnyTypeKind().name().toLowerCase(),
- profile.getTask().getResource().getKey(),
- event,
- result,
- before,
- output,
- input);
-
- auditManager.audit(AuditElements.EventCategoryType.SYNCHRONIZATION,
- getAnyUtils().getAnyTypeKind().name().toLowerCase(),
- profile.getTask().getResource().getKey(),
- event,
- result,
- before,
- output,
- input);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
deleted file mode 100644
index 4e6f2eb..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractSyncopeResultHandler.java
+++ /dev/null
@@ -1,155 +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.core.provisioning.java.sync;
-
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
-import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
-import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
-import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.SyncopeResultHandler;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
-import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
-import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningActions;
-import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
-import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
-import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A extends ProvisioningActions>
- implements SyncopeResultHandler<T, A> {
-
- protected static final Logger LOG = LoggerFactory.getLogger(SyncopeResultHandler.class);
-
- @Autowired
- protected AnyObjectDAO anyObjectDAO;
-
- @Autowired
- protected UserDAO userDAO;
-
- @Autowired
- protected GroupDAO groupDAO;
-
- /**
- * ConnectorObject utils.
- */
- @Autowired
- protected ConnObjectUtils connObjectUtils;
-
- /**
- * Notification Manager.
- */
- @Autowired
- protected NotificationManager notificationManager;
-
- /**
- * Audit Manager.
- */
- @Autowired
- protected AuditManager auditManager;
-
- /**
- * Propagation manager.
- */
- @Autowired
- protected PropagationManager propagationManager;
-
- /**
- * Task executor.
- */
- @Autowired
- protected PropagationTaskExecutor taskExecutor;
-
- protected AnyObjectWorkflowAdapter awfAdapter;
-
- /**
- * User workflow adapter.
- */
- @Autowired
- protected UserWorkflowAdapter uwfAdapter;
-
- /**
- * Group workflow adapter.
- */
- @Autowired
- protected GroupWorkflowAdapter gwfAdapter;
-
- @Autowired
- protected AnyObjectDataBinder anyObjectDataBinder;
-
- @Autowired
- protected UserDataBinder userDataBinder;
-
- @Autowired
- protected GroupDataBinder groupDataBinder;
-
- @Autowired
- protected AnyObjectProvisioningManager anyObjectProvisioningManager;
-
- @Autowired
- protected UserProvisioningManager userProvisioningManager;
-
- @Autowired
- protected GroupProvisioningManager groupProvisioningManager;
-
- @Autowired
- protected AnyUtilsFactory anyUtilsFactory;
-
- /**
- * Sync profile.
- */
- protected ProvisioningProfile<T, A> profile;
-
- protected abstract AnyUtils getAnyUtils();
-
- protected abstract AnyTO getAnyTO(long key);
-
- protected abstract Any<?> getAny(long key);
-
- protected abstract AnyPatch newPatch(final long key);
-
- protected abstract WorkflowResult<Long> update(AnyPatch patch);
-
- @Override
- public void setProfile(final ProvisioningProfile<T, A> profile) {
- this.profile = profile;
- }
-
- @Override
- public ProvisioningProfile<T, A> getProfile() {
- return profile;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java
deleted file mode 100644
index f9546cc..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectPushResultHandlerImpl.java
+++ /dev/null
@@ -1,70 +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.core.provisioning.java.sync;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.patch.AnyObjectPatch;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.sync.AnyObjectPushResultHandler;
-
-public class AnyObjectPushResultHandlerImpl extends AbstractPushResultHandler implements AnyObjectPushResultHandler {
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
- }
-
- @Override
- protected String getName(final Any<?> any) {
- return StringUtils.EMPTY;
- }
-
- @Override
- protected Any<?> getAny(final long key) {
- try {
- return anyObjectDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving anyObject {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final long key) {
- return anyObjectDataBinder.getAnyObjectTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final long key) {
- AnyObjectPatch patch = new AnyObjectPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<Long> update(final AnyPatch patch) {
- return awfAdapter.update((AnyObjectPatch) patch);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java
deleted file mode 100644
index d194a25..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AnyObjectSyncResultHandlerImpl.java
+++ /dev/null
@@ -1,112 +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.core.provisioning.java.sync;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.patch.AnyObjectPatch;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.sync.AnyObjectSyncResultHandler;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-
-public class AnyObjectSyncResultHandlerImpl extends AbstractSyncResultHandler implements AnyObjectSyncResultHandler {
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT);
- }
-
- @Override
- protected String getName(final AnyTO anyTO) {
- return StringUtils.EMPTY;
- }
-
- @Override
- protected ProvisioningManager<?, ?> getProvisioningManager() {
- return anyObjectProvisioningManager;
- }
-
- @Override
- protected Any<?> getAny(final long key) {
- try {
- return anyObjectDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving anyObject {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final long key) {
- return anyObjectDataBinder.getAnyObjectTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final long key) {
- AnyObjectPatch patch = new AnyObjectPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<Long> update(final AnyPatch patch) {
- return awfAdapter.update((AnyObjectPatch) patch);
- }
-
- @Override
- protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningReport result) {
- AnyObjectTO anyObjectTO = AnyObjectTO.class.cast(anyTO);
-
- Map.Entry<Long, List<PropagationStatus>> created = anyObjectProvisioningManager.create(
- anyObjectTO, Collections.singleton(profile.getTask().getResource().getKey()), true);
-
- result.setKey(created.getKey());
- result.setName(getName(anyTO));
-
- return getAnyTO(created.getKey());
- }
-
- @Override
- protected AnyTO doUpdate(
- final AnyTO before,
- final AnyPatch anyPatch,
- final SyncDelta delta,
- final ProvisioningReport result) {
-
- AnyObjectPatch anyObjectPatch = AnyObjectPatch.class.cast(anyPatch);
-
- Map.Entry<Long, List<PropagationStatus>> updated =
- anyObjectProvisioningManager.update(anyObjectPatch, true);
-
- AnyObjectTO after = anyObjectDataBinder.getAnyObjectTO(updated.getKey());
- result.setName(getName(after));
- return after;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
deleted file mode 100644
index 6e8af59..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DBPasswordSyncActions.java
+++ /dev/null
@@ -1,142 +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.core.provisioning.java.sync;
-
-import org.apache.commons.collections4.IterableUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-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.user.User;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * A SyncActions implementation which allows the ability to import passwords from a Database
- * backend, where the passwords are hashed according to the password cipher algorithm property
- * of the (DB) Connector and HEX-encoded.
- */
-public class DBPasswordSyncActions extends DefaultSyncActions {
-
- private static final Logger LOG = LoggerFactory.getLogger(DBPasswordSyncActions.class);
-
- private static final String CLEARTEXT = "CLEARTEXT";
-
- @Autowired
- private UserDAO userDAO;
-
- private String encodedPassword;
-
- private CipherAlgorithm cipher;
-
- @Transactional(readOnly = true)
- @Override
- public <A extends AnyTO> SyncDelta beforeProvision(
- final ProvisioningProfile<?, ?> profile,
- final SyncDelta delta,
- final A any) throws JobExecutionException {
-
- if (any instanceof UserTO) {
- String password = ((UserTO) any).getPassword();
- parseEncodedPassword(password, profile.getConnector());
- }
-
- return delta;
- }
-
- @Transactional(readOnly = true)
- @Override
- public <A extends AnyTO, M extends AnyPatch> SyncDelta beforeUpdate(
- final ProvisioningProfile<?, ?> profile,
- final SyncDelta delta,
- final A any,
- final M anyPatch) throws JobExecutionException {
-
- if (anyPatch instanceof UserPatch) {
- PasswordPatch modPassword = ((UserPatch) anyPatch).getPassword();
- parseEncodedPassword(modPassword == null ? null : modPassword.getValue(), profile.getConnector());
- }
-
- return delta;
- }
-
- private void parseEncodedPassword(final String password, final Connector connector) {
- if (password != null) {
- ConnInstance connInstance = connector.getConnInstance();
-
- String cipherAlgorithm = getCipherAlgorithm(connInstance);
- if (!CLEARTEXT.equals(cipherAlgorithm)) {
- try {
- encodedPassword = password;
- cipher = CipherAlgorithm.valueOf(cipherAlgorithm);
- } catch (IllegalArgumentException e) {
- LOG.error("Cipher algorithm not allowed: {}", cipherAlgorithm, e);
- encodedPassword = null;
- }
- }
- }
- }
-
- private String getCipherAlgorithm(final ConnInstance connInstance) {
- ConnConfProperty cipherAlgorithm =
- IterableUtils.find(connInstance.getConf(), new Predicate<ConnConfProperty>() {
-
- @Override
- public boolean evaluate(final ConnConfProperty property) {
- return "cipherAlgorithm".equals(property.getSchema().getName())
- && property.getValues() != null && !property.getValues().isEmpty();
- }
- });
-
- return cipherAlgorithm == null
- ? CLEARTEXT
- : (String) cipherAlgorithm.getValues().get(0);
- }
-
- @Transactional(readOnly = true)
- @Override
- public <A extends AnyTO> void after(
- final ProvisioningProfile<?, ?> profile,
- final SyncDelta delta,
- final A any,
- final ProvisioningReport result) throws JobExecutionException {
-
- if (any instanceof UserTO && encodedPassword != null && cipher != null) {
- User syncopeUser = userDAO.find(any.getKey());
- if (syncopeUser != null) {
- syncopeUser.setEncodedPassword(encodedPassword.toUpperCase(), cipher);
- }
- encodedPassword = null;
- cipher = null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.java
deleted file mode 100644
index a005493..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultPushActions.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.core.provisioning.java.sync;
-
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.quartz.JobExecutionException;
-
-/**
- * Default (empty) implementation of PushActions.
- */
-public abstract class DefaultPushActions implements PushActions {
-
- @Override
- public void beforeAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException {
- }
-
- @Override
- public <A extends Any<?>> A beforeAssign(final ProvisioningProfile<?, ?> profile, final A any)
- throws JobExecutionException {
-
- return any;
- }
-
- @Override
- public <A extends Any<?>> A beforeProvision(final ProvisioningProfile<?, ?> profile, final A any)
- throws JobExecutionException {
-
- return any;
- }
-
- @Override
- public <A extends Any<?>> A beforeLink(final ProvisioningProfile<?, ?> profile, final A any)
- throws JobExecutionException {
-
- return any;
- }
-
- @Override
- public <A extends Any<?>> A beforeUnassign(final ProvisioningProfile<?, ?> profile, final A any)
- throws JobExecutionException {
-
- return any;
- }
-
- @Override
- public <A extends Any<?>> A beforeDeprovision(final ProvisioningProfile<?, ?> profile, final A any)
- throws JobExecutionException {
-
- return any;
- }
-
- @Override
- public <A extends Any<?>> A beforeUnlink(final ProvisioningProfile<?, ?> profile, final A any)
- throws JobExecutionException {
-
- return any;
- }
-
- @Override
- public <A extends Any<?>> void onError(
- final ProvisioningProfile<?, ?> profile, final A any, final ProvisioningReport result,
- final Exception error) throws JobExecutionException {
-
- // do nothing
- }
-
- @Override
- public <A extends Any<?>> void after(
- final ProvisioningProfile<?, ?> profile, final A any, final ProvisioningReport result)
- throws JobExecutionException {
-
- // do nothing
- }
-
- @Override
- public void afterAll(final ProvisioningProfile<?, ?> profile)
- throws JobExecutionException {
-
- // do nothing
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultReconciliationFilterBuilder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultReconciliationFilterBuilder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultReconciliationFilterBuilder.java
deleted file mode 100644
index 2c75928..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultReconciliationFilterBuilder.java
+++ /dev/null
@@ -1,38 +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.core.provisioning.java.sync;
-
-import static org.identityconnectors.framework.impl.api.local.operations.FilteredResultsHandler.PassThroughFilter;
-
-import org.identityconnectors.framework.common.objects.filter.Filter;
-import org.apache.syncope.core.provisioning.api.sync.ReconciliationFilterBuilder;
-
-/**
- * Default (pass-through) implementation of {@link ReconciliationFilterBuilder}.
- */
-public abstract class DefaultReconciliationFilterBuilder implements ReconciliationFilterBuilder {
-
- private static final PassThroughFilter PASS_THROUGH = new PassThroughFilter();
-
- @Override
- public Filter build() {
- return PASS_THROUGH;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
deleted file mode 100644
index 9045e2a..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/DefaultSyncActions.java
+++ /dev/null
@@ -1,121 +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.core.provisioning.java.sync;
-
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.quartz.JobExecutionException;
-
-/**
- * Default (empty) implementation of {@link SyncActions}.
- */
-public abstract class DefaultSyncActions implements SyncActions {
-
- @Override
- public void beforeAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException {
- }
-
- @Override
- public <A extends AnyTO, P extends AnyPatch> SyncDelta beforeUpdate(
- final ProvisioningProfile<?, ?> profile,
- final SyncDelta delta,
- final A any,
- final P anyMod) throws JobExecutionException {
-
- return delta;
- }
-
- @Override
- public <A extends AnyTO> SyncDelta beforeDelete(
- final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
- throws JobExecutionException {
-
- return delta;
- }
-
- @Override
- public <A extends AnyTO> SyncDelta beforeAssign(
- final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
- throws JobExecutionException {
-
- return delta;
- }
-
- @Override
- public <A extends AnyTO> SyncDelta beforeProvision(
- final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
- throws JobExecutionException {
-
- return delta;
- }
-
- @Override
- public <A extends AnyTO> SyncDelta beforeLink(
- final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
- throws JobExecutionException {
-
- return delta;
- }
-
- @Override
- public <A extends AnyTO> SyncDelta beforeUnassign(
- final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
- throws JobExecutionException {
-
- return delta;
- }
-
- @Override
- public <A extends AnyTO> SyncDelta beforeDeprovision(
- final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
- throws JobExecutionException {
-
- return delta;
- }
-
- @Override
- public <A extends AnyTO> SyncDelta beforeUnlink(
- final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any)
- throws JobExecutionException {
-
- return delta;
- }
-
- @Override
- public void onError(
- final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final ProvisioningReport result,
- final Exception error) throws JobExecutionException {
- }
-
- @Override
- public <A extends AnyTO> void after(
- final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any,
- final ProvisioningReport result)
- throws JobExecutionException {
- }
-
- @Override
- public void afterAll(final ProvisioningProfile<?, ?> profile)
- throws JobExecutionException {
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
deleted file mode 100644
index 571fc47..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupPushResultHandlerImpl.java
+++ /dev/null
@@ -1,70 +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.core.provisioning.java.sync;
-
-import org.apache.syncope.common.lib.patch.GroupPatch;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.sync.GroupPushResultHandler;
-
-public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implements GroupPushResultHandler {
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
- }
-
- @Override
- protected String getName(final Any<?> any) {
- return Group.class.cast(any).getName();
- }
-
- @Override
- protected Any<?> getAny(final long key) {
- try {
- return groupDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving group {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final long key) {
- return groupDataBinder.getGroupTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final long key) {
- GroupPatch patch = new GroupPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<Long> update(final AnyPatch patch) {
- return gwfAdapter.update((GroupPatch) patch);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
deleted file mode 100644
index c3c63fb..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
+++ /dev/null
@@ -1,138 +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.core.provisioning.java.sync;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.AttrPatch;
-import org.apache.syncope.common.lib.patch.GroupPatch;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.provisioning.api.ProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.sync.GroupSyncResultHandler;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-
-public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implements GroupSyncResultHandler {
-
- protected final Map<Long, String> groupOwnerMap = new HashMap<>();
-
- @Override
- public Map<Long, String> getGroupOwnerMap() {
- return this.groupOwnerMap;
- }
-
- @Override
- protected AnyUtils getAnyUtils() {
- return anyUtilsFactory.getInstance(AnyTypeKind.GROUP);
- }
-
- @Override
- protected String getName(final AnyTO anyTO) {
- return GroupTO.class.cast(anyTO).getName();
- }
-
- @Override
- protected ProvisioningManager<?, ?> getProvisioningManager() {
- return groupProvisioningManager;
- }
-
- @Override
- protected Any<?> getAny(final long key) {
- try {
- return groupDAO.authFind(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving group {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AnyTO getAnyTO(final long key) {
- return groupDataBinder.getGroupTO(key);
- }
-
- @Override
- protected AnyPatch newPatch(final long key) {
- GroupPatch patch = new GroupPatch();
- patch.setKey(key);
- return patch;
- }
-
- @Override
- protected WorkflowResult<Long> update(final AnyPatch patch) {
- return gwfAdapter.update((GroupPatch) patch);
- }
-
- @Override
- protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningReport result) {
- GroupTO groupTO = GroupTO.class.cast(anyTO);
-
- Map.Entry<Long, List<PropagationStatus>> created = groupProvisioningManager.create(
- groupTO,
- groupOwnerMap,
- Collections.singleton(profile.getTask().getResource().getKey()),
- true);
-
- result.setKey(created.getKey());
- result.setName(getName(anyTO));
-
- return getAnyTO(created.getKey());
- }
-
- @Override
- protected AnyTO doUpdate(
- final AnyTO before,
- final AnyPatch anyPatch,
- final SyncDelta delta,
- final ProvisioningReport result) {
-
- GroupPatch groupPatch = GroupPatch.class.cast(anyPatch);
-
- Map.Entry<Long, List<PropagationStatus>> updated = groupProvisioningManager.update(groupPatch, true);
-
- String groupOwner = null;
- for (AttrPatch attrPatch : groupPatch.getPlainAttrs()) {
- if (attrPatch.getOperation() == PatchOperation.ADD_REPLACE && attrPatch.getAttrTO() != null
- && attrPatch.getAttrTO().getSchema().isEmpty() && !attrPatch.getAttrTO().getValues().isEmpty()) {
-
- groupOwner = attrPatch.getAttrTO().getValues().get(0);
- }
- }
- if (groupOwner != null) {
- groupOwnerMap.put(updated.getKey(), groupOwner);
- }
-
- GroupTO after = groupDataBinder.getGroupTO(updated.getKey());
-
- result.setName(getName(after));
-
- return after;
- }
-
-}