syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ilgro...@apache.org
Subject [52/57] syncope git commit: [SYNCOPE-119] New security model implemented
Date Tue, 21 Apr 2015 09:34:21 GMT
http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
index ea1d197..76595d3 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
@@ -36,6 +36,7 @@ import javax.ws.rs.core.Response;
 import org.apache.cxf.jaxrs.model.wadl.Description;
 import org.apache.cxf.jaxrs.model.wadl.Descriptions;
 import org.apache.cxf.jaxrs.model.wadl.DocTarget;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
@@ -95,25 +96,31 @@ public interface UserService extends JAXRSService {
     /**
      * Returns a paged list of existing users.
      *
+     * @param realms realms under which users are defined
      * @return paged list of all existing users
      */
     @GET
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<UserTO> list();
+    PagedResult<UserTO> list(
+            @DefaultValue(SyncopeConstants.ROOT_REALM) @QueryParam("realm") List<String> realms);
 
     /**
      * Returns a paged list of existing users.
      *
+     * @param realms realms under which users are defined
      * @param orderBy list of ordering clauses, separated by comma
      * @return paged list of all existing users
      */
     @GET
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<UserTO> list(@QueryParam(PARAM_ORDERBY) String orderBy);
+    PagedResult<UserTO> list(
+            @DefaultValue(SyncopeConstants.ROOT_REALM) @QueryParam("realm") List<String> realms,
+            @QueryParam(PARAM_ORDERBY) String orderBy);
 
     /**
      * Returns a paged list of existing users matching page/size conditions.
      *
+     * @param realms realms under which users are defined
      * @param page result page number
      * @param size number of entries per page
      * @return paged list of existing users matching page/size conditions
@@ -121,12 +128,14 @@ public interface UserService extends JAXRSService {
     @GET
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     PagedResult<UserTO> list(
+            @DefaultValue(SyncopeConstants.ROOT_REALM) @QueryParam("realm") List<String> realms,
             @NotNull @Min(1) @QueryParam(PARAM_PAGE) @DefaultValue(DEFAULT_PARAM_PAGE) Integer page,
             @NotNull @Min(1) @QueryParam(PARAM_SIZE) @DefaultValue(DEFAULT_PARAM_SIZE) Integer size);
 
     /**
      * Returns a paged list of existing users matching page/size conditions.
      *
+     * @param realms realms under which users are defined
      * @param page result page number
      * @param size number of entries per page
      * @param orderBy list of ordering clauses, separated by comma
@@ -135,6 +144,7 @@ public interface UserService extends JAXRSService {
     @GET
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     PagedResult<UserTO> list(
+            @DefaultValue(SyncopeConstants.ROOT_REALM) @QueryParam("realm") List<String> realms,
             @NotNull @Min(1) @QueryParam(PARAM_PAGE) @DefaultValue(DEFAULT_PARAM_PAGE) Integer page,
             @NotNull @Min(1) @QueryParam(PARAM_SIZE) @DefaultValue(DEFAULT_PARAM_SIZE) Integer size,
             @QueryParam(PARAM_ORDERBY) String orderBy);
@@ -142,17 +152,21 @@ public interface UserService extends JAXRSService {
     /**
      * Returns a paged list of users matching the provided FIQL search condition.
      *
+     * @param realms realms under which users are defined
      * @param fiql FIQL search expression
      * @return paged list of users matching the provided FIQL search condition
      */
     @GET
     @Path("search")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<UserTO> search(@NotNull @QueryParam(PARAM_FIQL) String fiql);
+    PagedResult<UserTO> search(
+            @DefaultValue(SyncopeConstants.ROOT_REALM) @QueryParam("realm") List<String> realms,
+            @NotNull @QueryParam(PARAM_FIQL) String fiql);
 
     /**
      * Returns a paged list of users matching the provided FIQL search condition.
      *
+     * @param realms realms under which users are defined
      * @param fiql FIQL search expression
      * @param orderBy list of ordering clauses, separated by comma
      * @return paged list of users matching the provided FIQL search condition
@@ -160,11 +174,15 @@ public interface UserService extends JAXRSService {
     @GET
     @Path("search")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<UserTO> search(@NotNull @QueryParam(PARAM_FIQL) String fiql, @QueryParam(PARAM_ORDERBY) String orderBy);
+    PagedResult<UserTO> search(
+            @DefaultValue(SyncopeConstants.ROOT_REALM) @QueryParam("realm") List<String> realms,
+            @NotNull @QueryParam(PARAM_FIQL) String fiql,
+            @QueryParam(PARAM_ORDERBY) String orderBy);
 
     /**
      * Returns a paged list of users matching the provided FIQL search condition.
      *
+     * @param realms realms under which users are defined
      * @param fiql FIQL search expression
      * @param page result page number
      * @param size number of entries per page
@@ -173,13 +191,16 @@ public interface UserService extends JAXRSService {
     @GET
     @Path("search")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<UserTO> search(@QueryParam(PARAM_FIQL) String fiql,
+    PagedResult<UserTO> search(
+            @DefaultValue(SyncopeConstants.ROOT_REALM) @QueryParam("realm") List<String> realms,
+            @QueryParam(PARAM_FIQL) String fiql,
             @NotNull @Min(1) @QueryParam(PARAM_PAGE) @DefaultValue(DEFAULT_PARAM_PAGE) Integer page,
             @NotNull @Min(1) @QueryParam(PARAM_SIZE) @DefaultValue(DEFAULT_PARAM_SIZE) Integer size);
 
     /**
      * Returns a paged list of users matching the provided FIQL search condition.
      *
+     * @param realms realms under which users are defined
      * @param fiql FIQL search expression
      * @param page result page number
      * @param size number of entries per page
@@ -189,7 +210,9 @@ public interface UserService extends JAXRSService {
     @GET
     @Path("search")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<UserTO> search(@QueryParam(PARAM_FIQL) String fiql,
+    PagedResult<UserTO> search(
+            @DefaultValue(SyncopeConstants.ROOT_REALM) @QueryParam("realm") List<String> realms,
+            @QueryParam(PARAM_FIQL) String fiql,
             @NotNull @Min(1) @QueryParam(PARAM_PAGE) @DefaultValue(DEFAULT_PARAM_PAGE) Integer page,
             @NotNull @Min(1) @QueryParam(PARAM_SIZE) @DefaultValue(DEFAULT_PARAM_SIZE) Integer size,
             @QueryParam(PARAM_ORDERBY) String orderBy);
@@ -210,7 +233,8 @@ public interface UserService extends JAXRSService {
     @POST
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response create(@NotNull UserTO userTO,
+    Response create(
+            @NotNull UserTO userTO,
             @DefaultValue("true") @QueryParam("storePassword") boolean storePassword);
 
     /**
@@ -284,7 +308,8 @@ public interface UserService extends JAXRSService {
     @Path("{userKey}/bulkDeassociation/{type}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkDeassociation(@NotNull @PathParam("userKey") Long userKey,
+    Response bulkDeassociation(
+            @NotNull @PathParam("userKey") Long userKey,
             @NotNull @PathParam("type") ResourceDeassociationActionType type,
             @NotNull List<ResourceName> resourceNames);
 
@@ -303,7 +328,8 @@ public interface UserService extends JAXRSService {
     @Path("{userKey}/bulkAssociation/{type}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkAssociation(@NotNull @PathParam("userKey") Long userKey,
+    Response bulkAssociation(
+            @NotNull @PathParam("userKey") Long userKey,
             @NotNull @PathParam("type") ResourceAssociationActionType type,
             @NotNull ResourceAssociationMod associationMod);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractSubjectLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractSubjectLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractSubjectLogic.java
index a1a94b4..7bd099b 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractSubjectLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractSubjectLogic.java
@@ -18,26 +18,53 @@
  */
 package org.apache.syncope.core.logic;
 
+import java.util.Collection;
 import java.util.List;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
 import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.core.misc.RealmUtils;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 
 public abstract class AbstractSubjectLogic<T extends AbstractSubjectTO, V extends AbstractSubjectMod>
         extends AbstractResourceAssociator<T> {
 
+    protected Set<String> getEffectiveRealms(
+            final Set<String> allowedRealms, final Collection<String> requestedRealms) {
+
+        Set<String> effective = RealmUtils.normalize(requestedRealms);
+        CollectionUtils.filter(effective, new Predicate<String>() {
+
+            @Override
+            public boolean evaluate(final String requestedRealm) {
+                return CollectionUtils.exists(allowedRealms, new Predicate<String>() {
+
+                    @Override
+                    public boolean evaluate(final String allowedRealm) {
+                        return requestedRealm.startsWith(allowedRealm);
+                    }
+                });
+            }
+        });
+
+        return effective;
+    }
+
     public abstract T read(Long key);
 
-    public abstract int count();
+    public abstract int count(List<String> realms);
 
     public abstract T update(V attributableMod);
 
     public abstract T delete(Long key);
 
-    public abstract List<T> list(int page, int size, List<OrderByClause> orderBy);
+    public abstract List<T> list(int page, int size, List<OrderByClause> orderBy, List<String> realms);
 
-    public abstract List<T> search(SearchCond searchCondition, int page, int size, List<OrderByClause> orderBy);
+    public abstract List<T> search(
+            SearchCond searchCondition, int page, int size, List<OrderByClause> orderBy, List<String> realms);
 
-    public abstract int searchCount(SearchCond searchCondition);
+    public abstract int searchCount(SearchCond searchCondition, List<String> realms);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
index 4068d63..23c60cc 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ConnectorLogic.java
@@ -30,8 +30,6 @@ import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnBundleTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -204,28 +202,25 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
     @PreAuthorize("hasRole('CONNECTOR_READ')")
     @Transactional(readOnly = true)
     public List<String> getSchemaNames(final ConnInstanceTO connInstanceTO, final boolean includeSpecial) {
-        final ConnInstance connInstance = connInstanceDAO.find(connInstanceTO.getKey());
+        ConnInstance connInstance = connInstanceDAO.find(connInstanceTO.getKey());
         if (connInstance == null) {
             throw new NotFoundException("Connector '" + connInstanceTO.getKey() + "'");
         }
 
         // consider the possibility to receive overridden properties only
-        final Set<ConnConfProperty> conf = binder.mergeConnConfProperties(connInstanceTO.getConfiguration(),
-                connInstance.getConfiguration());
+        Set<ConnConfProperty> conf =
+                binder.mergeConnConfProperties(connInstanceTO.getConfiguration(), connInstance.getConfiguration());
 
         // We cannot use Spring bean because this method could be used during resource definition or modification:
         // bean couldn't exist or couldn't be updated.
         // This is the reason why we should take a "not mature" connector facade proxy to ask for schema names.
-        final List<String> result = new ArrayList<>(connFactory.createConnector(connInstance, conf).
-                getSchemaNames(includeSpecial));
-
-        return result;
+        return new ArrayList<>(connFactory.createConnector(connInstance, conf).getSchemaNames(includeSpecial));
     }
 
     @PreAuthorize("hasRole('CONNECTOR_READ')")
     @Transactional(readOnly = true)
     public List<String> getSupportedObjectClasses(final ConnInstanceTO connInstanceTO) {
-        final ConnInstance connInstance = connInstanceDAO.find(connInstanceTO.getKey());
+        ConnInstance connInstance = connInstanceDAO.find(connInstanceTO.getKey());
         if (connInstance == null) {
             throw new NotFoundException("Connector '" + connInstanceTO.getKey() + "'");
         }
@@ -251,7 +246,7 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
     @Transactional(readOnly = true)
     public List<ConnConfProperty> getConfigurationProperties(final Long connInstanceId) {
 
-        final ConnInstance connInstance = connInstanceDAO.find(connInstanceId);
+        ConnInstance connInstance = connInstanceDAO.find(connInstanceId);
         if (connInstance == null) {
             throw new NotFoundException("Connector '" + connInstanceId + "'");
         }
@@ -294,27 +289,6 @@ public class ConnectorLogic extends AbstractTransactionalLogic<ConnInstanceTO> {
         connFactory.load();
     }
 
-    @PreAuthorize("hasRole('CONNECTOR_DELETE') and #bulkAction.operation == #bulkAction.operation.DELETE")
-    public BulkActionResult bulk(final BulkAction bulkAction) {
-        BulkActionResult res = new BulkActionResult();
-
-        if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
-            for (String id : bulkAction.getTargets()) {
-                try {
-                    res.add(delete(Long.valueOf(id)).getKey(), BulkActionResult.Status.SUCCESS);
-                } catch (Exception e) {
-                    LOG.error("Error performing delete for connector {}", id, e);
-                    res.add(id, BulkActionResult.Status.FAILURE);
-                }
-            }
-        }
-
-        return res;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected ConnInstanceTO resolveReference(final Method method, final Object... args)
             throws UnresolvedReferenceException {

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/EntitlementLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/EntitlementLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/EntitlementLogic.java
deleted file mode 100644
index a5dc6a0..0000000
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/EntitlementLogic.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.logic;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.common.lib.wrap.EntitlementTO;
-import org.apache.syncope.core.persistence.api.dao.EntitlementDAO;
-import org.apache.syncope.core.persistence.api.entity.Entitlement;
-import org.apache.syncope.core.misc.security.AuthContextUtil;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class EntitlementLogic extends AbstractTransactionalLogic<EntitlementTO> {
-
-    @Autowired
-    private EntitlementDAO entitlementDAO;
-
-    public List<String> getAll() {
-        return CollectionUtils.collect(entitlementDAO.findAll(), new Transformer<Entitlement, String>() {
-
-            @Override
-            public String transform(final Entitlement entitlement) {
-                return entitlement.getKey();
-            }
-        }, new ArrayList<String>());
-    }
-
-    public Set<String> getOwn() {
-        return AuthContextUtil.getOwnedEntitlementNames();
-    }
-
-    @Override
-    protected EntitlementTO resolveReference(final Method method, final Object... args)
-            throws UnresolvedReferenceException {
-
-        throw new UnresolvedReferenceException();
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
index 6e4604b..bbbca1b 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java
@@ -27,34 +27,31 @@ import java.util.Map;
 import java.util.Set;
 import javax.annotation.Resource;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.GroupMod;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.PropagationStatus;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.common.lib.CollectionUtils2;
-import org.apache.syncope.core.persistence.api.GroupEntitlementUtil;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.misc.RealmUtils;
 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.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.AttributableTransformer;
 import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.security.AuthContextUtil;
-import org.apache.syncope.core.misc.security.UnauthorizedGroupException;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.security.UnauthorizedException;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
@@ -95,127 +92,69 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
     @Autowired
     protected GroupProvisioningManager provisioningManager;
 
-    @PreAuthorize("hasAnyRole('GROUP_READ', T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT)")
+    @PreAuthorize("hasRole('GROUP_READ')")
     @Transactional(readOnly = true)
     @Override
     public GroupTO read(final Long groupKey) {
-        Group group;
-        // bypass group entitlements check
-        if (anonymousUser.equals(AuthContextUtil.getAuthenticatedUsername())) {
-            group = groupDAO.find(groupKey);
-        } else {
-            group = groupDAO.authFetch(groupKey);
-        }
-
-        if (group == null) {
-            throw new NotFoundException("Group " + groupKey);
-        }
-
-        return binder.getGroupTO(group);
+        return binder.getGroupTO(groupKey);
     }
 
-    @PreAuthorize("isAuthenticated() "
-            + "and not(hasRole(T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT))")
+    @PreAuthorize("isAuthenticated() and not(hasRole('ANONYMOUS'))")
     @Transactional(readOnly = true)
-    public GroupTO readSelf(final Long groupKey) {
-        // Explicit search instead of using binder.getGroupFromId() in order to bypass auth checks - will do here
-        Group group = groupDAO.find(groupKey);
-        if (group == null) {
-            throw new NotFoundException("Group " + groupKey);
-        }
-
-        Set<Long> ownedGroupIds;
-        User authUser = userDAO.find(AuthContextUtil.getAuthenticatedUsername());
-        if (authUser == null) {
-            ownedGroupIds = Collections.<Long>emptySet();
-        } else {
-            ownedGroupIds = authUser.getGroupKeys();
-        }
-
-        Set<Long> allowedGroupIds = GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames());
-        allowedGroupIds.addAll(ownedGroupIds);
-        if (!allowedGroupIds.contains(group.getKey())) {
-            throw new UnauthorizedGroupException(group.getKey());
-        }
-
-        return binder.getGroupTO(group);
-    }
-
-    @PreAuthorize("hasRole('GROUP_READ')")
-    @Transactional(readOnly = true)
-    public GroupTO parent(final Long groupKey) {
-        Group group = groupDAO.authFetch(groupKey);
-
-        Set<Long> allowedGroupIds = GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames());
-        if (group.getParent() != null && !allowedGroupIds.contains(group.getParent().getKey())) {
-            throw new UnauthorizedGroupException(group.getParent().getKey());
-        }
-
-        GroupTO result = group.getParent() == null
-                ? null
-                : binder.getGroupTO(group.getParent());
-
-        return result;
-    }
-
-    @PreAuthorize("hasRole('GROUP_READ')")
-    @Transactional(readOnly = true)
-    public List<GroupTO> children(final Long groupKey) {
-        Group group = groupDAO.authFetch(groupKey);
-        final Set<Long> allowedGroupKeys =
-                GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames());
-
-        return CollectionUtils2.collect(groupDAO.findChildren(group), new Transformer<Group, GroupTO>() {
-
-            @Override
-            public GroupTO transform(final Group group) {
-                return binder.getGroupTO(group);
-            }
-        }, new Predicate<Group>() {
-
-            @Override
-            public boolean evaluate(final Group group) {
-                return allowedGroupKeys.contains(group.getKey());
-            }
-        }, new ArrayList<GroupTO>());
+    public List<GroupTO> own() {
+        return CollectionUtils.collect(
+                userDAO.find(AuthContextUtils.getAuthenticatedUsername()).getGroups(),
+                new Transformer<Group, GroupTO>() {
+
+                    @Override
+                    public GroupTO transform(final Group input) {
+                        return binder.getGroupTO(input);
+                    }
+                }, new ArrayList<GroupTO>());
     }
 
     @PreAuthorize("isAuthenticated()")
     @Transactional(readOnly = true, rollbackFor = { Throwable.class })
     @Override
-    public int count() {
-        return groupDAO.count();
+    public int count(final List<String> realms) {
+        return groupDAO.count(getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realms));
     }
 
     @PreAuthorize("isAuthenticated()")
     @Transactional(readOnly = true)
     @Override
-    public List<GroupTO> list(final int page, final int size, final List<OrderByClause> orderBy) {
-        return CollectionUtils.collect(groupDAO.findAll(page, size, orderBy), new Transformer<Group, GroupTO>() {
-
-            @Override
-            public GroupTO transform(final Group input) {
-                return binder.getGroupTO(input);
-            }
-        }, new ArrayList<GroupTO>());
+    public List<GroupTO> list(
+            final int page, final int size, final List<OrderByClause> orderBy, final List<String> realms) {
+
+        return CollectionUtils.collect(groupDAO.findAll(
+                getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realms),
+                page, size, orderBy),
+                new Transformer<Group, GroupTO>() {
+
+                    @Override
+                    public GroupTO transform(final Group input) {
+                        return binder.getGroupTO(input);
+                    }
+                }, new ArrayList<GroupTO>());
     }
 
-    @PreAuthorize("isAuthenticated()")
+    @PreAuthorize("hasRole('GROUP_SEARCH')")
     @Transactional(readOnly = true, rollbackFor = { Throwable.class })
     @Override
-    public int searchCount(final SearchCond searchCondition) {
-        final Set<Long> adminGroupIds = GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames());
-        return searchDAO.count(adminGroupIds, searchCondition, SubjectType.GROUP);
+    public int searchCount(final SearchCond searchCondition, final List<String> realms) {
+        return searchDAO.count(
+                getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_SEARCH), realms),
+                searchCondition, SubjectType.GROUP);
     }
 
-    @PreAuthorize("isAuthenticated()")
+    @PreAuthorize("hasRole('GROUP_SEARCH')")
     @Transactional(readOnly = true, rollbackFor = { Throwable.class })
     @Override
     public List<GroupTO> search(final SearchCond searchCondition, final int page, final int size,
-            final List<OrderByClause> orderBy) {
+            final List<OrderByClause> orderBy, final List<String> realms) {
 
-        List<Group> matchingGroups = searchDAO.search(GroupEntitlementUtil.getGroupKeys(AuthContextUtil.
-                getOwnedEntitlementNames()),
+        final List<Group> matchingGroups = searchDAO.search(
+                getEffectiveRealms(AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_SEARCH), realms),
                 searchCondition, page, size, orderBy, SubjectType.GROUP);
         return CollectionUtils.collect(matchingGroups, new Transformer<Group, GroupTO>() {
 
@@ -228,10 +167,15 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
 
     @PreAuthorize("hasRole('GROUP_CREATE')")
     public GroupTO create(final GroupTO groupTO) {
-        // Check that this operation is allowed to be performed by caller
-        Set<Long> allowedGroupIds = GroupEntitlementUtil.getGroupKeys(AuthContextUtil.getOwnedEntitlementNames());
-        if (groupTO.getParent() != 0 && !allowedGroupIds.contains(groupTO.getParent())) {
-            throw new UnauthorizedGroupException(groupTO.getParent());
+        if (groupTO.getRealm() == null) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+            throw sce;
+        }
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_CREATE),
+                Collections.singleton(groupTO.getRealm()));
+        if (effectiveRealms.isEmpty()) {
+            throw new UnauthorizedException(SubjectType.GROUP, null);
         }
 
         // Attributable transformation (if configured)
@@ -242,7 +186,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
          * Actual operations: workflow, propagation
          */
         Map.Entry<Long, List<PropagationStatus>> created = provisioningManager.create(groupTO);
-        final GroupTO savedTO = binder.getGroupTO(created.getKey());
+        GroupTO savedTO = binder.getGroupTO(created.getKey());
         savedTO.getPropagationStatusTOs().addAll(created.getValue());
         return savedTO;
     }
@@ -250,8 +194,16 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
     @PreAuthorize("hasRole('GROUP_UPDATE')")
     @Override
     public GroupTO update(final GroupMod groupMod) {
-        // Check that this operation is allowed to be performed by caller
-        groupDAO.authFetch(groupMod.getKey());
+        Group group = groupDAO.authFetch(groupMod.getKey());
+        if (group == null) {
+            throw new NotFoundException("Group with key " + groupMod.getKey());
+        }
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_UPDATE),
+                Collections.singleton(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey())));
+        if (effectiveRealms.isEmpty()) {
+            throw new UnauthorizedException(SubjectType.GROUP, group.getKey());
+        }
 
         // Attribute value transformation (if configured)
         GroupMod actual = attrTransformer.transform(groupMod);
@@ -259,7 +211,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
 
         Map.Entry<Long, List<PropagationStatus>> updated = provisioningManager.update(groupMod);
 
-        final GroupTO updatedTO = binder.getGroupTO(updated.getKey());
+        GroupTO updatedTO = binder.getGroupTO(updated.getKey());
         updatedTO.getPropagationStatusTOs().addAll(updated.getValue());
         return updatedTO;
     }
@@ -267,6 +219,17 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
     @PreAuthorize("hasRole('GROUP_DELETE')")
     @Override
     public GroupTO delete(final Long groupKey) {
+        Group group = groupDAO.authFetch(groupKey);
+        if (group == null) {
+            throw new NotFoundException("Group with key " + groupKey);
+        }
+        Set<String> effectiveRealms = getEffectiveRealms(
+                AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_DELETE),
+                Collections.singleton(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey())));
+        if (effectiveRealms.isEmpty()) {
+            throw new UnauthorizedException(SubjectType.GROUP, group.getKey());
+        }
+
         List<Group> ownedGroups = groupDAO.findOwnedByGroup(groupKey);
         if (!ownedGroups.isEmpty()) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.GroupOwnership);
