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/11/25 12:26:05 UTC

[2/5] syncope git commit: [SYNCOPE-119] Added search options and checks to match assignable conditions, for usage with memberships and relationships

http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index a8ebe0c..639f1b2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -41,8 +41,11 @@ import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.core.misc.spring.BeanUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.RelationshipType;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
@@ -131,52 +134,77 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
 
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
-        // relationships
-        for (RelationshipTO relationshipTO : anyObjectTO.getRelationships()) {
-            AnyObject otherEnd = anyObjectDAO.find(relationshipTO.getRightKey());
-
-            if (otherEnd == null) {
-                LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
-            } else {
-                RelationshipType relationshipType = relationshipTypeDAO.find(relationshipTO.getType());
-                ARelationship relationship = null;
-                if (anyObject.getKey() != null) {
-                    relationship = anyObject.getRelationship(relationshipType, anyObject.getKey());
-                }
-                if (relationship == null) {
-                    relationship = entityFactory.newEntity(ARelationship.class);
+        // realm
+        Realm realm = realmDAO.find(anyObjectTO.getRealm());
+        if (realm == null) {
+            SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+            noRealm.getElements().add("Invalid or null realm specified: " + anyObjectTO.getRealm());
+            scce.addException(noRealm);
+        }
+        anyObject.setRealm(realm);
+
+        if (anyObject.getRealm() != null) {
+            AssignableCond assignableCond = new AssignableCond();
+            assignableCond.setRealmFullPath(anyObject.getRealm().getFullPath());
+
+            // relationships
+            List<AnyObject> assignableAnyObjects =
+                    searchDAO.search(SearchCond.getLeafCond(assignableCond), AnyTypeKind.ANY_OBJECT);
+
+            for (RelationshipTO relationshipTO : anyObjectTO.getRelationships()) {
+                AnyObject otherEnd = anyObjectDAO.find(relationshipTO.getRightKey());
+                if (otherEnd == null) {
+                    LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
+                } else if (assignableAnyObjects.contains(otherEnd)) {
+                    RelationshipType relationshipType = relationshipTypeDAO.find(relationshipTO.getType());
+                    ARelationship relationship = entityFactory.newEntity(ARelationship.class);
                     relationship.setType(relationshipType);
                     relationship.setRightEnd(anyObject);
                     relationship.setLeftEnd(anyObject);
 
                     anyObject.add(relationship);
+                } else {
+                    LOG.error("{} cannot be assigned to {}", otherEnd, anyObject);
+
+                    SyncopeClientException unassignabled =
+                            SyncopeClientException.build(ClientExceptionType.InvalidRelationship);
+                    unassignabled.getElements().add("Cannot be assigned: " + otherEnd);
+                    scce.addException(unassignabled);
                 }
             }
-        }
 
-        // memberships
-        for (MembershipTO membershipTO : anyObjectTO.getMemberships()) {
-            Group group = groupDAO.find(membershipTO.getRightKey());
-
-            if (group == null) {
-                LOG.debug("Ignoring invalid group " + membershipTO.getGroupName());
-            } else {
-                AMembership membership = null;
-                if (anyObject.getKey() != null) {
-                    membership = anyObject.getMembership(group.getKey());
-                }
-                if (membership == null) {
-                    membership = entityFactory.newEntity(AMembership.class);
+            // memberships
+            List<Group> assignableGroups =
+                    searchDAO.search(SearchCond.getLeafCond(assignableCond), AnyTypeKind.GROUP);
+
+            for (MembershipTO membershipTO : anyObjectTO.getMemberships()) {
+                Group group = groupDAO.find(membershipTO.getRightKey());
+                if (group == null) {
+                    LOG.debug("Ignoring invalid group " + membershipTO.getGroupName());
+                } else if (assignableGroups.contains(group)) {
+                    AMembership membership = entityFactory.newEntity(AMembership.class);
                     membership.setRightEnd(group);
                     membership.setLeftEnd(anyObject);
 
                     anyObject.add(membership);
+                } else {
+                    LOG.error("{} cannot be assigned to {}", group, anyObject);
+
+                    SyncopeClientException unassignabled =
+                            SyncopeClientException.build(ClientExceptionType.InvalidMembership);
+                    unassignabled.getElements().add("Cannot be assigned: " + group);
+                    scce.addException(unassignabled);
                 }
             }
         }
 
-        // realm, attributes, derived attributes, virtual attributes and resources
+        // attributes, derived attributes, virtual attributes and resources
         fill(anyObject, anyObjectTO, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT), scce);
+
+        // Throw composite exception if there is at least one element set in the composing exceptions
+        if (scce.hasExceptions()) {
+            throw scce;
+        }
     }
 
     @Override
@@ -200,6 +228,9 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
         Set<String> toBeProvisioned = new HashSet<>();
 
         // relationships
+        List<AnyObject> assignableAnyObjects =
+                searchDAO.searchAssignable(anyObject.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT);
+
         for (RelationshipPatch patch : anyObjectPatch.getRelationships()) {
             if (patch.getRelationshipTO() != null) {
                 RelationshipType relationshipType = relationshipTypeDAO.find(patch.getRelationshipTO().getType());
@@ -214,8 +245,7 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
                     AnyObject otherEnd = anyObjectDAO.find(patch.getRelationshipTO().getRightKey());
                     if (otherEnd == null) {
                         LOG.debug("Ignoring invalid any object {}", patch.getRelationshipTO().getRightKey());
-                    } else {
-
+                    } else if (assignableAnyObjects.contains(otherEnd)) {
                         relationship = entityFactory.newEntity(ARelationship.class);
                         relationship.setType(relationshipType);
                         relationship.setRightEnd(otherEnd);
@@ -224,12 +254,22 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
                         anyObject.add(relationship);
 
                         toBeProvisioned.addAll(otherEnd.getResourceNames());
+                    } else {
+                        LOG.error("{} cannot be assigned to {}", otherEnd, anyObject);
+
+                        SyncopeClientException unassignabled =
+                                SyncopeClientException.build(ClientExceptionType.InvalidRelationship);
+                        unassignabled.getElements().add("Cannot be assigned: " + otherEnd);
+                        scce.addException(unassignabled);
                     }
                 }
             }
         }
 
         // memberships
+        List<Group> assignableGroups =
+                searchDAO.searchAssignable(anyObject.getRealm().getFullPath(), AnyTypeKind.GROUP);
+
         for (MembershipPatch patch : anyObjectPatch.getMemberships()) {
             if (patch.getMembershipTO() != null) {
                 AMembership membership = anyObject.getMembership(patch.getMembershipTO().getRightKey());
@@ -242,7 +282,7 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
                     Group group = groupDAO.find(patch.getMembershipTO().getRightKey());
                     if (group == null) {
                         LOG.debug("Ignoring invalid group {}", patch.getMembershipTO().getRightKey());
-                    } else {
+                    } else if (assignableGroups.contains(group)) {
                         membership = entityFactory.newEntity(AMembership.class);
                         membership.setRightEnd(group);
                         membership.setLeftEnd(anyObject);
@@ -250,6 +290,13 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
                         anyObject.add(membership);
 
                         toBeProvisioned.addAll(group.getResourceNames());
+                    } else {
+                        LOG.error("{} cannot be assigned to {}", group, anyObject);
+
+                        SyncopeClientException unassignabled =
+                                SyncopeClientException.build(ClientExceptionType.InvalidMembership);
+                        unassignabled.getElements().add("Cannot be assigned: " + group);
+                        scce.addException(unassignabled);
                     }
                 }
             }
@@ -278,6 +325,11 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
             }
         }
 
