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/05/08 17:03:07 UTC
[2/3] syncope git commit: [SYNCOPE-140] Implemented
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/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 5264fcd..46b51dc 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
@@ -18,7 +18,10 @@
*/
package org.apache.syncope.core.persistence.jpa.dao;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Resource;
@@ -26,6 +29,7 @@ import javax.persistence.NoResultException;
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.syncope.common.lib.types.AttributableType;
import org.apache.syncope.common.lib.types.Entitlement;
import org.apache.syncope.common.lib.types.SubjectType;
@@ -47,8 +51,14 @@ 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.dao.RoleDAO;
+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.jpa.entity.JPADynGroupMembership;
+import org.apache.syncope.core.persistence.jpa.entity.JPADynRoleMembership;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Repository
@@ -57,6 +67,9 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
@Autowired
private GroupDAO groupDAO;
+ @Autowired
+ private RoleDAO roleDAO;
+
@Resource(name = "anonymousUser")
private String anonymousUser;
@@ -187,12 +200,15 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
@Override
public User save(final User user) {
- final User merged = entityManager.merge(user);
+ User merged = entityManager.merge(user);
for (VirAttr virAttr : merged.getVirAttrs()) {
virAttr.getValues().clear();
virAttr.getValues().addAll(user.getVirAttr(virAttr.getSchema().getKey()).getValues());
}
+ roleDAO.refreshDynMemberships(merged);
+ groupDAO.refreshDynMemberships(merged);
+
return merged;
}
@@ -220,6 +236,13 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
}
user.getMemberships().clear();
+ for (Role role : findDynRoleMemberships(user)) {
+ role.getDynMembership().removeUser(user);
+ }
+ for (Group group : findDynGroupMemberships(user)) {
+ group.getDynMembership().removeUser(user);
+ }
+
entityManager.remove(user);
}
@@ -277,4 +300,82 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
return user;
}
+ @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+ @Override
+ public List<Role> findDynRoleMemberships(final User user) {
+ 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);
+
+ return query.getResultList();
+ }
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+ @Override
+ public List<Group> findDynGroupMemberships(final User user) {
+ TypedQuery<Group> query = entityManager.createQuery(
+ "SELECT e.group FROM " + JPADynGroupMembership.class.getSimpleName()
+ + " e WHERE :user MEMBER OF e.users", Group.class);
+ query.setParameter("user", user);
+
+ return query.getResultList();
+ }
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+ @Override
+ public Collection<Role> findAllRoles(final User user) {
+ return CollectionUtils.union(user.getRoles(), findDynRoleMemberships(user));
+ }
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+ @Override
+ public Collection<Group> findAllGroups(final User user) {
+ return CollectionUtils.union(
+ CollectionUtils.collect(user.getMemberships(), new Transformer<Membership, Group>() {
+
+ @Override
+ public Group transform(final Membership input) {
+ return input.getGroup();
+ }
+ }, new ArrayList<Group>()),
+ findDynGroupMemberships(user));
+ }
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+ @Override
+ public Collection<Long> findAllGroupKeys(final User user) {
+ return CollectionUtils.collect(findAllGroups(user), new Transformer<Group, Long>() {
+
+ @Override
+ public Long transform(final Group input) {
+ return input.getKey();
+ }
+ });
+ }
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+ @Override
+ public Collection<ExternalResource> findAllResources(final User user) {
+ Set<ExternalResource> result = new HashSet<>();
+ result.addAll(user.getResources());
+ for (Group group : findAllGroups(user)) {
+ result.addAll(group.getResources());
+ }
+
+ return result;
+ }
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+ @Override
+ public Collection<String> findAllResourceNames(final User user) {
+ return CollectionUtils.collect(findAllResources(user), new Transformer<ExternalResource, String>() {
+
+ @Override
+ public String transform(final ExternalResource input) {
+ return input.getKey();
+ }
+ });
+ }
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
index 9e80ff7..11b3298 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
@@ -110,6 +110,18 @@ class SearchSupport {
return new SearchView("svm", field().name + "_membership");
}
+ public SearchView dyngroupmembership() {
+ return new SearchView("svdg", field().name + "_dyngroupmembership");
+ }
+
+ public SearchView role() {
+ return new SearchView("svr", field().name + "_role");
+ }
+
+ public SearchView dynrolemembership() {
+ return new SearchView("svdr", field().name + "_dynrolemembership");
+ }
+
public SearchView nullAttr() {
return new SearchView("svna", field().name + "_null_attr");
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java
new file mode 100644
index 0000000..6e47b34
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.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.persistence.jpa.entity;
+
+import java.util.List;
+import javax.persistence.MappedSuperclass;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.core.persistence.api.entity.DynMembership;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
+
+@MappedSuperclass
+public abstract class AbstractDynMembership extends AbstractEntity<Long> implements DynMembership {
+
+ private static final long serialVersionUID = 921821654690948787L;
+
+ @NotNull
+ private String fiql;
+
+ @Override
+ public String getFIQLCond() {
+ return fiql;
+ }
+
+ @Override
+ public void setFIQLCond(final String fiql) {
+ this.fiql = fiql;
+ }
+
+ protected abstract List<JPAUser> internalGetUsers();
+
+ @Override
+ public boolean addUser(final User user) {
+ checkType(user, JPAUser.class);
+ return internalGetUsers().add((JPAUser) user);
+ }
+
+ @Override
+ public boolean removeUser(final User user) {
+ checkType(user, JPAUser.class);
+ return internalGetUsers().remove((JPAUser) user);
+ }
+
+ @Override
+ public List<? extends User> getUsers() {
+ return internalGetUsers();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java
index b0a7ab4..166309f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java
@@ -52,17 +52,18 @@ public abstract class AbstractSubject<P extends PlainAttr, D extends DerAttr, V
this.realm = (JPARealm) realm;
}
- protected abstract Set<? extends ExternalResource> internalGetResources();
+ protected abstract Set<JPAExternalResource> internalGetResources();
@Override
- @SuppressWarnings("unchecked")
public boolean addResource(final ExternalResource resource) {
- return ((Set<ExternalResource>) internalGetResources()).add(resource);
+ checkType(resource, JPAExternalResource.class);
+ return internalGetResources().add((JPAExternalResource) resource);
}
@Override
public boolean removeResource(final ExternalResource resource) {
- return internalGetResources().remove(resource);
+ checkType(resource, JPAExternalResource.class);
+ return internalGetResources().remove((JPAExternalResource) resource);
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/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 f814033..8a9547e 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
@@ -28,9 +28,6 @@ import org.slf4j.LoggerFactory;
public class AnnotatedEntityListener {
- /**
- * Logger.
- */
private static final Logger LOG = LoggerFactory.getLogger(AnnotatedEntityListener.class);
@PrePersist
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynGroupMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynGroupMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynGroupMembership.java
new file mode 100644
index 0000000..1f55348
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynGroupMembership.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.persistence.jpa.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
+
+@Entity
+@Table(name = JPADynGroupMembership.TABLE)
+public class JPADynGroupMembership extends AbstractDynMembership implements DynGroupMembership {
+
+ private static final long serialVersionUID = -7336814163949640354L;
+
+ public static final String TABLE = "DynGroupMembership";
+
+ @Id
+ private Long id;
+
+ @OneToOne
+ private JPAGroup group;
+
+ @ManyToMany
+ @JoinTable(joinColumns =
+ @JoinColumn(name = "dynGroupMembership_id"),
+ inverseJoinColumns =
+ @JoinColumn(name = "user_id"))
+ private List<JPAUser> users = new ArrayList<>();
+
+ @Override
+ public Long getKey() {
+ return id;
+ }
+
+ @Override
+ protected List<JPAUser> internalGetUsers() {
+ return users;
+ }
+
+ @Override
+ public Group getGroup() {
+ return group;
+ }
+
+ @Override
+ public void setGroup(final Group role) {
+ checkType(role, JPAGroup.class);
+ this.group = (JPAGroup) role;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynRoleMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynRoleMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynRoleMembership.java
new file mode 100644
index 0000000..4796abf
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADynRoleMembership.java
@@ -0,0 +1,76 @@
+/*
+ * 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.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.DynRoleMembership;
+import org.apache.syncope.core.persistence.api.entity.Role;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
+
+@Entity
+@Table(name = JPADynRoleMembership.TABLE)
+public class JPADynRoleMembership extends AbstractDynMembership implements DynRoleMembership {
+
+ private static final long serialVersionUID = -7336814163949640354L;
+
+ public static final String TABLE = "DynRoleMembership";
+
+ @Id
+ private Long id;
+
+ @OneToOne
+ private JPARole role;
+
+ @ManyToMany
+ @JoinTable(joinColumns =
+ @JoinColumn(name = "dynRoleMembership_id"),
+ inverseJoinColumns =
+ @JoinColumn(name = "user_id"))
+ private List<JPAUser> users = new ArrayList<>();
+
+ @Override
+ public Long getKey() {
+ return id;
+ }
+
+ @Override
+ protected List<JPAUser> internalGetUsers() {
+ return users;
+ }
+
+ @Override
+ public Role getRole() {
+ return role;
+ }
+
+ @Override
+ public void setRole(final Role role) {
+ checkType(role, JPARole.class);
+ this.role = (JPARole) role;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index 3002dcc..048955b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
@@ -21,6 +21,8 @@ package org.apache.syncope.core.persistence.jpa.entity;
import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
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.DynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.DynRoleMembership;
import org.apache.syncope.core.persistence.api.entity.Entity;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.ExternalResource;
@@ -265,6 +267,10 @@ public class JPAEntityFactory implements EntityFactory {
result = (T) new JPASecurityQuestion();
} else if (reference.equals(Logger.class)) {
result = (T) new JPALogger();
+ } else if (reference.equals(DynRoleMembership.class)) {
+ result = (T) new JPADynRoleMembership();
+ } else if (reference.equals(DynGroupMembership.class)) {
+ result = (T) new JPADynGroupMembership();
} else {
throw new IllegalArgumentException("Could not find a JPA implementation of " + reference.getName());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
index f88f430..0360f54 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
@@ -23,6 +23,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.Cacheable;
+import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
@@ -32,9 +33,11 @@ import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
+import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
+import org.apache.syncope.core.persistence.api.entity.DynRoleMembership;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.Role;
@@ -69,6 +72,10 @@ public class JPARole extends AbstractEntity<Long> implements Role {
@Valid
private List<JPARealm> realms = new ArrayList<>();
+ @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "role")
+ @Valid
+ private JPADynRoleMembership dynMembership;
+
@Override
public Long getKey() {
return id;
@@ -106,4 +113,14 @@ public class JPARole extends AbstractEntity<Long> implements Role {
return realms;
}
+ @Override
+ public DynRoleMembership getDynMembership() {
+ return dynMembership;
+ }
+
+ @Override
+ public void setDynMembership(final DynRoleMembership dynMembership) {
+ checkType(dynMembership, JPADynRoleMembership.class);
+ this.dynMembership = (JPADynRoleMembership) dynMembership;
+ }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/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 720b875..20e8808 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
@@ -33,6 +33,7 @@ import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
@@ -40,7 +41,7 @@ import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.Transformer;
import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
import org.apache.syncope.core.persistence.api.entity.Schema;
import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
@@ -55,6 +56,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.core.persistence.jpa.validation.entity.GroupCheck;
import org.apache.syncope.core.persistence.jpa.entity.AbstractSubject;
+import org.apache.syncope.core.persistence.jpa.entity.JPADynGroupMembership;
import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrTemplate;
import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttrTemplate;
@@ -131,6 +133,10 @@ public class JPAGroup extends AbstractSubject<GPlainAttr, GDerAttr, GVirAttr> im
@Valid
private Set<JPAExternalResource> resources;
+ @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "group")
+ @Valid
+ private JPADynGroupMembership dynMembership;
+
public JPAGroup() {
super();
@@ -154,7 +160,7 @@ public class JPAGroup extends AbstractSubject<GPlainAttr, GDerAttr, GVirAttr> im
}
@Override
- protected Set<? extends ExternalResource> internalGetResources() {
+ protected Set<JPAExternalResource> internalGetResources() {
return resources;
}
@@ -286,4 +292,16 @@ public class JPAGroup extends AbstractSubject<GPlainAttr, GDerAttr, GVirAttr> im
public List<? extends GVirAttr> getVirAttrs() {
return virAttrs;
}
+
+ @Override
+ public DynGroupMembership getDynMembership() {
+ return dynMembership;
+ }
+
+ @Override
+ public void setDynMembership(final DynGroupMembership dynMembership) {
+ checkType(dynMembership, JPADynGroupMembership.class);
+ this.dynMembership = (JPADynGroupMembership) dynMembership;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/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 3170c14..029c96b 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
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.entity.user;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
@@ -53,9 +54,7 @@ import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.Transformer;
import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
@@ -71,9 +70,6 @@ import org.apache.syncope.core.misc.security.SecureRandomUtils;
import org.apache.syncope.core.persistence.api.entity.Role;
import org.apache.syncope.core.persistence.jpa.entity.JPARole;
-/**
- * JPA user bean.
- */
@Entity
@Table(name = JPAUser.TABLE)
@Cacheable
@@ -206,7 +202,7 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
}
@Override
- protected Set<? extends ExternalResource> internalGetResources() {
+ protected Set<JPAExternalResource> internalGetResources() {
return resources;
}
@@ -256,44 +252,17 @@ public class JPAUser extends AbstractSubject<UPlainAttr, UDerAttr, UVirAttr> imp
}
@Override
- public List<Group> getGroups() {
- return CollectionUtils.collect(memberships, new Transformer<Membership, Group>() {
-
- @Override
- public Group transform(final Membership input) {
- return input.getGroup();
- }
- }, new ArrayList<Group>());
- }
-
- @Override
- public Set<Long> getGroupKeys() {
- return CollectionUtils.collect(getGroups(), new Transformer<Group, Long>() {
+ public Collection<Long> getStaticGroupKeys() {
+ return CollectionUtils.collect(memberships, new Transformer<Membership, Long>() {
@Override
- public Long transform(final Group input) {
- return input.getKey();
+ public Long transform(final Membership membership) {
+ return membership.getGroup().getKey();
}
}, new HashSet<Long>());
}
@Override
- public Set<ExternalResource> getResources() {
- Set<ExternalResource> result = new HashSet<>();
- result.addAll(super.getResources());
- for (Group group : getGroups()) {
- result.addAll(group.getResources());
- }
-
- return result;
- }
-
- @Override
- public Set<? extends ExternalResource> getOwnResources() {
- return super.getResources();
- }
-
- @Override
public String getPassword() {
return password;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/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
index fac60cb..19fc7cf 100644
--- 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
@@ -25,7 +25,6 @@ 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.dao.PolicyDAO;
import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
import org.apache.syncope.core.persistence.api.entity.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
@@ -36,6 +35,7 @@ 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;
@@ -48,7 +48,7 @@ public class UserValidator extends AbstractValidator<UserCheck, User> {
private String anonymousUser;
@Autowired
- private PolicyDAO policyDAO;
+ private UserDAO userDAO;
@Autowired
private RealmDAO realmDAO;
@@ -155,7 +155,7 @@ public class UserValidator extends AbstractValidator<UserCheck, User> {
PasswordPolicy policy;
// add resource policies
- for (ExternalResource resource : user.getResources()) {
+ for (ExternalResource resource : userDAO.findAllResources(user)) {
policy = resource.getPasswordPolicy();
if (policy != null) {
policies.add(policy);
@@ -179,7 +179,7 @@ public class UserValidator extends AbstractValidator<UserCheck, User> {
AccountPolicy policy;
// add resource policies
- for (ExternalResource resource : user.getResources()) {
+ for (ExternalResource resource : userDAO.findAllResources(user)) {
policy = resource.getAccountPolicy();
if (policy != null) {
policies.add(policy);
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
index 3a61895..8c58d33 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
@@ -57,6 +57,15 @@ under the License.
</attributes>
</entity>
+ <entity class="org.apache.syncope.core.persistence.jpa.entity.JPADynRoleMembership">
+ <attributes>
+ <id name="id">
+ <generated-value generator="SEQ_DynRoleMembership" strategy="TABLE"/>
+ <table-generator name="SEQ_DynRoleMembership" pk-column-value="SEQ_DynRoleMembership" initial-value="100"/>
+ </id>
+ </attributes>
+ </entity>
+
<entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUser">
<attributes>
<id name="id">
@@ -75,6 +84,15 @@ under the License.
</attributes>
</entity>
+ <entity class="org.apache.syncope.core.persistence.jpa.entity.JPADynGroupMembership">
+ <attributes>
+ <id name="id">
+ <generated-value generator="SEQ_DynGroupMembership" strategy="TABLE"/>
+ <table-generator name="SEQ_DynGroupMembership" pk-column-value="SEQ_DynGroupMembership" initial-value="100"/>
+ </id>
+ </attributes>
+ </entity>
+
<entity class="org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership">
<attributes>
<id name="id">
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
index 97af974..bd7f664 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
@@ -57,6 +57,15 @@ under the License.
</attributes>
</entity>
+ <entity class="org.apache.syncope.core.persistence.jpa.entity.JPADynRoleMembership">
+ <attributes>
+ <id name="id">
+ <generated-value generator="SEQ_DynRoleMembership" strategy="TABLE"/>
+ <table-generator name="SEQ_DynRoleMembership" pk-column-value="SEQ_DynRoleMembership" initial-value="100"/>
+ </id>
+ </attributes>
+ </entity>
+
<entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUser">
<attributes>
<id name="id">
@@ -75,6 +84,15 @@ under the License.
</attributes>
</entity>
+ <entity class="org.apache.syncope.core.persistence.jpa.entity.JPADynGroupMembership">
+ <attributes>
+ <id name="id">
+ <generated-value generator="SEQ_DynGroupMembership" strategy="TABLE"/>
+ <table-generator name="SEQ_DynGroupMembership" pk-column-value="SEQ_DynGroupMembership" initial-value="100"/>
+ </id>
+ </attributes>
+ </entity>
+
<entity class="org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership">
<attributes>
<id name="id">
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
index 5921b94..5562674 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
@@ -56,7 +56,16 @@ under the License.
</id>
</attributes>
</entity>
-
+
+ <entity class="org.apache.syncope.core.persistence.jpa.entity.JPADynRoleMembership">
+ <attributes>
+ <id name="id">
+ <generated-value generator="SEQ_DynRoleMembership" strategy="TABLE"/>
+ <table-generator name="SEQ_DynRoleMembership" pk-column-value="SEQ_DynRoleMembership" initial-value="100"/>
+ </id>
+ </attributes>
+ </entity>
+
<entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUser">
<attributes>
<id name="id">
@@ -74,7 +83,16 @@ under the License.
</id>
</attributes>
</entity>
-
+
+ <entity class="org.apache.syncope.core.persistence.jpa.entity.JPADynGroupMembership">
+ <attributes>
+ <id name="id">
+ <generated-value generator="SEQ_DynGroupMembership" strategy="TABLE"/>
+ <table-generator name="SEQ_DynGroupMembership" pk-column-value="SEQ_DynGroupMembership" initial-value="100"/>
+ </id>
+ </attributes>
+ </entity>
+
<entity class="org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership">
<attributes>
<id name="id">
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/main/resources/views.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/views.xml b/core/persistence-jpa/src/main/resources/views.xml
index 8cd392d..f7bce20 100644
--- a/core/persistence-jpa/src/main/resources/views.xml
+++ b/core/persistence-jpa/src/main/resources/views.xml
@@ -68,9 +68,29 @@ under the License.
<entry key="user_search_membership">
CREATE VIEW user_search_membership AS
- SELECT m.user_id AS subject_id, r.id AS group_id, r.name AS group_name
- FROM Membership m, SyncopeGroup r
- WHERE m.group_id = r.id
+ SELECT m.user_id AS subject_id, g.id AS group_id, g.name AS group_name
+ FROM Membership m, SyncopeGroup g
+ WHERE m.group_id = g.id
+ </entry>
+ <entry key="user_search_dyngroupmembership">
+ CREATE VIEW user_search_dyngroupmembership AS
+
+ SELECT ds.user_id AS subject_id, d.group_id AS group_id
+ FROM DynGroupMembership d, DynGroupMembership_SyncopeUser ds
+ WHERE d.id = ds.dynGroupMembership_id
+ </entry>
+ <entry key="user_search_role">
+ CREATE VIEW user_search_role AS
+
+ SELECT ss.user_id AS subject_id, ss.role_id AS role_id
+ FROM SyncopeUser_SyncopeRole ss
+ </entry>
+ <entry key="user_search_dynrolemembership">
+ CREATE VIEW user_search_dynrolemembership AS
+
+ SELECT ds.user_id AS subject_id, d.role_id AS role_id
+ FROM DynRoleMembership d, DynRoleMembership_SyncopeUser ds
+ WHERE d.id = ds.dynRoleMembership_id
</entry>
<entry key="user_search_resource">
CREATE VIEW user_search_resource AS
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AttrTest.java
index 289f898..4ad4dd0 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AttrTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AttrTest.java
@@ -56,7 +56,7 @@ public class AttrTest extends AbstractTest {
private PlainAttrDAO plainAttrDAO;
@Autowired
- private PlainSchemaDAO userSchemaDAO;
+ private PlainSchemaDAO plainSchemaDAO;
@Test
public void findById() {
@@ -78,7 +78,7 @@ public class AttrTest extends AbstractTest {
public void save() throws ClassNotFoundException {
User user = userDAO.find(1L);
- UPlainSchema emailSchema = userSchemaDAO.find("email", UPlainSchema.class);
+ UPlainSchema emailSchema = plainSchemaDAO.find("email", UPlainSchema.class);
assertNotNull(emailSchema);
UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
@@ -106,7 +106,7 @@ public class AttrTest extends AbstractTest {
public void saveWithEnum() throws ClassNotFoundException {
User user = userDAO.find(1L);
- UPlainSchema gender = userSchemaDAO.find("gender", UPlainSchema.class);
+ UPlainSchema gender = plainSchemaDAO.find("gender", UPlainSchema.class);
assertNotNull(gender);
assertNotNull(gender.getType());
assertNotNull(gender.getEnumerationValues());
@@ -140,10 +140,10 @@ public class AttrTest extends AbstractTest {
public void validateAndSave() {
User user = userDAO.find(1L);
- final UPlainSchema emailSchema = userSchemaDAO.find("email", UPlainSchema.class);
+ final UPlainSchema emailSchema = plainSchemaDAO.find("email", UPlainSchema.class);
assertNotNull(emailSchema);
- final UPlainSchema fullnameSchema = userSchemaDAO.find("fullname", UPlainSchema.class);
+ final UPlainSchema fullnameSchema = plainSchemaDAO.find("fullname", UPlainSchema.class);
assertNotNull(fullnameSchema);
UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
@@ -176,7 +176,7 @@ public class AttrTest extends AbstractTest {
public void saveWithEncrypted() throws Exception {
User user = userDAO.find(1L);
- final UPlainSchema obscureSchema = userSchemaDAO.find("obscure", UPlainSchema.class);
+ final UPlainSchema obscureSchema = plainSchemaDAO.find("obscure", UPlainSchema.class);
assertNotNull(obscureSchema);
assertNotNull(obscureSchema.getSecretKey());
assertNotNull(obscureSchema.getCipherAlgorithm());
@@ -200,7 +200,7 @@ public class AttrTest extends AbstractTest {
public void saveWithBinary() throws UnsupportedEncodingException {
User user = userDAO.find(1L);
- final UPlainSchema photoSchema = userSchemaDAO.find("photo", UPlainSchema.class);
+ final UPlainSchema photoSchema = plainSchemaDAO.find("photo", UPlainSchema.class);
assertNotNull(photoSchema);
assertNotNull(photoSchema.getMimeType());
@@ -229,7 +229,7 @@ public class AttrTest extends AbstractTest {
plainAttrDAO.delete(attribute.getKey(), UPlainAttr.class);
- UPlainSchema schema = userSchemaDAO.find(attrSchemaName, UPlainSchema.class);
+ UPlainSchema schema = plainSchemaDAO.find(attrSchemaName, UPlainSchema.class);
assertNotNull("user attribute schema deleted when deleting values", schema);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.java
index a7bf883..7a20e89 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.java
@@ -28,7 +28,6 @@ import java.util.List;
import org.apache.syncope.common.lib.types.Entitlement;
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.dao.SubjectSearchDAO;
import org.apache.syncope.core.persistence.api.entity.Role;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
import org.junit.Test;
@@ -42,9 +41,6 @@ public class RoleTest extends AbstractTest {
private RoleDAO roleDAO;
@Autowired
- private SubjectSearchDAO searchDAO;
-
- @Autowired
private RealmDAO realmDAO;
@Test
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java
index d0a6d0c..22e7494 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java
@@ -36,9 +36,10 @@ import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
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.GroupCond;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
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.SubjectCond;
import org.apache.syncope.core.persistence.api.entity.group.Group;
@@ -65,14 +66,16 @@ public class SubjectSearchTest extends AbstractTest {
User user = userDAO.find(1L);
assertNotNull(user);
- MembershipCond membershipCond = new MembershipCond();
- membershipCond.setGroupId(5L);
+ GroupCond groupCond = new GroupCond();
+ groupCond.setGroupKey(5L);
+ assertFalse(searchDAO.matches(user, SearchCond.getLeafCond(groupCond), SubjectType.USER));
- assertFalse(searchDAO.matches(user, SearchCond.getLeafCond(membershipCond), SubjectType.USER));
+ groupCond.setGroupKey(1L);
+ assertTrue(searchDAO.matches(user, SearchCond.getLeafCond(groupCond), SubjectType.USER));
- membershipCond.setGroupId(1L);
-
- assertTrue(searchDAO.matches(user, SearchCond.getLeafCond(membershipCond), SubjectType.USER));
+ RoleCond roleCond = new RoleCond();
+ roleCond.setRoleKey(3L);
+ assertTrue(searchDAO.matches(user, SearchCond.getLeafCond(roleCond), SubjectType.USER));
}
@Test
@@ -93,15 +96,15 @@ public class SubjectSearchTest extends AbstractTest {
fullnameLeafCond.setSchema("fullname");
fullnameLeafCond.setExpression("%o%");
- MembershipCond membershipCond = new MembershipCond();
- membershipCond.setGroupId(1L);
+ GroupCond groupCond = new GroupCond();
+ groupCond.setGroupKey(1L);
AttributeCond loginDateCond = new AttributeCond(AttributeCond.Type.EQ);
loginDateCond.setSchema("loginDate");
loginDateCond.setExpression("2009-05-26");
SearchCond subCond = SearchCond.getAndCond(SearchCond.getLeafCond(fullnameLeafCond), SearchCond.getLeafCond(
- membershipCond));
+ groupCond));
assertTrue(subCond.isValid());
@@ -157,15 +160,15 @@ public class SubjectSearchTest extends AbstractTest {
fullnameLeafCond.setSchema("fullname");
fullnameLeafCond.setExpression("%o%");
- MembershipCond membershipCond = new MembershipCond();
- membershipCond.setGroupId(1L);
+ GroupCond groupCond = new GroupCond();
+ groupCond.setGroupKey(1L);
AttributeCond loginDateCond = new AttributeCond(AttributeCond.Type.EQ);
loginDateCond.setSchema("loginDate");
loginDateCond.setExpression("2009-05-26");
SearchCond subCond = SearchCond.getAndCond(
- SearchCond.getLeafCond(fullnameLeafCond), SearchCond.getLeafCond(membershipCond));
+ SearchCond.getLeafCond(fullnameLeafCond), SearchCond.getLeafCond(groupCond));
assertTrue(subCond.isValid());
@@ -187,25 +190,36 @@ public class SubjectSearchTest extends AbstractTest {
}
@Test
- public void searchByMembership() {
- MembershipCond membershipCond = new MembershipCond();
- membershipCond.setGroupId(1L);
+ public void searchByGroup() {
+ GroupCond groupCond = new GroupCond();
+ groupCond.setGroupKey(1L);
List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
- SearchCond.getLeafCond(membershipCond), SubjectType.USER);
+ SearchCond.getLeafCond(groupCond), SubjectType.USER);
assertNotNull(users);
assertEquals(2, users.size());
- membershipCond = new MembershipCond();
- membershipCond.setGroupId(5L);
+ groupCond = new GroupCond();
+ groupCond.setGroupKey(5L);
users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
- SearchCond.getNotLeafCond(membershipCond), SubjectType.USER);
+ SearchCond.getNotLeafCond(groupCond), SubjectType.USER);
assertNotNull(users);
assertEquals(5, users.size());
}
@Test
+ public void searchByRole() {
+ RoleCond roleCond = new RoleCond();
+ roleCond.setRoleKey(3L);
+
+ List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+ SearchCond.getLeafCond(roleCond), SubjectType.USER);
+ assertNotNull(users);
+ assertEquals(1, users.size());
+ }
+
+ @Test
public void searchByIsNull() {
AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.ISNULL);
coolLeafCond.setSchema("cool");
@@ -233,11 +247,9 @@ public class SubjectSearchTest extends AbstractTest {
ws1.setResourceName("ws-target-resource-list-mappings-2");
SearchCond searchCondition = SearchCond.getAndCond(SearchCond.getNotLeafCond(ws2), SearchCond.getLeafCond(ws1));
-
assertTrue(searchCondition.isValid());
List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, SubjectType.USER);
-
assertNotNull(users);
assertEquals(1, users.size());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
index 251296a..d6d99ce 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
@@ -24,19 +24,32 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.common.lib.types.AttributableType;
import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
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.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.persistence.jpa.entity.JPADynGroupMembership;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
@@ -45,12 +58,18 @@ import org.springframework.transaction.annotation.Transactional;
public class GroupTest extends AbstractTest {
@Autowired
+ private EntityManager entityManager;
+
+ @Autowired
private UserDAO userDAO;
@Autowired
private GroupDAO groupDAO;
@Autowired
+ private RealmDAO realmDAO;
+
+ @Autowired
private PlainSchemaDAO plainSchemaDAO;
@Autowired
@@ -68,6 +87,7 @@ public class GroupTest extends AbstractTest {
assertNotNull("did not find expected user", user);
Group group = entityFactory.newEntity(Group.class);
+ group.setRealm(realmDAO.getRoot());
group.setName("error");
group.setUserOwner(user);
group.setGroupOwner(root);
@@ -98,9 +118,103 @@ public class GroupTest extends AbstractTest {
groupDAO.flush();
assertNull(groupDAO.find(2L));
- assertEquals(userDAO.find(2L).getGroups().size(), 2);
+ assertEquals(userDAO.findAllGroups(userDAO.find(2L)).size(), 2);
assertNull(plainAttrDAO.find(700L, GPlainAttr.class));
assertNull(plainAttrValueDAO.find(41L, GPlainAttrValue.class));
assertNotNull(plainSchemaDAO.find("icon", GPlainSchema.class));
}
+
+ /**
+ * Static copy of {@link org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO} method with same signature:
+ * required for avoiding creating of a new transaction - good for general use case but bad for the way how
+ * this test class is architected.
+ */
+ private Collection<Group> findDynGroupMemberships(final User user) {
+ TypedQuery<Group> query = entityManager.createQuery(
+ "SELECT e.group FROM " + JPADynGroupMembership.class.getSimpleName()
+ + " e WHERE :user MEMBER OF e.users", Group.class);
+ query.setParameter("user", user);
+
+ return query.getResultList();
+ }
+
+ @Test
+ public void dynMembership() {
+ // 0. create user matching the condition below
+ User user = entityFactory.newEntity(User.class);
+ user.setUsername("username");
+ user.setRealm(realmDAO.find("/even/two"));
+
+ UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
+ attribute.setSchema(plainSchemaDAO.find("cool", UPlainSchema.class));
+ attribute.setOwner(user);
+ attribute.addValue("true", attrUtilsFactory.getInstance(AttributableType.USER));
+ user.addPlainAttr(attribute);
+
+ user = userDAO.save(user);
+ Long newUserKey = user.getKey();
+ assertNotNull(newUserKey);
+
+ // 1. create group with dynamic membership
+ Group group = entityFactory.newEntity(Group.class);
+ group.setRealm(realmDAO.getRoot());
+ group.setName("new");
+
+ DynGroupMembership dynMembership = entityFactory.newEntity(DynGroupMembership.class);
+ dynMembership.setFIQLCond("cool==true");
+ dynMembership.setGroup(group);
+
+ group.setDynMembership(dynMembership);
+
+ Group actual = groupDAO.save(group);
+ assertNotNull(actual);
+
+ groupDAO.flush();
+
+ // 2. verify that dynamic membership is there
+ actual = groupDAO.find(actual.getKey());
+ assertNotNull(actual);
+ assertNotNull(actual.getDynMembership());
+ assertNotNull(actual.getDynMembership().getKey());
+ assertEquals(actual, actual.getDynMembership().getGroup());
+
+ // 3. verify that expected users have the created group dynamically assigned
+ assertEquals(2, actual.getDynMembership().getUsers().size());
+ assertEquals(new HashSet<>(Arrays.asList(4L, newUserKey)),
+ CollectionUtils.collect(actual.getDynMembership().getUsers(), new Transformer<User, Long>() {
+
+ @Override
+ public Long transform(final User input) {
+ return input.getKey();
+ }
+ }, new HashSet<Long>()));
+
+ user = userDAO.find(4L);
+ assertNotNull(user);
+ Collection<Group> dynGroupMemberships = findDynGroupMemberships(user);
+ assertEquals(1, dynGroupMemberships.size());
+ assertTrue(dynGroupMemberships.contains(actual.getDynMembership().getGroup()));
+
+ // 4. delete the new user and verify that dynamic membership was updated
+ userDAO.delete(newUserKey);
+
+ userDAO.flush();
+
+ actual = groupDAO.find(actual.getKey());
+ assertEquals(1, actual.getDynMembership().getUsers().size());
+ assertEquals(4L, actual.getDynMembership().getUsers().get(0).getKey(), 0);
+
+ // 5. delete group and verify that dynamic membership was also removed
+ Long dynMembershipKey = actual.getDynMembership().getKey();
+
+ groupDAO.delete(actual);
+
+ groupDAO.flush();
+
+ assertNull(entityManager.find(JPADynGroupMembership.class, dynMembershipKey));
+
+ dynGroupMemberships = findDynGroupMemberships(user);
+ assertTrue(dynGroupMemberships.isEmpty());
+ }
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ResourceTest.java
index d9e1864..868f104 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ResourceTest.java
@@ -225,7 +225,7 @@ public class ResourceTest extends AbstractTest {
for (Long id : userIds) {
User actualUser = userDAO.find(id);
assertNotNull(actualUser);
- for (ExternalResource res : actualUser.getResources()) {
+ for (ExternalResource res : userDAO.findAllResources(actualUser)) {
assertFalse(res.getKey().equalsIgnoreCase(resource.getKey()));
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java
new file mode 100644
index 0000000..52e3451
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.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.persistence.jpa.relationship;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.Entitlement;
+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.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.DynRoleMembership;
+import org.apache.syncope.core.persistence.api.entity.Role;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.persistence.jpa.entity.JPADynRoleMembership;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class RoleTest extends AbstractTest {
+
+ @Autowired
+ private EntityManager entityManager;
+
+ @Autowired
+ private RoleDAO roleDAO;
+
+ @Autowired
+ private RealmDAO realmDAO;
+
+ @Autowired
+ private PlainSchemaDAO plainSchemaDAO;
+
+ @Autowired
+ private UserDAO userDAO;
+
+ /**
+ * Static copy of {@link org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO} method with same signature:
+ * required for avoiding creating new transaction - good for general use case but bad for the way how
+ * this test class is architected.
+ */
+ private Collection<Role> findDynRoleMemberships(final User user) {
+ 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);
+
+ return query.getResultList();
+ }
+
+ @Test
+ public void dynMembership() {
+ // 0. create user matching the condition below
+ User user = entityFactory.newEntity(User.class);
+ user.setUsername("username");
+ user.setRealm(realmDAO.find("/even/two"));
+
+ UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
+ attribute.setSchema(plainSchemaDAO.find("cool", UPlainSchema.class));
+ attribute.setOwner(user);
+ attribute.addValue("true", attrUtilsFactory.getInstance(AttributableType.USER));
+ user.addPlainAttr(attribute);
+
+ user = userDAO.save(user);
+ Long newUserKey = user.getKey();
+ assertNotNull(newUserKey);
+
+ // 1. create role with dynamic membership
+ Role role = entityFactory.newEntity(Role.class);
+ role.setName("new");
+ role.addRealm(realmDAO.getRoot());
+ role.addRealm(realmDAO.find("/even/two"));
+ role.getEntitlements().add(Entitlement.LOG_LIST);
+ role.getEntitlements().add(Entitlement.LOG_SET_LEVEL);
+
+ DynRoleMembership dynMembership = entityFactory.newEntity(DynRoleMembership.class);
+ dynMembership.setFIQLCond("cool==true");
+ dynMembership.setRole(role);
+
+ role.setDynMembership(dynMembership);
+
+ Role actual = roleDAO.save(role);
+ assertNotNull(actual);
+
+ roleDAO.flush();
+
+ // 2. verify that dynamic membership is there
+ actual = roleDAO.find(actual.getKey());
+ assertNotNull(actual);
+ assertNotNull(actual.getDynMembership());
+ assertNotNull(actual.getDynMembership().getKey());
+ assertEquals(actual, actual.getDynMembership().getRole());
+
+ // 3. verify that expected users have the created role dynamically assigned
+ assertEquals(2, actual.getDynMembership().getUsers().size());
+ assertEquals(new HashSet<>(Arrays.asList(4L, newUserKey)),
+ CollectionUtils.collect(actual.getDynMembership().getUsers(), new Transformer<User, Long>() {
+
+ @Override
+ public Long transform(final User input) {
+ return input.getKey();
+ }
+ }, new HashSet<Long>()));
+
+ user = userDAO.find(4L);
+ assertNotNull(user);
+ Collection<Role> dynRoleMemberships = findDynRoleMemberships(user);
+ assertEquals(1, dynRoleMemberships.size());
+ assertTrue(dynRoleMemberships.contains(actual.getDynMembership().getRole()));
+
+ // 4. delete the new user and verify that dynamic membership was updated
+ userDAO.delete(newUserKey);
+
+ userDAO.flush();
+
+ actual = roleDAO.find(actual.getKey());
+ assertEquals(1, actual.getDynMembership().getUsers().size());
+ assertEquals(4L, actual.getDynMembership().getUsers().get(0).getKey(), 0);
+
+ // 5. delete role and verify that dynamic membership was also removed
+ Long dynMembershipKey = actual.getDynMembership().getKey();
+
+ roleDAO.delete(actual);
+
+ roleDAO.flush();
+
+ assertNull(entityManager.find(JPADynRoleMembership.class, dynMembershipKey));
+
+ dynRoleMemberships = findDynRoleMemberships(user);
+ assertTrue(dynRoleMemberships.isEmpty());
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java
index d3eb0be..025d7cc 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java
@@ -26,11 +26,17 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.Entitlement;
import org.apache.syncope.common.lib.types.SubjectType;
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.RoleDAO;
import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+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.entity.DynRoleMembership;
+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.User;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
@@ -47,6 +53,12 @@ public class SubjectSearchTest extends AbstractTest {
@Autowired
private SubjectSearchDAO searchDAO;
+ @Autowired
+ private RealmDAO realmDAO;
+
+ @Autowired
+ private RoleDAO roleDAO;
+
@Test
public void issueSYNCOPE95() {
Set<Group> groups = new HashSet<>(groupDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100));
@@ -55,18 +67,49 @@ public class SubjectSearchTest extends AbstractTest {
}
groupDAO.flush();
- final AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.EQ);
+ AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.EQ);
coolLeafCond.setSchema("cool");
coolLeafCond.setExpression("true");
- final SearchCond cond = SearchCond.getLeafCond(coolLeafCond);
+ SearchCond cond = SearchCond.getLeafCond(coolLeafCond);
assertTrue(cond.isValid());
- final List<User> users =
- searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, SubjectType.USER);
+ List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, SubjectType.USER);
assertNotNull(users);
assertEquals(1, users.size());
- assertEquals(Long.valueOf(4L), users.get(0).getKey());
+ assertEquals(4L, users.get(0).getKey(), 0);
+ }
+
+ @Test
+ public void searchByDynMembership() {
+ // 1. create role with dynamic membership
+ Role role = entityFactory.newEntity(Role.class);
+ role.setName("new");
+ role.addRealm(realmDAO.getRoot());
+ role.addRealm(realmDAO.find("/even/two"));
+ role.getEntitlements().add(Entitlement.LOG_LIST);
+ role.getEntitlements().add(Entitlement.LOG_SET_LEVEL);
+
+ DynRoleMembership dynMembership = entityFactory.newEntity(DynRoleMembership.class);
+ dynMembership.setFIQLCond("cool==true");
+ dynMembership.setRole(role);
+
+ role.setDynMembership(dynMembership);
+
+ role = roleDAO.save(role);
+ assertNotNull(role);
+
+ roleDAO.flush();
+
+ // 2. search user by this dynamic role
+ RoleCond roleCond = new RoleCond();
+ roleCond.setRoleKey(role.getKey());
+
+ List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+ SearchCond.getLeafCond(roleCond), SubjectType.USER);
+ assertNotNull(users);
+ assertEquals(1, users.size());
+ assertEquals(4L, users.get(0).getKey(), 0);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/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 ce28830..c1eff8c 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
@@ -230,7 +230,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
protected List<PropagationStatus> propagateStatus(final User user, final StatusMod statusMod) {
Collection<String> noPropResourceNames =
- CollectionUtils.removeAll(user.getResourceNames(), statusMod.getResourceNames());
+ CollectionUtils.removeAll(userDAO.findAllResourceNames(user), statusMod.getResourceNames());
List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
user, statusMod.getType() != StatusMod.ModType.SUSPEND, noPropResourceNames);
@@ -269,11 +269,11 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
public List<PropagationStatus> deprovision(final Long userKey, final Collection<String> resources) {
final User user = userDAO.authFetch(userKey);
- Collection<String> noPropResourceNames = CollectionUtils.removeAll(user.getResourceNames(), resources);
-
- final List<PropagationTask> tasks =
- propagationManager.getUserDeleteTasks(userKey, new HashSet<>(resources), noPropResourceNames);
- final PropagationReporter propagationReporter =
+ List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(
+ userKey,
+ new HashSet<>(resources),
+ CollectionUtils.removeAll(userDAO.findAllResourceNames(user), resources));
+ PropagationReporter propagationReporter =
ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
try {
taskExecutor.execute(tasks, propagationReporter);
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
index 6354041..14c00c7 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
@@ -51,6 +51,7 @@ import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
+import org.apache.syncope.core.persistence.api.entity.user.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -132,11 +133,13 @@ public class VirAttrHandler {
PropagationByResource propByRes = new PropagationByResource();
- final Set<ExternalResource> externalResources = new HashSet<>();
- if (attributable instanceof Subject) {
- externalResources.addAll(((Subject<?, ?, ?>) attributable).getResources());
+ Set<ExternalResource> externalResources = new HashSet<>();
+ if (attributable instanceof User) {
+ externalResources.addAll(userDAO.findAllResources((User) attributable));
+ } else if (attributable instanceof Group) {
+ externalResources.addAll(((Group) attributable).getResources());
} else if (attributable instanceof Membership) {
- externalResources.addAll(((Membership) attributable).getUser().getResources());
+ externalResources.addAll(userDAO.findAllResources(((Membership) attributable).getUser()));
externalResources.addAll(((Membership) attributable).getGroup().getResources());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
index 6264379..b94ffa2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
@@ -91,6 +91,7 @@ import org.apache.syncope.core.misc.jexl.JexlUtils;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
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.user.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -240,7 +241,7 @@ abstract class AbstractAttributableDataBinder {
Collection<MappingItem> mappings = MappingUtils.getMatchingMappingItems(
attrUtils.getMappingItems(resource, MappingPurpose.PROPAGATION), intAttrName, intMappingType);
for (Iterator<MappingItem> itor = mappings.iterator(); itor.hasNext() && !result;) {
- final MappingItem mapping = itor.next();
+ MappingItem mapping = itor.next();
result |= JexlUtils.evaluateMandatoryCondition(mapping.getMandatoryCondition(), attributable);
}
@@ -252,15 +253,17 @@ abstract class AbstractAttributableDataBinder {
boolean result = false;
- if (attributable instanceof Subject) {
- for (Iterator<? extends ExternalResource> itor =
- ((Subject<?, ?, ?>) attributable).getResources().iterator(); itor.hasNext() && !result;) {
-
- final ExternalResource resource = itor.next();
- if (resource.isEnforceMandatoryCondition()) {
- result |= evaluateMandatoryCondition(
- attrUtils, resource, attributable, intAttrName, intMappingType);
- }
+ Iterable<? extends ExternalResource> iterable = attributable instanceof User
+ ? userDAO.findAllResources((User) attributable)
+ : attributable instanceof Group
+ ? ((Group) attributable).getResources()
+ : Collections.<ExternalResource>emptySet();
+
+ for (Iterator<? extends ExternalResource> itor = iterable.iterator(); itor.hasNext() && !result;) {
+ ExternalResource resource = itor.next();
+ if (resource.isEnforceMandatoryCondition()) {
+ result |= evaluateMandatoryCondition(
+ attrUtils, resource, attributable, intAttrName, intMappingType);
}
}
@@ -427,11 +430,13 @@ abstract class AbstractAttributableDataBinder {
LOG.debug("Resources to be added:\n{}", propByRes);
}
- final Set<ExternalResource> externalResources = new HashSet<>();
- if (attributable instanceof Subject) {
- externalResources.addAll(((Subject<?, ?, ?>) attributable).getResources());
+ Set<ExternalResource> externalResources = new HashSet<>();
+ if (attributable instanceof User) {
+ externalResources.addAll(userDAO.findAllResources((User) attributable));
+ } else if (attributable instanceof Group) {
+ externalResources.addAll(((Group) attributable).getResources());
} else if (attributable instanceof Membership) {
- externalResources.addAll(((Membership) attributable).getUser().getResources());
+ externalResources.addAll(userDAO.findAllResources(((Membership) attributable).getUser()));
externalResources.addAll(((Membership) attributable).getGroup().getResources());
}
@@ -777,7 +782,10 @@ abstract class AbstractAttributableDataBinder {
protected Map<String, String> getAccountIds(final Subject<?, ?, ?> subject, final AttributableType type) {
Map<String, String> accountIds = new HashMap<>();
- for (ExternalResource resource : subject.getResources()) {
+ Iterable<? extends ExternalResource> iterable = subject instanceof User
+ ? userDAO.findAllResources((User) subject)
+ : ((Group) subject).getResources();
+ for (ExternalResource resource : iterable) {
if ((type == AttributableType.USER && resource.getUmapping() != null)
|| (type == AttributableType.GROUP && resource.getGmapping() != null)) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/22839bf3/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 6cadc9d..efe7771 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
@@ -18,8 +18,6 @@
*/
package org.apache.syncope.core.provisioning.java.data;
-import static org.apache.syncope.core.provisioning.java.data.AbstractAttributableDataBinder.LOG;
-
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -49,6 +47,9 @@ 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.ConnObjectUtils;
+import org.apache.syncope.core.misc.search.SearchCondConverter;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -89,6 +90,25 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
}
}
+ private void setDynMembership(final Group group, final String dynMembershipFIQL) {
+ SearchCond dynMembershipCond = SearchCondConverter.convert(dynMembershipFIQL);
+ if (!dynMembershipCond.isValid()) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression);
+ sce.getElements().add(dynMembershipFIQL);
+ throw sce;
+ }
+
+ DynGroupMembership dynMembership;
+ if (group.getDynMembership() == null) {
+ dynMembership = entityFactory.newEntity(DynGroupMembership.class);
+ dynMembership.setGroup(group);
+ group.setDynMembership(dynMembership);
+ } else {
+ dynMembership = group.getDynMembership();
+ }
+ dynMembership.setFIQLCond(dynMembershipFIQL);
+ }
+
@Override
public Group create(final Group group, final GroupTO groupTO) {
SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
@@ -132,6 +152,10 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
}
}
+ if (groupTO.getDynMembershipCond() != null) {
+ setDynMembership(group, groupTO.getDynMembershipCond());
+ }
+
return group;
}
@@ -202,6 +226,18 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
}
}
+ // dynamic membership
+ if (group.getDynMembership() != null && groupMod.getDynMembershipCond() == null) {
+ group.setDynMembership(null);
+ } else if (group.getDynMembership() == null && groupMod.getDynMembershipCond() != null) {
+ setDynMembership(group, groupMod.getDynMembershipCond());
+ } else if (group.getDynMembership() != null && groupMod.getDynMembershipCond() != null
+ && !group.getDynMembership().getFIQLCond().equals(groupMod.getDynMembershipCond())) {
+
+ group.getDynMembership().getUsers().clear();
+ setDynMembership(group, groupMod.getDynMembershipCond());
+ }
+
return propByRes;
}
@@ -251,6 +287,10 @@ public class GroupDataBinderImpl extends AbstractAttributableDataBinder implemen
groupTO.getMVirAttrTemplates().add(template.getSchema().getKey());
}
+ if (group.getDynMembership() != null) {
+ groupTO.setDynMembershipCond(group.getDynMembership().getFIQLCond());
+ }
+
return groupTO;
}