@@ -290,26 +253,6 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
         return groupTO;
     }
 
-    @PreAuthorize("(hasRole('GROUP_DELETE') and #bulkAction.operation == #bulkAction.operation.DELETE)")
-    public BulkActionResult bulk(final BulkAction bulkAction) {
-        BulkActionResult res = new BulkActionResult();
-
-        if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
-            for (String groupKey : bulkAction.getTargets()) {
-                try {
-                    res.add(delete(Long.valueOf(groupKey)).getKey(), BulkActionResult.Status.SUCCESS);
-                } catch (Exception e) {
-                    LOG.error("Error performing delete for group {}", groupKey, e);
-                    res.add(groupKey, BulkActionResult.Status.FAILURE);
-                }
-            }
-        } else {
-            LOG.warn("Unsupported bulk action: {}", bulkAction.getOperation());
-        }
-
-        return res;
-    }
-
     @PreAuthorize("hasRole('GROUP_UPDATE')")
     @Transactional(rollbackFor = { Throwable.class })
     @Override
@@ -362,7 +305,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
 
         List<PropagationStatus> statuses = provisioningManager.deprovision(groupKey, resources);
 
-        final GroupTO updatedTO = binder.getGroupTO(group);
+        GroupTO updatedTO = binder.getGroupTO(group);
         updatedTO.getPropagationStatusTOs().addAll(statuses);
         return updatedTO;
     }