+        // Throw composite exception if there is at least one element set in the composing exceptions
+        if (scce.hasExceptions()) {
+            throw scce;
+        }
+
         return propByRes;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/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 9562ff7..c71fce5 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
@@ -44,6 +44,7 @@ import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
@@ -85,7 +86,7 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
     }
 
     @Override
-    public Group create(final Group group, final GroupTO groupTO) {
+    public void create(final Group group, final GroupTO groupTO) {
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
         // name
@@ -98,7 +99,16 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
             group.setName(groupTO.getName());
         }
 
-        // realm, attributes, derived attributes, virtual attributes and resources
+        // realm
+        Realm realm = realmDAO.find(groupTO.getRealm());
+        if (realm == null) {
+            SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+            noRealm.getElements().add("Invalid or null realm specified: " + groupTO.getRealm());
+            scce.addException(noRealm);
+        }
+        group.setRealm(realm);
+
+        // attributes, derived attributes, virtual attributes and resources
         fill(group, groupTO, anyUtilsFactory.getInstance(AnyTypeKind.GROUP), scce);
 
         // owner
@@ -153,7 +163,10 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
             }
         }
 
-        return group;
+        // Throw composite exception if there is at least one element set in the composing exceptions
+        if (scce.hasExceptions()) {
+            throw scce;
+        }
     }
 
     @Override
