You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/08/13 17:17:59 UTC
[17/26] syncope git commit: [SYNCOPE-652] Still several things to
refine, but it starts taking shape
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java
index 793411d..6de5ffb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportDAO.java
@@ -32,12 +32,13 @@ import org.springframework.transaction.annotation.Transactional;
@Repository
public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO {
- @Override
@Transactional(readOnly = true)
+ @Override
public Report find(final Long key) {
- return entityManager.find(JPAReport.class, key);
+ return entityManager().find(JPAReport.class, key);
}
+ @Transactional(readOnly = true)
@Override
public List<Report> findAll() {
return findAll(-1, -1, Collections.<OrderByClause>emptyList());
@@ -45,7 +46,7 @@ public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO
@Override
public List<Report> findAll(final int page, final int itemsPerPage, final List<OrderByClause> orderByClauses) {
- final TypedQuery<Report> query = entityManager.createQuery(
+ final TypedQuery<Report> query = entityManager().createQuery(
"SELECT e FROM " + JPAReport.class.getSimpleName() + " e "
+ toOrderByStatement(Report.class, "e", orderByClauses), Report.class);
@@ -62,14 +63,14 @@ public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO
@Override
public int count() {
- Query countQuery = entityManager.createNativeQuery("SELECT COUNT(id) FROM " + JPAReport.TABLE);
+ Query countQuery = entityManager().createNativeQuery("SELECT COUNT(id) FROM " + JPAReport.TABLE);
return ((Number) countQuery.getSingleResult()).intValue();
}
@Override
@Transactional(rollbackFor = Throwable.class)
public Report save(final Report report) {
- return entityManager.merge(report);
+ return entityManager().merge(report);
}
@Override
@@ -84,6 +85,6 @@ public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO
@Override
public void delete(final Report report) {
- entityManager.remove(report);
+ entityManager().remove(report);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
index 95f57df..cf9e781 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
@@ -32,11 +32,11 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
@Override
public ReportExec find(final Long key) {
- return entityManager.find(JPAReportExec.class, key);
+ return entityManager().find(JPAReportExec.class, key);
}
private ReportExec findLatest(final Report report, final String field) {
- TypedQuery<ReportExec> query = entityManager.createQuery(
+ TypedQuery<ReportExec> query = entityManager().createQuery(
"SELECT e FROM " + JPAReportExec.class.getSimpleName() + " e "
+ "WHERE e.report=:report ORDER BY e." + field + " DESC", ReportExec.class);
query.setParameter("report", report);
@@ -60,7 +60,7 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
@Override
public List<ReportExec> findAll() {
- TypedQuery<ReportExec> query = entityManager.createQuery(
+ TypedQuery<ReportExec> query = entityManager().createQuery(
"SELECT e FROM " + JPAReportExec.class.getSimpleName() + " e", ReportExec.class);
return query.getResultList();
}
@@ -75,7 +75,7 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
@Override
@Transactional(rollbackFor = Throwable.class)
public ReportExec save(final ReportExec execution) {
- return entityManager.merge(execution);
+ return entityManager().merge(execution);
}
@Override
@@ -94,6 +94,6 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements R
execution.getReport().removeExec(execution);
}
- entityManager.remove(execution);
+ entityManager().remove(execution);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/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 5f600b6..6fb5ec3 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
@@ -43,12 +43,12 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
@Override
public Role find(final Long key) {
- return entityManager.find(JPARole.class, key);
+ return entityManager().find(JPARole.class, key);
}
@Override
public Role find(final String name) {
- TypedQuery<Role> query = entityManager.createQuery(
+ TypedQuery<Role> query = entityManager().createQuery(
"SELECT e FROM " + JPARole.class.getSimpleName() + " e WHERE e.name=:name", Role.class);
query.setParameter("name", name);
@@ -64,7 +64,7 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
@Override
public List<Role> findByRealm(final Realm realm) {
- TypedQuery<Role> query = entityManager.createQuery(
+ TypedQuery<Role> query = entityManager().createQuery(
"SELECT e FROM " + JPARole.class.getSimpleName() + " e WHERE :realm MEMBER OF e.realms", Role.class);
query.setParameter("realm", realm);
return query.getResultList();
@@ -72,7 +72,7 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
@Override
public List<Role> findAll() {
- TypedQuery<Role> query = entityManager.createQuery(
+ TypedQuery<Role> query = entityManager().createQuery(
"SELECT e FROM " + JPARole.class.getSimpleName() + " e ", Role.class);
return query.getResultList();
}
@@ -90,12 +90,12 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO {
}
}
- return entityManager.merge(role);
+ return entityManager().merge(role);
}
@Override
public void delete(final Role role) {
- entityManager.remove(role);
+ entityManager().remove(role);
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java
index 5c242d6..7028080 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASecurityQuestionDAO.java
@@ -36,19 +36,19 @@ public class JPASecurityQuestionDAO extends AbstractDAO<SecurityQuestion, Long>
@Override
public SecurityQuestion find(final Long key) {
- return entityManager.find(JPASecurityQuestion.class, key);
+ return entityManager().find(JPASecurityQuestion.class, key);
}
@Override
public List<SecurityQuestion> findAll() {
- final TypedQuery<SecurityQuestion> query = entityManager.createQuery(
+ final TypedQuery<SecurityQuestion> query = entityManager().createQuery(
"SELECT e FROM " + JPASecurityQuestion.class.getSimpleName() + " e ", SecurityQuestion.class);
return query.getResultList();
}
@Override
public SecurityQuestion save(final SecurityQuestion securityQuestion) {
- return entityManager.merge(securityQuestion);
+ return entityManager().merge(securityQuestion);
}
@Override
@@ -64,7 +64,7 @@ public class JPASecurityQuestionDAO extends AbstractDAO<SecurityQuestion, Long>
userDAO.save(user);
}
- entityManager.remove(securityQuestion);
+ entityManager().remove(securityQuestion);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
index ff93071..a70f65e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java
@@ -75,7 +75,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
@SuppressWarnings("unchecked")
@Override
public <T extends Task> T find(final Long key) {
- return (T) entityManager.find(JPATask.class, key);
+ return (T) entityManager().find(JPATask.class, key);
}
private <T extends Task> StringBuilder buildfindAllQuery(final TaskType type) {
@@ -96,7 +96,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
}
queryString.append("ORDER BY e.id DESC");
- Query query = entityManager.createQuery(queryString.toString());
+ Query query = entityManager().createQuery(queryString.toString());
query.setParameter("type", type);
return query.getResultList();
}
@@ -106,13 +106,14 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
public <T extends Task> List<T> findAll(final ExternalResource resource, final TaskType type) {
StringBuilder queryString = buildfindAllQuery(type).append("AND e.resource=:resource ORDER BY e.id DESC");
- final Query query = entityManager.createQuery(queryString.toString());
+ final Query query = entityManager().createQuery(queryString.toString());
query.setParameter("type", type);
query.setParameter("resource", resource);
return query.getResultList();
}
+ @Transactional(readOnly = true)
@Override
public <T extends Task> List<T> findAll(final TaskType type) {
return findAll(-1, -1, Collections.<OrderByClause>emptyList(), type);
@@ -128,7 +129,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
? "ORDER BY e.id DESC"
: toOrderByStatement(getEntityReference(type), "e", orderByClauses));
- Query query = entityManager.createQuery(queryString.toString());
+ Query query = entityManager().createQuery(queryString.toString());
query.setParameter("type", type);
query.setFirstResult(itemsPerPage * (page <= 0
@@ -144,7 +145,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
@Override
public int count(final TaskType type) {
- Query countQuery = entityManager.createNativeQuery("SELECT COUNT(id) FROM Task WHERE TYPE=?1");
+ Query countQuery = entityManager().createNativeQuery("SELECT COUNT(id) FROM Task WHERE TYPE=?1");
countQuery.setParameter(1, type.name());
return ((Number) countQuery.getSingleResult()).intValue();
}
@@ -152,7 +153,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
@Transactional(rollbackFor = { Throwable.class })
@Override
public <T extends Task> T save(final T task) {
- return entityManager.merge(task);
+ return entityManager().merge(task);
}
@Override
@@ -167,7 +168,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
@Override
public void delete(final Task task) {
- entityManager.remove(task);
+ entityManager().remove(task);
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
index 5d840da..38155ff 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskExecDAO.java
@@ -38,11 +38,11 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec, Long> implements TaskE
@Override
public TaskExec find(final Long key) {
- return entityManager.find(JPATaskExec.class, key);
+ return entityManager().find(JPATaskExec.class, key);
}
private <T extends Task> TaskExec findLatest(final T task, final String field) {
- TypedQuery<TaskExec> query = entityManager.createQuery(
+ TypedQuery<TaskExec> query = entityManager().createQuery(
"SELECT e FROM " + JPATaskExec.class.getSimpleName() + " e "
+ "WHERE e.task=:task "
+ "ORDER BY e." + field + " DESC", TaskExec.class);
@@ -71,13 +71,13 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec, Long> implements TaskE
append(" e WHERE e.task IN (").append("SELECT t FROM ").
append(taskDAO.getEntityReference(type).getSimpleName()).append(" t)");
- TypedQuery<TaskExec> query = entityManager.createQuery(queryString.toString(), TaskExec.class);
+ TypedQuery<TaskExec> query = entityManager().createQuery(queryString.toString(), TaskExec.class);
return query.getResultList();
}
@Override
public TaskExec save(final TaskExec execution) {
- return entityManager.merge(execution);
+ return entityManager().merge(execution);
}
/**
@@ -111,6 +111,6 @@ public class JPATaskExecDAO extends AbstractDAO<TaskExec, Long> implements TaskE
execution.getTask().removeExec(execution);
}
- entityManager.remove(execution);
+ entityManager().remove(execution);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/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 3b413c0..50564f2 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
@@ -29,8 +29,17 @@ import javax.persistence.TypedQuery;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
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.types.AccountPolicySpec;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.PasswordPolicySpec;
+import org.apache.syncope.core.misc.policy.AccountPolicyEnforcer;
+import org.apache.syncope.core.misc.policy.AccountPolicyException;
+import org.apache.syncope.core.misc.policy.PasswordPolicyEnforcer;
+import org.apache.syncope.core.misc.policy.PolicyEvaluator;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
@@ -40,14 +49,21 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
import org.apache.syncope.core.misc.security.AuthContextUtils;
import org.apache.syncope.core.misc.security.UnauthorizedException;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.core.persistence.api.entity.Policy;
+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.group.Group;
import org.apache.syncope.core.persistence.api.entity.user.UMembership;
import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
import org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
+import org.apache.syncope.core.provisioning.api.UserSuspender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
@@ -57,14 +73,32 @@ import org.springframework.transaction.annotation.Transactional;
public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
@Autowired
+ private RealmDAO realmDAO;
+
+ @Autowired
private GroupDAO groupDAO;
@Autowired
private RoleDAO roleDAO;
+ @Resource(name = "adminUser")
+ private String adminUser;
+
@Resource(name = "anonymousUser")
private String anonymousUser;
+ @Autowired
+ private PolicyEvaluator evaluator;
+
+ @Autowired
+ private PasswordPolicyEnforcer ppEnforcer;
+
+ @Autowired
+ private AccountPolicyEnforcer apEnforcer;
+
+ @Autowired(required = false)
+ private UserSuspender suspender;
+
@Override
protected AnyUtils init() {
return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.USER);
@@ -110,7 +144,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
@Override
public User find(final String username) {
- TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
+ TypedQuery<User> query = entityManager().createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
+ " e WHERE e.username = :username", User.class);
query.setParameter("username", username);
@@ -126,7 +160,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
@Override
public User findByToken(final String token) {
- TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
+ TypedQuery<User> query = entityManager().createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
+ " e WHERE e.token LIKE :token", User.class);
query.setParameter("token", token);
@@ -142,16 +176,151 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
@Override
public List<User> findBySecurityQuestion(final SecurityQuestion securityQuestion) {
- TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
+ TypedQuery<User> query = entityManager().createQuery("SELECT e FROM " + JPAUser.class.getSimpleName()
+ " e WHERE e.securityQuestion = :securityQuestion", User.class);
query.setParameter("securityQuestion", securityQuestion);
return query.getResultList();
}
+ private List<PasswordPolicy> getPasswordPolicies(final User user) {
+ List<PasswordPolicy> policies = new ArrayList<>();
+
+ PasswordPolicy policy;
+
+ // add resource policies
+ for (ExternalResource resource : findAllResources(user)) {
+ policy = resource.getPasswordPolicy();
+ if (policy != null) {
+ policies.add(policy);
+ }
+ }
+
+ // add realm policies
+ for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
+ policy = realm.getPasswordPolicy();
+ if (policy != null) {
+ policies.add(policy);
+ }
+ }
+
+ return policies;
+ }
+
+ private List<AccountPolicy> getAccountPolicies(final User user) {
+ List<AccountPolicy> policies = new ArrayList<>();
+
+ AccountPolicy policy;
+
+ // add resource policies
+ for (ExternalResource resource : findAllResources(user)) {
+ policy = resource.getAccountPolicy();
+ if (policy != null) {
+ policies.add(policy);
+ }
+ }
+
+ // add realm policies
+ for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
+ policy = realm.getAccountPolicy();
+ if (policy != null) {
+ policies.add(policy);
+ }
+ }
+
+ return policies;
+ }
+
+ private Pair<Boolean, Boolean> enforcePolicies(final User user) {
+ // ------------------------------
+ // Verify password policies
+ // ------------------------------
+ LOG.debug("Password Policy enforcement");
+
+ try {
+ int maxPPSpecHistory = 0;
+ for (Policy policy : getPasswordPolicies(user)) {
+ // evaluate policy
+ PasswordPolicySpec ppSpec = evaluator.evaluate(policy, user);
+ // enforce policy
+ ppEnforcer.enforce(ppSpec, policy.getType(), user);
+
+ if (ppSpec.getHistoryLength() > maxPPSpecHistory) {
+ maxPPSpecHistory = ppSpec.getHistoryLength();
+ }
+ }
+
+ // update user's password history with encrypted password
+ if (maxPPSpecHistory > 0 && user.getPassword() != null) {
+ user.getPasswordHistory().add(user.getPassword());
+ }
+ // keep only the last maxPPSpecHistory items in user's password history
+ if (maxPPSpecHistory < user.getPasswordHistory().size()) {
+ for (int i = 0; i < user.getPasswordHistory().size() - maxPPSpecHistory; i++) {
+ user.getPasswordHistory().remove(i);
+ }
+ }
+ } catch (Exception e) {
+ LOG.error("Invalid password for {}", user, e);
+ throw new InvalidEntityException(User.class, EntityViolationType.InvalidPassword, e.getMessage());
+ } finally {
+ // password has been validated, let's remove its clear version
+ user.removeClearPassword();
+ }
+
+ // ------------------------------
+ // Verify account policies
+ // ------------------------------
+ LOG.debug("Account Policy enforcement");
+
+ boolean suspend = false;
+ boolean propagateSuspension = false;
+ try {
+ if (adminUser.equals(user.getUsername()) || anonymousUser.equals(user.getUsername())) {
+ throw new AccountPolicyException("Not allowed: " + user.getUsername());
+ }
+
+ // invalid username
+ for (Policy policy : getAccountPolicies(user)) {
+ // evaluate policy
+ AccountPolicySpec apSpec = evaluator.evaluate(policy, user);
+
+ // enforce policy
+ suspend |= apEnforcer.enforce(apSpec, policy.getType(), user);
+ propagateSuspension |= apSpec.isPropagateSuspension();
+ }
+ } catch (Exception e) {
+ LOG.error("Invalid username for {}", user, e);
+ throw new InvalidEntityException(User.class, EntityViolationType.InvalidUsername, e.getMessage());
+ }
+
+ return ImmutablePair.of(suspend, propagateSuspension);
+ }
+
@Override
public User save(final User user) {
+ // 1. save clear password value before save
+ String clearPwd = user.getClearPassword();
+
+ // 2. save and flush to trigger entity validation
User merged = super.save(user);
+ entityManager().flush();
+
+ // 3. set back the sole clear password value
+ JPAUser.class.cast(merged).setClearPassword(clearPwd);
+
+ // 4. enforce password and account policies
+ Pair<Boolean, Boolean> enforceSuspend = null;
+ try {
+ enforceSuspend = enforcePolicies(merged);
+ } catch (InvalidEntityException e) {
+ entityManager().remove(merged);
+ throw e;
+ }
+
+ if (suspender != null && enforceSuspend.getKey()) {
+ suspender.suspend(user, enforceSuspend.getValue());
+ }
roleDAO.refreshDynMemberships(merged);
groupDAO.refreshDynMemberships(merged);
@@ -168,13 +337,13 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
group.getUDynMembership().remove(user);
}
- entityManager.remove(user);
+ entityManager().remove(user);
}
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
@Override
public List<Role> findDynRoleMemberships(final User user) {
- TypedQuery<Role> query = entityManager.createQuery(
+ TypedQuery<Role> query = entityManager().createQuery(
"SELECT e.role FROM " + JPADynRoleMembership.class.getSimpleName()
+ " e WHERE :user MEMBER OF e.users", Role.class);
query.setParameter("user", user);
@@ -185,7 +354,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
@Override
public List<Group> findDynGroupMemberships(final User user) {
- TypedQuery<Group> query = entityManager.createQuery(
+ TypedQuery<Group> query = entityManager().createQuery(
"SELECT e.group FROM " + JPAUDynGroupMembership.class.getSimpleName()
+ " e WHERE :user MEMBER OF e.users", Group.class);
query.setParameter("user", user);
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
index 3ef6791..2c8b99f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
@@ -49,19 +49,19 @@ public class JPAVirAttrDAO extends AbstractDAO<VirAttr<?>, Long> implements VirA
@Override
public <T extends VirAttr<?>> T find(final Long key, final Class<T> reference) {
- return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+ return reference.cast(entityManager().find(getJPAEntityReference(reference), key));
}
@Override
public <T extends VirAttr<?>> List<T> findAll(final Class<T> reference) {
- TypedQuery<T> query = entityManager.createQuery(
+ TypedQuery<T> query = entityManager().createQuery(
"SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
return query.getResultList();
}
@Override
public <T extends VirAttr<?>> T save(final T virAttr) {
- return entityManager.merge(virAttr);
+ return entityManager().merge(virAttr);
}
@Override
@@ -81,6 +81,6 @@ public class JPAVirAttrDAO extends AbstractDAO<VirAttr<?>, Long> implements VirA
((Any<?, ?, T>) virAttr.getOwner()).remove(virAttr);
}
- entityManager.remove(virAttr);
+ entityManager().remove(virAttr);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
index dae6afc..46a06f6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
@@ -45,7 +45,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
@Override
public VirSchema find(final String key) {
- return entityManager.find(JPAVirSchema.class, key);
+ return entityManager().find(JPAVirSchema.class, key);
}
@Override
@@ -54,7 +54,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
append(JPAVirSchema.class.getSimpleName()).
append(" e WHERE e.anyTypeClass=:anyTypeClass");
- TypedQuery<VirSchema> query = entityManager.createQuery(queryString.toString(), VirSchema.class);
+ TypedQuery<VirSchema> query = entityManager().createQuery(queryString.toString(), VirSchema.class);
query.setParameter("anyTypeClass", anyTypeClass);
return query.getResultList();
@@ -62,7 +62,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
@Override
public List<VirSchema> findAll() {
- TypedQuery<VirSchema> query = entityManager.createQuery(
+ TypedQuery<VirSchema> query = entityManager().createQuery(
"SELECT e FROM " + JPAVirSchema.class.getSimpleName() + " e", VirSchema.class);
return query.getResultList();
}
@@ -73,7 +73,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
append(((JPAVirAttrDAO) virAttrDAO).getJPAEntityReference(reference).getSimpleName()).
append(" e WHERE e.schema=:schema");
- TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
+ TypedQuery<T> query = entityManager().createQuery(queryString.toString(), reference);
query.setParameter("schema", schema);
return query.getResultList();
@@ -81,7 +81,7 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
@Override
public VirSchema save(final VirSchema virSchema) {
- return entityManager.merge(virSchema);
+ return entityManager().merge(virSchema);
}
@Override
@@ -106,6 +106,6 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
schema.getAnyTypeClass().remove(schema);
}
- entityManager.remove(schema);
+ entityManager().remove(schema);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/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 06bebdb..2913dc6 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
@@ -125,7 +125,7 @@ public class JPAGroup extends AbstractAny<GPlainAttr, GDerAttr, GVirAttr> implem
@Override
public AnyType getType() {
- return ApplicationContextProvider.getApplicationContext().getBean(AnyTypeDAO.class).findGroup();
+ return ApplicationContextProvider.getBeanFactory().getBean(AnyTypeDAO.class).findGroup();
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
index 9723f1d..463408e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
@@ -80,15 +80,15 @@ public abstract class AbstractProvisioningTask extends JPASchedTask implements P
@Enumerated(EnumType.STRING)
protected MatchingRule matchingRule;
- public AbstractProvisioningTask(final TaskType type, final String jobClassName) {
+ public AbstractProvisioningTask(final TaskType type, final String jobDelegateClassName) {
super();
this.type = type;
- super.setJobClassName(jobClassName);
+ super.setJobDelegateClassName(jobDelegateClassName);
}
@Override
- public void setJobClassName(final String jobClassName) {
+ public void setJobDelegateClassName(final String jobClassName) {
// fixed to SyncJob, cannot be changed
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
index 0592a9d..190cc0f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
@@ -37,7 +37,6 @@ import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.task.AnyFilter;
import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.provisioning.api.job.PushJob;
@Entity
@DiscriminatorValue("PushTask")
@@ -59,7 +58,7 @@ public class JPAPushTask extends AbstractProvisioningTask implements PushTask {
* Default constructor.
*/
public JPAPushTask() {
- super(TaskType.PUSH, PushJob.class.getName());
+ super(TaskType.PUSH, null);
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
index 5703380..4f650ba 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
@@ -34,8 +34,7 @@ public class JPASchedTask extends JPATask implements SchedTask {
protected String cronExpression;
- @NotNull
- protected String jobClassName;
+ protected String jobDelegateClassName;
@NotNull
protected String name;
@@ -58,13 +57,13 @@ public class JPASchedTask extends JPATask implements SchedTask {
}
@Override
- public String getJobClassName() {
- return jobClassName;
+ public String getJobDelegateClassName() {
+ return jobDelegateClassName;
}
@Override
- public void setJobClassName(final String jobClassName) {
- this.jobClassName = jobClassName;
+ public void setJobDelegateClassName(final String jobDelegateClassName) {
+ this.jobDelegateClassName = jobDelegateClassName;
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
index 41eb4ea..f2da581 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
@@ -40,7 +40,6 @@ import org.apache.commons.collections4.Predicate;
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
@@ -73,7 +72,7 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
* Default constructor.
*/
public JPASyncTask() {
- super(TaskType.SYNCHRONIZATION, SyncJob.class.getName());
+ super(TaskType.SYNCHRONIZATION, null);
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/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 88c86fb..1f153da 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
@@ -55,7 +55,6 @@ import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.validation.entity.UserCheck;
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;
@@ -75,7 +74,6 @@ import org.apache.syncope.core.persistence.jpa.entity.JPARole;
@Entity
@Table(name = JPAUser.TABLE)
@Cacheable
-@UserCheck
public class JPAUser extends AbstractAny<UPlainAttr, UDerAttr, UVirAttr> implements User {
private static final long serialVersionUID = -3905046855521446823L;
@@ -212,7 +210,7 @@ public class JPAUser extends AbstractAny<UPlainAttr, UDerAttr, UVirAttr> impleme
@Override
public AnyType getType() {
- return ApplicationContextProvider.getApplicationContext().getBean(AnyTypeDAO.class).findUser();
+ return ApplicationContextProvider.getBeanFactory().getBean(AnyTypeDAO.class).findUser();
}
@Override
@@ -252,9 +250,13 @@ public class JPAUser extends AbstractAny<UPlainAttr, UDerAttr, UVirAttr> impleme
return clearPassword;
}
+ public void setClearPassword(final String clearPassword) {
+ this.clearPassword = clearPassword;
+ }
+
@Override
public void removeClearPassword() {
- clearPassword = null;
+ setClearPassword(null);
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java
new file mode 100644
index 0000000..3e44864
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java
@@ -0,0 +1,107 @@
+/*
+ * 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.util.HashMap;
+import java.util.Map;
+import javax.persistence.ValidationMode;
+import javax.sql.DataSource;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
+
+/**
+ * Container for common configuration options among all EntityManagerFactory entities (one for each domain).
+ * <br/>
+ * Acts as a commodity place for fetching each domain's {@link DataSource}..
+ */
+public class CommonEntityManagerFactoryConf implements DomainsHolder, InitializingBean, ApplicationContextAware {
+
+ private ApplicationContext ctx;
+
+ private final Map<String, DataSource> domains = new HashMap<>();
+
+ private String[] packagesToScan;
+
+ private ValidationMode validationMode;
+
+ private PersistenceUnitPostProcessor[] postProcessors;
+
+ private final Map<String, Object> jpaPropertyMap = new HashMap<>();
+
+ @Override
+ public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
+ this.ctx = ctx;
+ }
+
+ @Override
+ public void afterPropertiesSet() {
+ for (Map.Entry<String, DataSource> entry : ctx.getBeansOfType(DataSource.class).entrySet()) {
+ if (!entry.getKey().startsWith("local")) {
+ this.domains.put(
+ StringUtils.substringBefore(entry.getKey(), DataSource.class.getSimpleName()),
+ entry.getValue());
+ }
+ }
+ }
+
+ @Override
+ public Map<String, DataSource> getDomains() {
+ return domains;
+ }
+
+ public String[] getPackagesToScan() {
+ return packagesToScan;
+ }
+
+ public void setPackagesToScan(final String... packagesToScan) {
+ this.packagesToScan = packagesToScan;
+ }
+
+ public ValidationMode getValidationMode() {
+ return validationMode;
+ }
+
+ public void setValidationMode(final ValidationMode validationMode) {
+ this.validationMode = validationMode;
+ }
+
+ public PersistenceUnitPostProcessor[] getPersistenceUnitPostProcessors() {
+ return postProcessors;
+ }
+
+ public void setPersistenceUnitPostProcessors(final PersistenceUnitPostProcessor... postProcessors) {
+ this.postProcessors = postProcessors;
+ }
+
+ public Map<String, ?> getJpaPropertyMap() {
+ return jpaPropertyMap;
+ }
+
+ public void setJpaPropertyMap(final Map<String, ?> jpaProperties) {
+ if (jpaProperties != null) {
+ this.jpaPropertyMap.putAll(jpaProperties);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
new file mode 100644
index 0000000..a959f96
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
@@ -0,0 +1,45 @@
+/*
+ * 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.orm.jpa.LocalContainerEntityManagerFactoryBean;
+
+/**
+ * Extension of {@link LocalContainerEntityManagerFactoryBean} relying on {@link CommonEntityManagerFactoryConf} for
+ * common configuration options.
+ */
+public class DomainEntityManagerFactoryBean extends LocalContainerEntityManagerFactoryBean {
+
+ private static final long serialVersionUID = 49152547930966545L;
+
+ public void setCommonEntityManagerFactoryConf(final CommonEntityManagerFactoryConf commonEMFConf) {
+ super.setJpaPropertyMap(commonEMFConf.getJpaPropertyMap());
+
+ if (commonEMFConf.getPackagesToScan() != null) {
+ super.setPackagesToScan(commonEMFConf.getPackagesToScan());
+ }
+
+ super.setValidationMode(commonEMFConf.getValidationMode());
+
+ if (commonEMFConf.getPersistenceUnitPostProcessors() != null) {
+ super.setPersistenceUnitPostProcessors(commonEMFConf.getPersistenceUnitPostProcessors());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/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..42779ed
--- /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.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/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/SpringComponentReplacer.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/SpringComponentReplacer.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/SpringComponentReplacer.java
new file mode 100644
index 0000000..e983426
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/SpringComponentReplacer.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.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.stereotype.Component;
+import org.springframework.transaction.interceptor.TransactionInterceptor;
+
+/**
+ * Hack for dynamically replacing standard {@link TransactionInterceptor} with
+ * {@link DomainTransactionInterceptor} in Spring context.
+ */
+@Component
+public class SpringComponentReplacer implements BeanFactoryPostProcessor {
+
+ @Override
+ public void postProcessBeanFactory(final ConfigurableListableBeanFactory factory) throws BeansException {
+ for (String name : factory.getBeanNamesForType(TransactionInterceptor.class)) {
+ BeanDefinition bd = factory.getBeanDefinition(name);
+ bd.setBeanClassName(DomainTransactionInterceptor.class.getName());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/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 b7616c7..f1df70c 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
@@ -49,7 +49,7 @@ public class EntityValidationListener {
@PrePersist
@PreUpdate
public void validate(final Object object) {
- final Validator validator = ApplicationContextProvider.getApplicationContext().getBean(Validator.class);
+ final Validator validator = ApplicationContextProvider.getBeanFactory().getBean(Validator.class);
Set<ConstraintViolation<Object>> violations = validator.validate(object);
if (!violations.isEmpty()) {
LOG.warn("Bean validation errors found: {}", violations);
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/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 2b6e4e0..3c64499 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
@@ -37,11 +37,11 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas
}
@Override
- public boolean isValid(final ProvisioningTask object, final ConstraintValidatorContext context) {
- boolean isValid = schedV.isValid(object, context);
+ public boolean isValid(final ProvisioningTask task, final ConstraintValidatorContext context) {
+ boolean isValid = schedV.isValid(task, context);
if (isValid) {
- isValid = object.getResource() != null;
+ isValid = task.getResource() != null;
if (!isValid) {
LOG.error("Resource is null");
@@ -51,15 +51,15 @@ public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTas
addPropertyNode("resource").addConstraintViolation();
}
- if (!object.getActionsClassNames().isEmpty()) {
- for (String className : object.getActionsClassNames()) {
+ if (!task.getActionsClassNames().isEmpty()) {
+ for (String className : task.getActionsClassNames()) {
Class<?> actionsClass = null;
boolean isAssignable = false;
try {
actionsClass = Class.forName(className);
- isAssignable = object instanceof JPASyncTask
+ isAssignable = task instanceof JPASyncTask
? SyncActions.class.isAssignableFrom(actionsClass)
- : object instanceof JPAPushTask
+ : task instanceof JPAPushTask
? PushActions.class.isAssignableFrom(actionsClass)
: false;
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java
index 50a6d5d..5c159c2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SchedTaskValidator.java
@@ -21,39 +21,43 @@ package org.apache.syncope.core.persistence.jpa.validation.entity;
import java.text.ParseException;
import javax.validation.ConstraintValidatorContext;
+import org.apache.commons.lang3.ClassUtils;
import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
import org.quartz.CronExpression;
-import org.quartz.Job;
public class SchedTaskValidator extends AbstractValidator<SchedTaskCheck, SchedTask> {
@Override
- public boolean isValid(final SchedTask object, final ConstraintValidatorContext context) {
- boolean isValid;
+ public boolean isValid(final SchedTask task, final ConstraintValidatorContext context) {
+ boolean isValid = true;
- Class<?> jobClass = null;
- try {
- jobClass = Class.forName(object.getJobClassName());
- isValid = Job.class.isAssignableFrom(jobClass);
- } catch (Exception e) {
- LOG.error("Invalid Job class specified", e);
- isValid = false;
- }
- if (jobClass == null || !isValid) {
- isValid = false;
+ if (!(task instanceof ProvisioningTask)) {
+ Class<?> jobDelegateClass = null;
+ try {
+ jobDelegateClass = ClassUtils.getClass(task.getJobDelegateClassName());
+ isValid = SchedTaskJobDelegate.class.isAssignableFrom(jobDelegateClass);
+ } catch (Exception e) {
+ LOG.error("Invalid JobDelegate class specified", e);
+ isValid = false;
+ }
+ if (jobDelegateClass == null || !isValid) {
+ isValid = false;
- context.disableDefaultConstraintViolation();
- context.buildConstraintViolationWithTemplate(
- getTemplate(EntityViolationType.InvalidSchedTask, "Invalid job class name")).
- addPropertyNode("jobClassName").addConstraintViolation();
+ context.disableDefaultConstraintViolation();
+ context.buildConstraintViolationWithTemplate(
+ getTemplate(EntityViolationType.InvalidSchedTask, "Invalid job delegate class name")).
+ addPropertyNode("jobDelegateClassName").addConstraintViolation();
+ }
}
- if (isValid && object.getCronExpression() != null) {
+ if (isValid && task.getCronExpression() != null) {
try {
- new CronExpression(object.getCronExpression());
+ new CronExpression(task.getCronExpression());
} catch (ParseException e) {
- LOG.error("Invalid cron expression '" + object.getCronExpression() + "'", e);
+ LOG.error("Invalid cron expression '" + task.getCronExpression() + "'", e);
isValid = false;
context.disableDefaultConstraintViolation();
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserCheck.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserCheck.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserCheck.java
deleted file mode 100644
index 2d9fec6..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserCheck.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.persistence.jpa.validation.entity;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import javax.validation.Constraint;
-import javax.validation.Payload;
-
-@Target({ ElementType.TYPE })
-@Retention(RetentionPolicy.RUNTIME)
-@Constraint(validatedBy = UserValidator.class)
-@Documented
-public @interface UserCheck {
-
- String message() default "{org.apache.syncope.core.persistence.validation.user}";
-
- Class<?>[] groups() default {};
-
- Class<? extends Payload>[] payload() default {};
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
deleted file mode 100644
index e142de3..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/UserValidator.java
+++ /dev/null
@@ -1,199 +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.persistence.jpa.validation.entity;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.annotation.Resource;
-import javax.validation.ConstraintValidatorContext;
-import org.apache.syncope.common.lib.types.AccountPolicySpec;
-import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.common.lib.types.PasswordPolicySpec;
-import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.Policy;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.misc.policy.AccountPolicyEnforcer;
-import org.apache.syncope.core.misc.policy.AccountPolicyException;
-import org.apache.syncope.core.misc.policy.PasswordPolicyEnforcer;
-import org.apache.syncope.core.misc.policy.PolicyEvaluator;
-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;
-
-public class UserValidator extends AbstractValidator<UserCheck, User> {
-
- @Resource(name = "adminUser")
- private String adminUser;
-
- @Resource(name = "anonymousUser")
- private String anonymousUser;
-
- @Autowired
- private UserDAO userDAO;
-
- @Autowired
- private RealmDAO realmDAO;
-
- @Autowired
- private PolicyEvaluator evaluator;
-
- @Autowired
- private PasswordPolicyEnforcer ppEnforcer;
-
- @Autowired
- private AccountPolicyEnforcer apEnforcer;
-
- @Override
- public boolean isValid(final User user, final ConstraintValidatorContext context) {
- context.disableDefaultConstraintViolation();
-
- // need to treat it explicitly, otherwise policy evaluation will silently fail
- if (user.getRealm() == null) {
- context.buildConstraintViolationWithTemplate(
- getTemplate(EntityViolationType.InvalidRealm, "realm not specified")).
- addPropertyNode("realm").addConstraintViolation();
-
- return false;
- }
-
- // ------------------------------
- // Verify password policies
- // ------------------------------
- LOG.debug("Password Policy enforcement");
-
- try {
- int maxPPSpecHistory = 0;
- for (Policy policy : getPasswordPolicies(user)) {
- // evaluate policy
- PasswordPolicySpec ppSpec = evaluator.evaluate(policy, user);
- // enforce policy
- ppEnforcer.enforce(ppSpec, policy.getType(), user);
-
- if (ppSpec.getHistoryLength() > maxPPSpecHistory) {
- maxPPSpecHistory = ppSpec.getHistoryLength();
- }
- }
-
- // update user's password history with encrypted password
- if (maxPPSpecHistory > 0 && user.getPassword() != null) {
- user.getPasswordHistory().add(user.getPassword());
- }
- // keep only the last maxPPSpecHistory items in user's password history
- if (maxPPSpecHistory < user.getPasswordHistory().size()) {
- for (int i = 0; i < user.getPasswordHistory().size() - maxPPSpecHistory; i++) {
- user.getPasswordHistory().remove(i);
- }
- }
- } catch (Exception e) {
- LOG.debug("Invalid password");
-
- context.buildConstraintViolationWithTemplate(
- getTemplate(EntityViolationType.InvalidPassword, e.getMessage())).
- addPropertyNode("password").addConstraintViolation();
-
- return false;
- } finally {
- // password has been validated, let's remove its clear version
- user.removeClearPassword();
- }
- // ------------------------------
-
- // ------------------------------
- // Verify account policies
- // ------------------------------
- LOG.debug("Account Policy enforcement");
-
- try {
- if (adminUser.equals(user.getUsername()) || anonymousUser.equals(user.getUsername())) {
- throw new AccountPolicyException("Not allowed: " + user.getUsername());
- }
-
- // invalid username
- for (Policy policy : getAccountPolicies(user)) {
- // evaluate policy
- AccountPolicySpec accountPolicy = evaluator.evaluate(policy, user);
-
- // enforce policy
- apEnforcer.enforce(accountPolicy, policy.getType(), user);
- }
- } catch (Exception e) {
- LOG.debug("Invalid username");
-
- context.buildConstraintViolationWithTemplate(
- getTemplate(EntityViolationType.InvalidUsername, e.getMessage())).
- addPropertyNode("username").addConstraintViolation();
-
- return false;
- }
- // ------------------------------
-
- return true;
- }
-
- private List<PasswordPolicy> getPasswordPolicies(final User user) {
- List<PasswordPolicy> policies = new ArrayList<>();
-
- PasswordPolicy policy;
-
- // add resource policies
- for (ExternalResource resource : userDAO.findAllResources(user)) {
- policy = resource.getPasswordPolicy();
- if (policy != null) {
- policies.add(policy);
- }
- }
-
- // add realm policies
- for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
- policy = realm.getPasswordPolicy();
- if (policy != null) {
- policies.add(policy);
- }
- }
-
- return policies;
- }
-
- private List<AccountPolicy> getAccountPolicies(final User user) {
- List<AccountPolicy> policies = new ArrayList<>();
-
- AccountPolicy policy;
-
- // add resource policies
- for (ExternalResource resource : userDAO.findAllResources(user)) {
- policy = resource.getAccountPolicy();
- if (policy != null) {
- policies.add(policy);
- }
- }
-
- // add realm policies
- for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
- policy = realm.getAccountPolicy();
- if (policy != null) {
- policies.add(policy);
- }
- }
-
- return policies;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/audit/audit.sql
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/audit/audit.sql b/core/persistence-jpa/src/main/resources/audit/audit.sql
index faf8c5b..44ffb17 100644
--- a/core/persistence-jpa/src/main/resources/audit/audit.sql
+++ b/core/persistence-jpa/src/main/resources/audit/audit.sql
@@ -21,4 +21,6 @@ CREATE TABLE IF NOT EXISTS SYNCOPEAUDIT (
LOGGER VARCHAR(255) NOT NULL,
MESSAGE TEXT NOT NULL,
THROWABLE TEXT
-)
+);
+
+COMMIT;
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/content.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/content.xml b/core/persistence-jpa/src/main/resources/content.xml
deleted file mode 100644
index caba10e..0000000
--- a/core/persistence-jpa/src/main/resources/content.xml
+++ /dev/null
@@ -1,117 +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.
--->
-<dataset>
- <Realm id="1" name="/"/>
-
- <SyncopeConf id="1"
- creator="admin" lastModifier="admin"
- creationDate="2014-06-20 11:00:00" lastChangeDate="2014-06-20 11:00:00"/>
-
- <PlainSchema name="password.cipher.algorithm" type="String"
- mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
- <CPlainAttr id="1" owner_id="1" schema_name="password.cipher.algorithm"/>
- <CPlainAttrValue id="1" attribute_id="1" stringValue="SHA1"/>
-
- <!-- notificationjob.cronExpression:
- + not existing: NotificationJob runs according to Notification.DEFAULT_CRON_EXP
- + provided as empty string: NotificationJob disabled
- + provided as non-empty string: NotificationJob runs according to the given value -->
- <PlainSchema name="notificationjob.cronExpression" type="String"
- mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
- <CPlainAttr id="2" owner_id="1" schema_name="notificationjob.cronExpression"/>
- <CPlainAttrValue id="2" attribute_id="2" stringValue=""/>
-
- <PlainSchema name="notification.maxRetries" type="Long"
- mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
- <CPlainAttr id="3" owner_id="1" schema_name="notification.maxRetries"/>
- <CPlainAttrValue id="3" attribute_id="3" longValue="3"/>
-
- <PlainSchema name="token.length" type="Long"
- mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
- <CPlainAttr id="4" owner_id="1" schema_name="token.length"/>
- <CPlainAttrValue id="4" attribute_id="4" longValue="256"/>
-
- <PlainSchema name="token.expireTime" type="Long"
- mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
- <CPlainAttr id="5" owner_id="1" schema_name="token.expireTime"/>
- <CPlainAttrValue id="5" attribute_id="5" longValue="60"/>
-
- <PlainSchema name="selfRegistration.allowed" type="Boolean"
- mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
- <CPlainAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
- <CPlainAttrValue id="6" attribute_id="6" booleanValue="1"/>
-
- <PlainSchema name="passwordReset.allowed" type="Boolean"
- mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
- <CPlainAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
- <CPlainAttrValue id="7" attribute_id="7" booleanValue="1"/>
-
- <PlainSchema name="passwordReset.securityQuestion" type="Boolean"
- mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
- <CPlainAttr id="8" owner_id="1" schema_name="passwordReset.securityQuestion"/>
- <CPlainAttrValue id="8" attribute_id="8" booleanValue="1"/>
-
- <PlainSchema name="authentication.statuses" type="String"
- mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
- <CPlainAttr id="9" owner_id="1" schema_name="authentication.statuses"/>
- <CPlainAttrValue id="9" attribute_id="9" stringValue="created"/>
- <CPlainAttrValue id="10" attribute_id="9" stringValue="active"/>
-
- <!-- Save user login date upon successful authentication -->
- <PlainSchema name="log.lastlogindate" type="Boolean"
- mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
- <CPlainAttr id="11" owner_id="1" schema_name="log.lastlogindate"/>
- <CPlainAttrValue id="11" attribute_id="11" booleanValue="1"/>
-
- <PlainSchema name="tasks.interruptMaxRetries" type="Long"
- mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
- <CPlainAttr id="12" owner_id="1" schema_name="tasks.interruptMaxRetries"/>
- <CPlainAttrValue id="12" attribute_id="12" longValue="20"/>
-
- <!-- For usage with admin console -->
- <PlainSchema name="admin.user.layout" type="String"
- mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
- <PlainSchema name="self.user.layout" type="String"
- mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
- <PlainSchema name="admin.group.layout" type="String"
- mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
- <PlainSchema name="self.group.layout" type="String"
- mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
- <PlainSchema name="admin.membership.layout" type="String"
- mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
- <PlainSchema name="self.membership.layout" type="String"
- mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
-
- <PlainSchema name="email" type="String"
- mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
- validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
-
- <!-- Password reset notifications -->
- <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1"
- sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset"
- traceLevel="FAILURES" userAbout="token!=$null"/>
- <Notification_events Notification_id="1" event="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/>
-
- <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1"
- sender="admin@syncope.apache.org" subject="Password Reset successful" template="confirmPasswordReset"
- traceLevel="FAILURES" userAbout="token!=$null"/>
- <Notification_events Notification_id="2" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
-
-</dataset>
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/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
new file mode 100644
index 0000000..43fce14
--- /dev/null
+++ b/core/persistence-jpa/src/main/resources/domains.xml
@@ -0,0 +1,56 @@
+<?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"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <import resource="classpath*:domains/*Domain.xml"/>
+
+ <bean id="commonEMFConf" class="org.apache.syncope.core.persistence.jpa.spring.CommonEntityManagerFactoryConf">
+ <property name="packagesToScan" value="org.apache.syncope.core.persistence.jpa.entity"/>
+ <property name="validationMode" value="NONE"/>
+ <property name="persistenceUnitPostProcessors">
+ <list>
+ <bean class="org.apache.syncope.core.persistence.jpa.spring.MultiJarAwarePersistenceUnitPostProcessor"/>
+ </list>
+ </property>
+ <property name="jpaPropertyMap">
+ <map>
+ <entry key="openjpa.Log" value="slf4j"/>
+ <!--<entry key="openjpa.Log" value="SQL=TRACE"/>
+ <entry key="openjpa.ConnectionFactoryProperties"
+ value="PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=80"/>-->
+
+ <entry key="openjpa.NontransactionalWrite" value="false"/>
+ <entry key="openjpa.AutoDetach" value="close, commit, nontx-read, rollback"/>
+
+ <entry key="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)"/>
+ <entry key="openjpa.jdbc.MappingDefaults"
+ value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict"/>
+
+ <entry key="openjpa.DataCache" value="true"/>
+ <entry key="openjpa.QueryCache" value="true"/>
+ <entry key="openjpa.RemoteCommitProvider" value="sjvm"/>
+ </map>
+ </property>
+ </bean>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/syncope/blob/6dfedd8f/core/persistence-jpa/src/main/resources/domains/Master.properties
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/domains/Master.properties b/core/persistence-jpa/src/main/resources/domains/Master.properties
new file mode 100644
index 0000000..177e988
--- /dev/null
+++ b/core/persistence-jpa/src/main/resources/domains/Master.properties
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+Master.driverClassName=org.postgresql.Driver
+Master.url=jdbc:postgresql://localhost:5432/syncope
+Master.schema=
+Master.username=syncope
+Master.password=syncope
+Master.databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDictionary
+Master.orm=META-INF/spring-orm.xml
+
+# note: other connection pool settings can also be configured here, see DataSource definition
+Master.pool.validationQuery=SELECT 1
+
+Master.audit.sql=audit.sql