@@ -372,7 +315,7 @@ public class GroupLogic extends AbstractSubjectLogic<GroupTO, GroupMod> {
     @Override
     public GroupTO provision(
             final Long groupKey, final Collection<String> resources, final boolean changePwd, final String password) {
-        final GroupTO original = binder.getGroupTO(groupKey);
+        GroupTO original = binder.getGroupTO(groupKey);
 
         //trick: assign and retrieve propagation statuses ...
         original.getPropagationStatusTOs().addAll(

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
index 09a5d6b..a315bb4 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java
@@ -222,29 +222,26 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
 
     @PreAuthorize("hasRole('AUDIT_LIST') or hasRole('NOTIFICATION_LIST')")
     public List<EventCategoryTO> listAuditEvents() {
-        // use set to avoi duplications or null elements
-        final Set<EventCategoryTO> events = new HashSet<>();
+        // use set to avoid duplications or null elements
+        Set<EventCategoryTO> events = new HashSet<>();
 
         try {
-            final ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
-            final MetadataReaderFactory metadataReaderFactory =
-                    new CachingMetadataReaderFactory(resourcePatternResolver);
+            ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
+            MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
 
-            final String packageSearchPath =
-                    ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+            String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
                     + ClassUtils.convertClassNameToResourcePath(
                             SystemPropertyUtils.resolvePlaceholders(this.getClass().getPackage().getName()))
-                    + "/" + "**/*.class";
+                    + "/**/*.class";
 
-            final Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
+            Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
             for (Resource resource : resources) {
                 if (resource.isReadable()) {
                     final MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
                     final Class<?> clazz = Class.forName(metadataReader.getClassMetadata().getClassName());
 
-                    if (clazz.isAnnotationPresent(Component.class)
-                            && AbstractLogic.class.isAssignableFrom(clazz)) {
-                        final EventCategoryTO eventCategoryTO = new EventCategoryTO();
+                    if (clazz.isAnnotationPresent(Component.class) && AbstractLogic.class.isAssignableFrom(clazz)) {
+                        EventCategoryTO eventCategoryTO = new EventCategoryTO();
                         eventCategoryTO.setCategory(clazz.getSimpleName());
                         for (Method method : clazz.getDeclaredMethods()) {
                             if (Modifier.isPublic(method.getModifiers())) {
@@ -257,7 +254,7 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
             }
 
             //SYNCOPE-608
-            final EventCategoryTO authenticationControllerEvents = new EventCategoryTO();
+            EventCategoryTO authenticationControllerEvents = new EventCategoryTO();
             authenticationControllerEvents.setCategory("AuthenticationController");
             authenticationControllerEvents.getEvents().add("login");
             events.add(authenticationControllerEvents);
@@ -268,9 +265,9 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
 
             for (AttributableType attributableType : AttributableType.values()) {
                 for (ExternalResource resource : resourceDAO.findAll()) {
-                    final EventCategoryTO propEventCategoryTO = new EventCategoryTO(EventCategoryType.PROPAGATION);
-                    final EventCategoryTO syncEventCategoryTO = new EventCategoryTO(EventCategoryType.SYNCHRONIZATION);
-                    final EventCategoryTO pushEventCategoryTO = new EventCategoryTO(EventCategoryType.PUSH);
+                    EventCategoryTO propEventCategoryTO = new EventCategoryTO(EventCategoryType.PROPAGATION);
+                    EventCategoryTO syncEventCategoryTO = new EventCategoryTO(EventCategoryType.SYNCHRONIZATION);
+                    EventCategoryTO pushEventCategoryTO = new EventCategoryTO(EventCategoryType.PUSH);
 
                     propEventCategoryTO.setCategory(attributableType.name().toLowerCase());
                     propEventCategoryTO.setSubcategory(resource.getKey());
@@ -305,13 +302,13 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
             }
 
             for (SchedTask task : taskDAO.<SchedTask>findAll(TaskType.SCHEDULED)) {
-                final EventCategoryTO eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
+                EventCategoryTO eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
                 eventCategoryTO.setCategory(Class.forName(task.getJobClassName()).getSimpleName());
                 events.add(eventCategoryTO);
             }
 
             for (SyncTask task : taskDAO.<SyncTask>findAll(TaskType.SYNCHRONIZATION)) {
-                final EventCategoryTO eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
+                EventCategoryTO eventCategoryTO = new EventCategoryTO(EventCategoryType.TASK);
                 eventCategoryTO.setCategory(Class.forName(task.getJobClassName()).getSimpleName());
                 events.add(eventCategoryTO);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java
index 015c2a3..92be74b 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/PolicyLogic.java
@@ -102,36 +102,6 @@ public class PolicyLogic extends AbstractTransactionalLogic<AbstractPolicyTO> {
     }
 
     @PreAuthorize("hasRole('POLICY_READ')")
-    public PasswordPolicyTO getGlobalPasswordPolicy() {
-        PasswordPolicy policy = policyDAO.getGlobalPasswordPolicy();
-        if (policy == null) {
-            throw new NotFoundException("No password policy found");
-        }
-
-        return (PasswordPolicyTO) binder.getPolicyTO(policy);
-    }
-
-    @PreAuthorize("hasRole('POLICY_READ')")
-    public AccountPolicyTO getGlobalAccountPolicy() {
-        AccountPolicy policy = policyDAO.getGlobalAccountPolicy();
-        if (policy == null) {
-            throw new NotFoundException("No account policy found");
-        }
-
-        return (AccountPolicyTO) binder.getPolicyTO(policy);
-    }
-
-    @PreAuthorize("hasRole('POLICY_READ')")
-    public SyncPolicyTO getGlobalSyncPolicy() {
-        SyncPolicy policy = policyDAO.getGlobalSyncPolicy();
-        if (policy == null) {
-            throw new NotFoundException("No sync policy found");
-        }
-
-        return (SyncPolicyTO) binder.getPolicyTO(policy);
-    }
-
-    @PreAuthorize("hasRole('POLICY_READ')")
     public <T extends AbstractPolicyTO> T read(final Long id) {
         Policy policy = policyDAO.find(id);
         if (policy == null) {
@@ -154,12 +124,10 @@ public class PolicyLogic extends AbstractTransactionalLogic<AbstractPolicyTO> {
         return policyToDelete;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected AbstractPolicyTO resolveReference(final Method method, final Object... args)
             throws UnresolvedReferenceException {
+
         Long id = null;
 
         if (ArrayUtils.isNotEmpty(args)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
index 9a3c641..3148d19 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
@@ -27,8 +27,6 @@ import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
@@ -39,8 +37,8 @@ import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilFactory;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.MappingItem;
@@ -48,8 +46,8 @@ import org.apache.syncope.core.persistence.api.entity.Subject;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.ConnectorFactory;
 import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder;
-import org.apache.syncope.core.misc.ConnObjectUtil;
-import org.apache.syncope.core.misc.MappingUtil;
+import org.apache.syncope.core.misc.ConnObjectUtils;
+import org.apache.syncope.core.misc.MappingUtils;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
 import org.identityconnectors.framework.common.objects.ConnectorObject;
@@ -77,13 +75,13 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
     private ResourceDataBinder binder;
 
     @Autowired
-    private ConnObjectUtil connObjectUtil;
+    private ConnObjectUtils connObjectUtils;
 
     @Autowired
     private ConnectorFactory connFactory;
 
     @Autowired
-    private AttributableUtilFactory attrUtilFactory;
+    private AttributableUtilsFactory attrUtilsFactory;
 
     @PreAuthorize("hasRole('RESOURCE_CREATE')")
     public ResourceTO create(final ResourceTO resourceTO) {
@@ -184,21 +182,21 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             throw new NotFoundException(type + " " + id);
         }
 
-        final AttributableUtil attrUtil = attrUtilFactory.getInstance(type.asAttributableType());
+        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(type.asAttributableType());
 
-        MappingItem accountIdItem = attrUtil.getAccountIdItem(resource);
+        MappingItem accountIdItem = attrUtils.getAccountIdItem(resource);
         if (accountIdItem == null) {
             throw new NotFoundException(
                     "AccountId mapping for " + type + " " + id + " on resource '" + resourceName + "'");
         }
-        final String accountIdValue = MappingUtil.getAccountIdValue(
-                subject, resource, attrUtil.getAccountIdItem(resource));
+        final String accountIdValue = MappingUtils.getAccountIdValue(
+                subject, resource, attrUtils.getAccountIdItem(resource));
 
         final ObjectClass objectClass = SubjectType.USER == type ? ObjectClass.ACCOUNT : ObjectClass.GROUP;
 
         final Connector connector = connFactory.getConnector(resource);
         final ConnectorObject connectorObject = connector.getObject(objectClass, new Uid(accountIdValue),
-                connector.getOperationOptions(attrUtil.getMappingItems(resource, MappingPurpose.BOTH)));
+                connector.getOperationOptions(attrUtils.getMappingItems(resource, MappingPurpose.BOTH)));
         if (connectorObject == null) {
             throw new NotFoundException("Object " + accountIdValue + " with class " + objectClass
                     + "not found on resource " + resourceName);
@@ -212,7 +210,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
             attributes.add(connectorObject.getName());
         }
 
-        return connObjectUtil.getConnObjectTO(connectorObject);
+        return connObjectUtils.getConnObjectTO(connectorObject);
     }
 
     @PreAuthorize("hasRole('CONNECTOR_READ')")
@@ -234,24 +232,6 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         return result;
     }
 
-    @PreAuthorize("hasRole('RESOURCE_DELETE') and #bulkAction.operation == #bulkAction.operation.DELETE")
-    public BulkActionResult bulk(final BulkAction bulkAction) {
-        BulkActionResult res = new BulkActionResult();
-
-        if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
-            for (String name : bulkAction.getTargets()) {
-                try {
-                    res.add(delete(name).getKey(), BulkActionResult.Status.SUCCESS);
-                } catch (Exception e) {
-                    LOG.error("Error performing delete for resource {}", name, e);
-                    res.add(name, BulkActionResult.Status.FAILURE);
-                }
-            }
-        }
-
-        return res;
-    }
-
     @Override
     protected ResourceTO resolveReference(final Method method, final Object... args)
             throws UnresolvedReferenceException {

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
index 8e15c96..1ced7a0 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
@@ -38,8 +38,8 @@ import org.apache.syncope.core.persistence.api.dao.DuplicateException;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilFactory;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
@@ -64,22 +64,22 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
     private SchemaDataBinder binder;
 
     @Autowired
-    private AttributableUtilFactory attrUtilFactory;
+    private AttributableUtilsFactory attrUtilsFactory;
 
-    private boolean doesSchemaExist(final SchemaType schemaType, final String name, final AttributableUtil attrUtil) {
+    private boolean doesSchemaExist(final SchemaType schemaType, final String name, final AttributableUtils attrUtils) {
         boolean found;
 
         switch (schemaType) {
             case VIRTUAL:
-                found = virSchemaDAO.find(name, attrUtil.virSchemaClass()) != null;
+                found = virSchemaDAO.find(name, attrUtils.virSchemaClass()) != null;
                 break;
 
             case DERIVED:
-                found = derSchemaDAO.find(name, attrUtil.derSchemaClass()) != null;
+                found = derSchemaDAO.find(name, attrUtils.derSchemaClass()) != null;
                 break;
 
             case PLAIN:
-                found = plainSchemaDAO.find(name, attrUtil.plainSchemaClass()) != null;
+                found = plainSchemaDAO.find(name, attrUtils.plainSchemaClass()) != null;
                 break;
 
             default:
@@ -100,22 +100,21 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
             throw sce;
         }
 
-        final AttributableUtil attrUtil = attrUtilFactory.getInstance(attrType);
-
-        if (doesSchemaExist(schemaType, schemaTO.getKey(), attrUtil)) {
-            throw new DuplicateException(schemaType + "/" + attrType + "/" + schemaTO.getKey());
+        AttributableUtils attrUtils = attrUtilsFactory.getInstance(attrType);
+        if (doesSchemaExist(schemaType, schemaTO.getKey(), attrUtils)) {
+            throw new DuplicateException(attrType + "/" + schemaType + "/" + schemaTO.getKey());
         }
 
         T created;
         switch (schemaType) {
             case VIRTUAL:
-                VirSchema virSchema = attrUtil.newVirSchema();
+                VirSchema virSchema = attrUtils.newVirSchema();
                 binder.create((VirSchemaTO) schemaTO, virSchema);
                 virSchema = virSchemaDAO.save(virSchema);
                 created = (T) binder.getVirSchemaTO(virSchema);
                 break;
             case DERIVED:
-                DerSchema derSchema = attrUtil.newDerSchema();
+                DerSchema derSchema = attrUtils.newDerSchema();
                 binder.create((DerSchemaTO) schemaTO, derSchema);
                 derSchema = derSchemaDAO.save(derSchema);
 
@@ -124,47 +123,47 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
 
             case PLAIN:
             default:
-                PlainSchema normalSchema = attrUtil.newPlainSchema();
+                PlainSchema normalSchema = attrUtils.newPlainSchema();
                 binder.create((PlainSchemaTO) schemaTO, normalSchema);
                 normalSchema = plainSchemaDAO.save(normalSchema);
 
-                created = (T) binder.getPlainSchemaTO(normalSchema, attrUtil);
+                created = (T) binder.getPlainSchemaTO(normalSchema, attrUtils);
         }
         return created;
     }
 
     @PreAuthorize("hasRole('SCHEMA_DELETE')")
     public void delete(final AttributableType attrType, final SchemaType schemaType, final String schemaName) {
-        final AttributableUtil attrUtil = attrUtilFactory.getInstance(attrType);
+        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(attrType);
 
-        if (!doesSchemaExist(schemaType, schemaName, attrUtil)) {
+        if (!doesSchemaExist(schemaType, schemaName, attrUtils)) {
             throw new NotFoundException(schemaType + "/" + attrType + "/" + schemaName);
         }
 
         switch (schemaType) {
             case VIRTUAL:
-                virSchemaDAO.delete(schemaName, attrUtil);
+                virSchemaDAO.delete(schemaName, attrUtils);
                 break;
 
             case DERIVED:
-                derSchemaDAO.delete(schemaName, attrUtil);
+                derSchemaDAO.delete(schemaName, attrUtils);
                 break;
 
             case PLAIN:
             default:
-                plainSchemaDAO.delete(schemaName, attrUtil);
+                plainSchemaDAO.delete(schemaName, attrUtils);
         }
     }
 
     @PreAuthorize("isAuthenticated()")
     @SuppressWarnings("unchecked")
     public <T extends AbstractSchemaTO> List<T> list(final AttributableType attrType, final SchemaType schemaType) {
-        final AttributableUtil attrUtil = attrUtilFactory.getInstance(attrType);
+        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(attrType);
 
         List<T> result;
         switch (schemaType) {
             case VIRTUAL:
-                result = CollectionUtils.collect(virSchemaDAO.findAll(attrUtil.virSchemaClass()),
+                result = CollectionUtils.collect(virSchemaDAO.findAll(attrUtils.virSchemaClass()),
                         new Transformer<VirSchema, T>() {
 
                             @Override
@@ -175,7 +174,7 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
                 break;
 
             case DERIVED:
-                result = CollectionUtils.collect(derSchemaDAO.findAll(attrUtil.derSchemaClass()),
+                result = CollectionUtils.collect(derSchemaDAO.findAll(attrUtils.derSchemaClass()),
                         new Transformer<DerSchema, T>() {
 
                             @Override
@@ -187,12 +186,12 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
 
             case PLAIN:
             default:
-                result = CollectionUtils.collect(plainSchemaDAO.findAll(attrUtil.plainSchemaClass()),
+                result = CollectionUtils.collect(plainSchemaDAO.findAll(attrUtils.plainSchemaClass()),
                         new Transformer<PlainSchema, T>() {
 
                             @Override
                             public T transform(final PlainSchema input) {
-                                return (T) binder.getPlainSchemaTO(input, attrUtil);
+                                return (T) binder.getPlainSchemaTO(input, attrUtils);
                             }
                         }, new ArrayList<T>());
         }
@@ -205,12 +204,12 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
     public <T extends AbstractSchemaTO> T read(
             final AttributableType attrType, final SchemaType schemaType, final String schemaName) {
 
-        final AttributableUtil attrUtil = attrUtilFactory.getInstance(attrType);
+        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(attrType);
 
         T read;
         switch (schemaType) {
             case VIRTUAL:
-                VirSchema virSchema = virSchemaDAO.find(schemaName, attrUtil.virSchemaClass());
+                VirSchema virSchema = virSchemaDAO.find(schemaName, attrUtils.virSchemaClass());
                 if (virSchema == null) {
                     throw new NotFoundException("Virtual Schema '" + schemaName + "'");
                 }
@@ -219,7 +218,7 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
                 break;
 
             case DERIVED:
-                DerSchema derSchema = derSchemaDAO.find(schemaName, attrUtil.derSchemaClass());
+                DerSchema derSchema = derSchemaDAO.find(schemaName, attrUtils.derSchemaClass());
                 if (derSchema == null) {
                     throw new NotFoundException("Derived schema '" + schemaName + "'");
                 }
@@ -229,12 +228,12 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
 
             case PLAIN:
             default:
-                PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtil.plainSchemaClass());
+                PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtils.plainSchemaClass());
                 if (schema == null) {
                     throw new NotFoundException("Schema '" + schemaName + "'");
                 }
 
-                read = (T) binder.getPlainSchemaTO(schema, attrUtil);
+                read = (T) binder.getPlainSchemaTO(schema, attrUtils);
         }
 
         return read;
@@ -244,15 +243,15 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
     public <T extends AbstractSchemaTO> void update(
             final AttributableType attrType, final SchemaType schemaType, final T schemaTO) {
 
-        final AttributableUtil attrUtil = attrUtilFactory.getInstance(attrType);
+        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(attrType);
 
-        if (!doesSchemaExist(schemaType, schemaTO.getKey(), attrUtil)) {
+        if (!doesSchemaExist(schemaType, schemaTO.getKey(), attrUtils)) {
             throw new NotFoundException(schemaType + "/" + attrType + "/" + schemaTO.getKey());
         }
 
         switch (schemaType) {
             case VIRTUAL:
-                VirSchema virSchema = virSchemaDAO.find(schemaTO.getKey(), attrUtil.virSchemaClass());
+                VirSchema virSchema = virSchemaDAO.find(schemaTO.getKey(), attrUtils.virSchemaClass());
                 if (virSchema == null) {
                     throw new NotFoundException("Virtual Schema '" + schemaTO.getKey() + "'");
                 }
@@ -262,7 +261,7 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
                 break;
 
             case DERIVED:
-                DerSchema derSchema = derSchemaDAO.find(schemaTO.getKey(), attrUtil.derSchemaClass());
+                DerSchema derSchema = derSchemaDAO.find(schemaTO.getKey(), attrUtils.derSchemaClass());
                 if (derSchema == null) {
                     throw new NotFoundException("Derived schema '" + schemaTO.getKey() + "'");
                 }
@@ -273,12 +272,12 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
 
             case PLAIN:
             default:
-                PlainSchema schema = plainSchemaDAO.find(schemaTO.getKey(), attrUtil.plainSchemaClass());
+                PlainSchema schema = plainSchemaDAO.find(schemaTO.getKey(), attrUtils.plainSchemaClass());
                 if (schema == null) {
                     throw new NotFoundException("Schema '" + schemaTO.getKey() + "'");
                 }
 
-                binder.update((PlainSchemaTO) schemaTO, schema, attrUtil);
+                binder.update((PlainSchemaTO) schemaTO, schema, attrUtils);
                 plainSchemaDAO.save(schema);
         }
     }
@@ -305,15 +304,15 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
 
         if (key != null) {
             try {
-                final AttributableUtil attrUtil = attrUtilFactory.getInstance(kind);
+                final AttributableUtils attrUtils = attrUtilsFactory.getInstance(kind);
 
                 AbstractSchemaTO result = null;
 
-                PlainSchema plainSchema = plainSchemaDAO.find(key, attrUtil.plainSchemaClass());
+                PlainSchema plainSchema = plainSchemaDAO.find(key, attrUtils.plainSchemaClass());
                 if (plainSchema == null) {
-                    DerSchema derSchema = derSchemaDAO.find(key, attrUtil.derSchemaClass());
+                    DerSchema derSchema = derSchemaDAO.find(key, attrUtils.derSchemaClass());
                     if (derSchema == null) {
-                        VirSchema virSchema = virSchemaDAO.find(key, attrUtil.virSchemaClass());
+                        VirSchema virSchema = virSchemaDAO.find(key, attrUtils.virSchemaClass());
                         if (virSchema != null) {
                             result = binder.getVirSchemaTO(virSchema);
                         }
@@ -321,7 +320,7 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
                         result = binder.getDerSchemaTO(derSchema);
                     }
                 } else {
-                    result = binder.getPlainSchemaTO(plainSchema, attrUtil);
+                    result = binder.getPlainSchemaTO(plainSchema, attrUtils);
                 }
 
                 return result;

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java
index b2a89ca..6963dbe 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SecurityQuestionLogic.java
@@ -105,7 +105,7 @@ public class SecurityQuestionLogic extends AbstractTransactionalLogic<SecurityQu
         return deleted;
     }
 
-    @PreAuthorize("isAnonymous() or hasRole(T(org.apache.syncope.common.lib.SyncopeConstants).ANONYMOUS_ENTITLEMENT)")
+    @PreAuthorize("isAnonymous() or hasRole('ANONYMOUS')")
     public SecurityQuestionTO read(final String username) {
         if (username == null) {
             throw new NotFoundException("Null username");

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
index 8084cd4..09c606a 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
@@ -34,6 +34,7 @@ import org.apache.syncope.core.provisioning.api.AttributableTransformer;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
 import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
 import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
 import org.apache.syncope.core.provisioning.java.notification.NotificationManagerImpl;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
@@ -71,6 +72,9 @@ public class SyncopeLogic extends AbstractLogic<SyncopeTO> {
     private GroupProvisioningManager gProvisioningManager;
 
     @Autowired
+    private VirAttrCache virAttrCache;
+
+    @Autowired
     private ImplementationClassNamesLoader classNamesLoader;
 
     @Resource(name = "velocityResourceLoader")
@@ -114,6 +118,7 @@ public class SyncopeLogic extends AbstractLogic<SyncopeTO> {
 
         syncopeTO.setUserProvisioningManager(uProvisioningManager.getClass().getName());
         syncopeTO.setGroupProvisioningManager(gProvisioningManager.getClass().getName());
+        syncopeTO.setVirAttrCache(virAttrCache.getClass().getName());
 
         syncopeTO.getReportlets().addAll(
                 classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.REPORTLET));

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
index 4e51328..168e306 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java
@@ -27,8 +27,6 @@ import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
 import org.apache.syncope.common.lib.to.SyncTaskTO;
 import org.apache.syncope.common.lib.to.TaskExecTO;
@@ -45,8 +43,8 @@ import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.persistence.api.entity.task.TaskUtil;
-import org.apache.syncope.core.persistence.api.entity.task.TaskUtilFactory;
+import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
+import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory;
 import org.apache.syncope.core.provisioning.api.data.TaskDataBinder;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
 import org.apache.syncope.core.provisioning.api.job.TaskJob;
@@ -86,13 +84,13 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
     private SchedulerFactoryBean scheduler;
 
     @Autowired
-    private TaskUtilFactory taskUtilFactory;
+    private TaskUtilsFactory taskUtilsFactory;
 
     @PreAuthorize("hasRole('TASK_CREATE')")
     public <T extends SchedTaskTO> T createSchedTask(final T taskTO) {
-        TaskUtil taskUtil = taskUtilFactory.getInstance(taskTO);
+        TaskUtils taskUtils = taskUtilsFactory.getInstance(taskTO);
 
-        SchedTask task = binder.createSchedTask(taskTO, taskUtil);
+        SchedTask task = binder.createSchedTask(taskTO, taskUtils);
         task = taskDAO.save(task);
 
         try {
@@ -105,7 +103,7 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
             throw sce;
         }
 
-        return binder.getTaskTO(task, taskUtil);
+        return binder.getTaskTO(task, taskUtils);
     }
 
     @PreAuthorize("hasRole('TASK_UPDATE')")
@@ -120,9 +118,9 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
             throw new NotFoundException("Task " + taskTO.getKey());
         }
 
-        TaskUtil taskUtil = taskUtilFactory.getInstance(task);
+        TaskUtils taskUtils = taskUtilsFactory.getInstance(task);
 
-        binder.updateSchedTask(task, taskTO, taskUtil);
+        binder.updateSchedTask(task, taskTO, taskUtils);
         task = taskDAO.save(task);
 
         try {
@@ -135,7 +133,7 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
             throw sce;
         }
 
-        return binder.getTaskTO(task, taskUtil);
+        return binder.getTaskTO(task, taskUtils);
     }
 
     @PreAuthorize("hasRole('TASK_LIST')")
@@ -148,14 +146,14 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
     public <T extends AbstractTaskTO> List<T> list(final TaskType taskType,
             final int page, final int size, final List<OrderByClause> orderByClauses) {
 
-        final TaskUtil taskUtil = taskUtilFactory.getInstance(taskType);
+        final TaskUtils taskUtilss = taskUtilsFactory.getInstance(taskType);
 
         return CollectionUtils.collect(taskDAO.findAll(page, size, orderByClauses, taskType),
                 new Transformer<Task, T>() {
 
                     @Override
                     public T transform(final Task task) {
-                        return (T) binder.getTaskTO(task, taskUtil);
+                        return (T) binder.getTaskTO(task, taskUtilss);
                     }
                 }, new ArrayList<T>());
     }
@@ -166,7 +164,7 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
         if (task == null) {
             throw new NotFoundException("Task " + taskId);
         }
-        return binder.getTaskTO(task, taskUtilFactory.getInstance(task));
+        return binder.getTaskTO(task, taskUtilsFactory.getInstance(task));
     }
 
     @PreAuthorize("hasRole('TASK_READ')")
@@ -184,10 +182,10 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
         if (task == null) {
             throw new NotFoundException("Task " + taskId);
         }
-        TaskUtil taskUtil = taskUtilFactory.getInstance(task);
+        TaskUtils taskUtils = taskUtilsFactory.getInstance(task);
 
         TaskExecTO result = null;
-        switch (taskUtil.getType()) {
+        switch (taskUtils.getType()) {
             case PROPAGATION:
                 final TaskExec propExec = taskExecutor.execute((PropagationTask) task);
                 result = binder.getTaskExecTO(propExec);
@@ -241,14 +239,14 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
 
         SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPropagationTaskExecReport);
 
-        TaskUtil taskUtil = taskUtilFactory.getInstance(exec.getTask());
-        if (TaskType.PROPAGATION == taskUtil.getType()) {
+        TaskUtils taskUtils = taskUtilsFactory.getInstance(exec.getTask());
+        if (TaskType.PROPAGATION == taskUtils.getType()) {
             PropagationTask task = (PropagationTask) exec.getTask();
             if (task.getPropagationMode() != PropagationMode.TWO_PHASES) {
                 sce.getElements().add("Propagation mode: " + task.getPropagationMode());
             }
         } else {
-            sce.getElements().add("Task type: " + taskUtil);
+            sce.getElements().add("Task type: " + taskUtils);
         }
 
         switch (status) {
@@ -280,13 +278,13 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
         if (task == null) {
             throw new NotFoundException("Task " + taskId);
         }
-        TaskUtil taskUtil = taskUtilFactory.getInstance(task);
+        TaskUtils taskUtils = taskUtilsFactory.getInstance(task);
 
-        T taskToDelete = binder.getTaskTO(task, taskUtil);
+        T taskToDelete = binder.getTaskTO(task, taskUtils);
 
-        if (TaskType.SCHEDULED == taskUtil.getType()
-                || TaskType.SYNCHRONIZATION == taskUtil.getType()
-                || TaskType.PUSH == taskUtil.getType()) {
+        if (TaskType.SCHEDULED == taskUtils.getType()
+                || TaskType.SYNCHRONIZATION == taskUtils.getType()
+                || TaskType.PUSH == taskUtils.getType()) {
 
             jobInstanceLoader.unregisterJob(task);
         }
@@ -307,55 +305,6 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
         return taskExecutionToDelete;
     }
 
-    @PreAuthorize("(hasRole('TASK_DELETE') and #bulkAction.operation == #bulkAction.operation.DELETE) or "
-            + "(hasRole('TASK_EXECUTE') and "
-            + "(#bulkAction.operation == #bulkAction.operation.EXECUTE or "
-            + "#bulkAction.operation == #bulkAction.operation.DRYRUN))")
-    public BulkActionResult bulk(final BulkAction bulkAction) {
-        BulkActionResult res = new BulkActionResult();
-
-        switch (bulkAction.getOperation()) {
-            case DELETE:
-                for (String taskId : bulkAction.getTargets()) {
-                    try {
-                        res.add(delete(Long.valueOf(taskId)).getKey(), BulkActionResult.Status.SUCCESS);
-                    } catch (Exception e) {
-                        LOG.error("Error performing delete for task {}", taskId, e);
-                        res.add(taskId, BulkActionResult.Status.FAILURE);
-                    }
-                }
-                break;
-
-            case DRYRUN:
-                for (String taskId : bulkAction.getTargets()) {
-                    try {
-                        execute(Long.valueOf(taskId), true);
-                        res.add(taskId, BulkActionResult.Status.SUCCESS);
-                    } catch (Exception e) {
-                        LOG.error("Error performing dryrun for task {}", taskId, e);
-                        res.add(taskId, BulkActionResult.Status.FAILURE);
-                    }
-                }
-                break;
-
-            case EXECUTE:
-                for (String taskId : bulkAction.getTargets()) {
-                    try {
-                        execute(Long.valueOf(taskId), false);
-                        res.add(taskId, BulkActionResult.Status.SUCCESS);
-                    } catch (Exception e) {
-                        LOG.error("Error performing execute for task {}", taskId, e);
-                        res.add(taskId, BulkActionResult.Status.FAILURE);
-                    }
-                }
-                break;
-
-            default:
-        }
-
-        return res;
-    }
-
     @Override
     protected AbstractTaskTO resolveReference(final Method method, final Object... args)
             throws UnresolvedReferenceException {
@@ -377,7 +326,7 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
         if ((key != null) && !key.equals(0L)) {
             try {
                 final Task task = taskDAO.find(key);
-                return binder.getTaskTO(task, taskUtilFactory.getInstance(task));
+                return binder.getTaskTO(task, taskUtilsFactory.getInstance(task));
             } catch (Throwable ignore) {
                 LOG.debug("Unresolved reference", ignore);
                 throw new UnresolvedReferenceException(ignore);


Mime
View raw message