@@ -268,6 +281,11 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
             }
         }
 
+        // Throw composite exception if there is at least one element set in the composing exceptions
+        if (scce.hasExceptions()) {
+            throw scce;
+        }
+
         return propByRes;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index ca3448c..22d690a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -57,7 +57,10 @@ import org.apache.syncope.core.misc.security.Encryptor;
 import org.apache.syncope.core.misc.spring.BeanUtils;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.RelationshipType;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
@@ -173,50 +176,71 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
             }
         }
 
-        // relationships
-        for (RelationshipTO relationshipTO : userTO.getRelationships()) {
-            AnyObject anyObject = anyObjectDAO.find(relationshipTO.getRightKey());
-            if (anyObject == null) {
-                LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
-            } else {
-                RelationshipType relationshipType = relationshipTypeDAO.find(relationshipTO.getType());
-                URelationship relationship = null;
-                if (user.getKey() != null) {
-                    relationship = user.getRelationship(relationshipType, anyObject.getKey());
-                }
-                if (relationship == null) {
-                    relationship = entityFactory.newEntity(URelationship.class);
+        // realm
+        Realm realm = realmDAO.find(userTO.getRealm());
+        if (realm == null) {
+            SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+            noRealm.getElements().add("Invalid or null realm specified: " + userTO.getRealm());
+            scce.addException(noRealm);
+        }
+        user.setRealm(realm);
+
+        if (user.getRealm() != null) {
+            AssignableCond assignableCond = new AssignableCond();
+            assignableCond.setRealmFullPath(user.getRealm().getFullPath());
+
+            // relationships
+            List<AnyObject> assignableAnyObjects =
+                    searchDAO.search(SearchCond.getLeafCond(assignableCond), AnyTypeKind.ANY_OBJECT);
+
+            for (RelationshipTO relationshipTO : userTO.getRelationships()) {
+                AnyObject otherEnd = anyObjectDAO.find(relationshipTO.getRightKey());
+                if (otherEnd == null) {
+                    LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
+                } else if (assignableAnyObjects.contains(otherEnd)) {
+                    RelationshipType relationshipType = relationshipTypeDAO.find(relationshipTO.getType());
+                    URelationship relationship = entityFactory.newEntity(URelationship.class);
                     relationship.setType(relationshipType);
-                    relationship.setRightEnd(anyObject);
+                    relationship.setRightEnd(otherEnd);
                     relationship.setLeftEnd(user);
 
                     user.add(relationship);
+                } else {
+                    LOG.error("{} cannot be assigned to {}", otherEnd, user);
+
+                    SyncopeClientException unassignabled =
+                            SyncopeClientException.build(ClientExceptionType.InvalidRelationship);
+                    unassignabled.getElements().add("Cannot be assigned: " + otherEnd);
+                    scce.addException(unassignabled);
                 }
             }
-        }
-
-        // memberships
-        for (MembershipTO membershipTO : userTO.getMemberships()) {
-            Group group = groupDAO.find(membershipTO.getRightKey());
 
-            if (group == null) {
-                LOG.debug("Ignoring invalid group " + membershipTO.getGroupName());
-            } else {
-                UMembership membership = null;
-                if (user.getKey() != null) {
-                    membership = user.getMembership(group.getKey());
-                }
-                if (membership == null) {
-                    membership = entityFactory.newEntity(UMembership.class);
+            // memberships
+            List<Group> assignableGroups =
+                    searchDAO.search(SearchCond.getLeafCond(assignableCond), AnyTypeKind.GROUP);
+
+            for (MembershipTO membershipTO : userTO.getMemberships()) {
+                Group group = groupDAO.find(membershipTO.getRightKey());
+                if (group == null) {
+                    LOG.debug("Ignoring invalid group " + membershipTO.getGroupName());
+                } else if (assignableGroups.contains(group)) {
+                    UMembership membership = entityFactory.newEntity(UMembership.class);
                     membership.setRightEnd(group);
                     membership.setLeftEnd(user);
 
                     user.add(membership);
+                } else {
+                    LOG.error("{} cannot be assigned to {}", group, user);
+
+                    SyncopeClientException unassignabled =
+                            SyncopeClientException.build(ClientExceptionType.InvalidMembership);
+                    unassignabled.getElements().add("Cannot be assigned: " + group);
+                    scce.addException(unassignabled);
                 }
             }
         }
 
-        // realm, attributes, derived attributes, virtual attributes and resources
+        // attributes, derived attributes, virtual attributes and resources
         fill(user, userTO, anyUtilsFactory.getInstance(AnyTypeKind.USER), scce);
 
         // set password
@@ -239,6 +263,11 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
         user.setSecurityAnswer(userTO.getSecurityAnswer());
 
         user.setMustChangePassword(userTO.isMustChangePassword());
+
+        // Throw composite exception if there is at least one element set in the composing exceptions
+        if (scce.hasExceptions()) {
+            throw scce;
+        }
     }
 
     private boolean isPasswordMapped(final ExternalResource resource) {
@@ -341,6 +370,9 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
         Set<String> toBeProvisioned = new HashSet<>();
 
         // relationships
+        List<AnyObject> assignableAnyObjects =
+                searchDAO.searchAssignable(user.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT);
+
         for (RelationshipPatch patch : userPatch.getRelationships()) {
             if (patch.getRelationshipTO() != null) {
                 RelationshipType relationshipType = relationshipTypeDAO.find(patch.getRelationshipTO().getType());
@@ -355,7 +387,7 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
                     AnyObject otherEnd = anyObjectDAO.find(patch.getRelationshipTO().getRightKey());
                     if (otherEnd == null) {
                         LOG.debug("Ignoring invalid any object {}", patch.getRelationshipTO().getRightKey());
-                    } else {
+                    } else if (assignableAnyObjects.contains(otherEnd)) {
                         relationship = entityFactory.newEntity(URelationship.class);
                         relationship.setType(relationshipType);
                         relationship.setRightEnd(otherEnd);
@@ -364,12 +396,22 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
                         user.add(relationship);
 
                         toBeProvisioned.addAll(otherEnd.getResourceNames());
+                    } else {
+                        LOG.error("{} cannot be assigned to {}", otherEnd, user);
+
+                        SyncopeClientException unassignabled =
+                                SyncopeClientException.build(ClientExceptionType.InvalidRelationship);
+                        unassignabled.getElements().add("Cannot be assigned: " + otherEnd);
+                        scce.addException(unassignabled);
                     }
                 }
             }
         }
 
         // memberships
+        List<Group> assignableGroups =
+                searchDAO.searchAssignable(user.getRealm().getFullPath(), AnyTypeKind.GROUP);
+
         for (MembershipPatch patch : userPatch.getMemberships()) {
             if (patch.getMembershipTO() != null) {
                 UMembership membership = user.getMembership(patch.getMembershipTO().getRightKey());
@@ -382,7 +424,7 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
                     Group group = groupDAO.find(patch.getMembershipTO().getRightKey());
                     if (group == null) {
                         LOG.debug("Ignoring invalid group {}", patch.getMembershipTO().getRightKey());
-                    } else {
+                    } else if (assignableGroups.contains(group)) {
                         membership = entityFactory.newEntity(UMembership.class);
                         membership.setRightEnd(group);
                         membership.setLeftEnd(user);
@@ -403,6 +445,13 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
                                 }
                             }
                         }
+                    } else {
+                        LOG.error("{} cannot be assigned to {}", group, user);
+
+                        SyncopeClientException unassignabled =
+                                SyncopeClientException.build(ClientExceptionType.InvalidMembership);
+                        unassignabled.getElements().add("Cannot be assigned: " + group);
+                        scce.addException(unassignabled);
                     }
                 }
             }
@@ -429,6 +478,11 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
             }
         }
 
+        // Throw composite exception if there is at least one element set in the composing exceptions
+        if (scce.hasExceptions()) {
+            throw scce;
+        }
+
         return propByRes;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
index 0be3f0d..82d8647 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
@@ -62,7 +62,7 @@ public class AnyObjectServiceImpl extends AbstractAnyService<AnyObjectTO, AnyObj
         }
 
         AnySearchQuery searchQuery = new AnySearchQuery();
-        searchQuery.setFiql(new AnyObjectFiqlSearchConditionBuilder().type(type).query());
+        searchQuery.setFiql(new AnyObjectFiqlSearchConditionBuilder(type).query());
         searchQuery.setDetails(listQuery.isDetails());
         searchQuery.setOrderBy(listQuery.getOrderBy());
         searchQuery.setPage(listQuery.getPage());

http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
index c044187..192fa76 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
@@ -32,6 +32,7 @@ import org.apache.syncope.common.lib.patch.AnyObjectPatch;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.SchemaType;
@@ -68,6 +69,27 @@ public class AnyObjectITCase extends AbstractITCase {
     }
 
     @Test
+    public void createInvalidMembership() {
+        // 1. create anyObject in realm /odd and attempt to assign group 15, from realm /even => exception
+        AnyObjectTO anyObjectTO = getSampleTO("createInvalidMembership");
+        anyObjectTO.setRealm("/odd");
+        anyObjectTO.getMemberships().add(new MembershipTO.Builder().group(15L).build());
+
+        try {
+            createAnyObject(anyObjectTO);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidMembership, e.getType());
+        }
+
+        // 2. change anyObject's realm to /even/two, now it works
+        anyObjectTO.setRealm("/even/two");
+
+        anyObjectTO = createAnyObject(anyObjectTO).getAny();
+        assertTrue(anyObjectTO.getMembershipMap().containsKey(15L));
+    }
+
+    @Test
     public void delete() {
         try {
             anyObjectService.delete(0L);

http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
index 38624b9..d7b8796 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
@@ -88,14 +88,14 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void searchByGroupNameAndKey() {
-        PagedResult<GroupTO> matchingGroups = groupService.search(
+        PagedResult<GroupTO> groups = groupService.search(
                 new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().
+                fiql(SyncopeClient.getGroupSearchConditionBuilder().
                         is("name").equalTo("root").and("key").lessThan(2).query()).build());
-        assertNotNull(matchingGroups);
-        assertEquals(1, matchingGroups.getResult().size());
-        assertEquals("root", matchingGroups.getResult().iterator().next().getName());
-        assertEquals(1L, matchingGroups.getResult().iterator().next().getKey());
+        assertNotNull(groups);
+        assertEquals(1, groups.getResult().size());
+        assertEquals("root", groups.getResult().iterator().next().getName());
+        assertEquals(1L, groups.getResult().iterator().next().getKey());
     }
 
     @Test
@@ -225,21 +225,21 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void searchByBooleanAnyCond() {
-        PagedResult<GroupTO> matchingGroups = groupService.search(
+        PagedResult<GroupTO> groups = groupService.search(
                 new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getGroupSearchConditionBuilder().is("show").equalTo("true").query()).build());
-        assertNotNull(matchingGroups);
-        assertFalse(matchingGroups.getResult().isEmpty());
+        assertNotNull(groups);
+        assertFalse(groups.getResult().isEmpty());
     }
 
     @Test
     public void searchByRelationshipAnyCond() {
-        PagedResult<GroupTO> matchingGroups = groupService.search(
+        PagedResult<GroupTO> groups = groupService.search(
                 new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getGroupSearchConditionBuilder().is("userOwner").equalTo(5).query()).build());
-        assertNotNull(matchingGroups);
-        assertEquals(1, matchingGroups.getResult().size());
-        assertEquals(6L, matchingGroups.getResult().iterator().next().getKey());
+        assertNotNull(groups);
+        assertEquals(1, groups.getResult().size());
+        assertEquals(6L, groups.getResult().iterator().next().getKey());
     }
 
     @Test
@@ -259,7 +259,7 @@ public class SearchITCase extends AbstractITCase {
     public void searchByType() {
         PagedResult<AnyObjectTO> matching = anyObjectService.search(
                 new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("PRINTER").query()).build());
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").query()).build());
         assertNotNull(matching);
 
         assertFalse(matching.getResult().isEmpty());
@@ -269,13 +269,118 @@ public class SearchITCase extends AbstractITCase {
 
         matching = anyObjectService.search(
                 new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("UNEXISTING").query()).build());
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("UNEXISTING").query()).build());
         assertNotNull(matching);
 
         assertTrue(matching.getResult().isEmpty());
     }
 
     @Test
+    public void searchByRelationship() {
+        PagedResult<AnyObjectTO> anyObjects = anyObjectService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+                        inRelationships(2L).query()).
+                build());
+        assertNotNull(anyObjects);
+        assertTrue(CollectionUtils.exists(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
+
+            @Override
+            public boolean evaluate(final AnyObjectTO anyObject) {
+                return anyObject.getKey() == 1L;
+            }
+        }));
+
+        PagedResult<UserTO> users = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().inRelationships(1L).query()).
+                build());
+        assertNotNull(users);
+        assertTrue(CollectionUtils.exists(users.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO user) {
+                return user.getKey() == 4L;
+            }
+        }));
+    }
+
+    @Test
+    public void searchByRelationshipType() {
+        PagedResult<AnyObjectTO> anyObjects = anyObjectService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+                        inRelationshipTypes("neighborhood").query()).
+                build());
+        assertNotNull(anyObjects);
+        assertTrue(CollectionUtils.exists(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
+
+            @Override
+            public boolean evaluate(final AnyObjectTO anyObject) {
+                return anyObject.getKey() == 1L;
+            }
+        }));
+        assertTrue(CollectionUtils.exists(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
+
+            @Override
+            public boolean evaluate(final AnyObjectTO anyObject) {
+                return anyObject.getKey() == 2L;
+            }
+        }));
+
+        PagedResult<UserTO> users = userService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().inRelationshipTypes("neighborhood").query()).
+                build());
+        assertNotNull(users);
+        assertTrue(CollectionUtils.exists(users.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO user) {
+                return user.getKey() == 4L;
+            }
+        }));
+    }
+
+    @Test
+    public void assignable() {
+        PagedResult<GroupTO> groups = groupService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getGroupSearchConditionBuilder().
+                        isAssignable("/even/two").query()).
+                build());
+        assertNotNull(groups);
+        assertTrue(CollectionUtils.exists(groups.getResult(), new Predicate<GroupTO>() {
+
+            @Override
+            public boolean evaluate(final GroupTO group) {
+                return group.getKey() == 15L;
+            }
+        }));
+        assertFalse(CollectionUtils.exists(groups.getResult(), new Predicate<GroupTO>() {
+
+            @Override
+            public boolean evaluate(final GroupTO group) {
+                return group.getKey() == 16L;
+            }
+        }));
+
+        PagedResult<AnyObjectTO> anyObjects = anyObjectService.search(
+                new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+                        isAssignable("/odd").query()).
+                build());
+        assertNotNull(anyObjects);
+        assertFalse(CollectionUtils.exists(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
+
+            @Override
+            public boolean evaluate(final AnyObjectTO anyObject) {
+                return anyObject.getKey() == 3L;
+            }
+        }));
+    }
+
+    @Test
     public void orderBy() {
         PagedResult<UserTO> matchingUsers = userService.search(
                 new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).

http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
index 75631e7..cea4752 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
@@ -416,7 +416,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             // 3. unlink any existing printer and delete from Syncope (printer is now only on external resource)
             PagedResult<AnyObjectTO> matchingPrinters = anyObjectService.search(
                     new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("PRINTER").and().
+                    fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
                             is("location").equalTo("sync*").query()).build());
             assertTrue(matchingPrinters.getSize() > 0);
             for (AnyObjectTO printer : matchingPrinters.getResult()) {
@@ -435,7 +435,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             // hence PrefixMappingItemTransformer was applied during sync)
             matchingPrinters = anyObjectService.search(
                     new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
-                    fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("PRINTER").and().
+                    fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
                             is("location").equalTo("sync*").query()).build());
             assertTrue(matchingPrinters.getSize() > 0);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
index 54589c6..21adebb 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
@@ -445,7 +445,7 @@ public class UserITCase extends AbstractITCase {
 
     @Test
     public void createWithRequiredValueMissing() {
-        UserTO userTO = getSampleTO("a.b@c.it");
+        UserTO userTO = getUniqueSampleTO("a.b@c.it");
 
         AttrTO type = userTO.getPlainAttrMap().get("type");
         userTO.getPlainAttrs().remove(type);