cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mc...@apache.org
Subject git commit: updated refs/heads/rbac to 2b4703b
Date Thu, 10 Oct 2013 05:04:38 GMT
Updated Branches:
  refs/heads/rbac f59e47b26 -> 2b4703b6e


Change ListVMsCmd to use new role and entity permission information.

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/2b4703b6
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/2b4703b6
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/2b4703b6

Branch: refs/heads/rbac
Commit: 2b4703b6e62e47a14e8cadd04e7d0dbf601de6f7
Parents: f59e47b
Author: Min Chen <min.chen@citrix.com>
Authored: Wed Oct 9 21:56:52 2013 -0700
Committer: Min Chen <min.chen@citrix.com>
Committed: Wed Oct 9 21:56:52 2013 -0700

----------------------------------------------------------------------
 .../cloudstack/acl/AclRolePermission.java       |   2 +
 .../org/apache/cloudstack/acl/AclService.java   |   8 +
 .../apache/cloudstack/acl/PermissionScope.java  |  23 ++-
 .../cloudstack/acl/AclEntityPermissionVO.java   |  10 +-
 .../cloudstack/acl/AclRolePermissionVO.java     |  22 ++-
 .../acl/dao/AclEntityPermissionDao.java         |   4 +
 .../acl/dao/AclEntityPermissionDaoImpl.java     |  21 +++
 .../acl/dao/AclRolePermissionDao.java           |   4 +
 .../acl/dao/AclRolePermissionDaoImpl.java       |  22 +++
 .../com/cloud/api/query/QueryManagerImpl.java   |  16 +-
 server/src/com/cloud/user/AccountManager.java   |   9 +-
 .../src/com/cloud/user/AccountManagerImpl.java  | 169 ++++++++++++++++---
 .../apache/cloudstack/acl/AclServiceImpl.java   |  64 +++++++
 .../com/cloud/user/MockAccountManagerImpl.java  |   7 +
 14 files changed, 345 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/api/src/org/apache/cloudstack/acl/AclRolePermission.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/acl/AclRolePermission.java b/api/src/org/apache/cloudstack/acl/AclRolePermission.java
index 4ec16bc..69259e2 100644
--- a/api/src/org/apache/cloudstack/acl/AclRolePermission.java
+++ b/api/src/org/apache/cloudstack/acl/AclRolePermission.java
@@ -27,5 +27,7 @@ public interface AclRolePermission extends InternalIdentity {
 
     AccessType getAccessType();
 
+    PermissionScope getScope();
+
     boolean isAllowed();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/api/src/org/apache/cloudstack/acl/AclService.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/acl/AclService.java b/api/src/org/apache/cloudstack/acl/AclService.java
index 0866b2f..c7a1174 100644
--- a/api/src/org/apache/cloudstack/acl/AclService.java
+++ b/api/src/org/apache/cloudstack/acl/AclService.java
@@ -20,6 +20,8 @@ import java.util.List;
 
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 
+import com.cloud.utils.Pair;
+
 public interface AclService {
 
     /**
@@ -76,6 +78,12 @@ public interface AclService {
 
     List<AclRole> getAclRoles(long accountId);
 
+    List<AclGroup> getAclGroups(long accountId);
+
+    AclRolePermission getAclRolePermission(long accountId, String entityType, AccessType
accessType);
+
+    Pair<List<Long>, List<Long>> getAclEntityPermission(long accountId,
String entityType, AccessType accessType);
+
     boolean isAPIAccessibleForRoles(String apiName, List<AclRole> roles);
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/api/src/org/apache/cloudstack/acl/PermissionScope.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/acl/PermissionScope.java b/api/src/org/apache/cloudstack/acl/PermissionScope.java
index f33e4c3..5e72747 100644
--- a/api/src/org/apache/cloudstack/acl/PermissionScope.java
+++ b/api/src/org/apache/cloudstack/acl/PermissionScope.java
@@ -1,7 +1,24 @@
 package org.apache.cloudstack.acl;
 
 public enum PermissionScope {
-    ACCOUNT,
-    DOMAIN,
-    REGION;
+    ACCOUNT(1),
+    DOMAIN(2),
+    REGION(3);
+
+    private int _scale;
+
+    private PermissionScope(int scale) {
+        _scale = scale;
+    }
+
+    public int getScale() {
+        return _scale;
+    }
+
+    public boolean greaterThan(PermissionScope s) {
+        if (_scale > s.getScale())
+            return true;
+        else
+            return false;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/engine/schema/src/org/apache/cloudstack/acl/AclEntityPermissionVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/acl/AclEntityPermissionVO.java b/engine/schema/src/org/apache/cloudstack/acl/AclEntityPermissionVO.java
index 4e0f3c0..151e9c0 100644
--- a/engine/schema/src/org/apache/cloudstack/acl/AclEntityPermissionVO.java
+++ b/engine/schema/src/org/apache/cloudstack/acl/AclEntityPermissionVO.java
@@ -41,7 +41,7 @@ public class AclEntityPermissionVO implements AclEntityPermission {
     AccessType accessType;
 
     @Column(name = "permission")
-    private boolean permission;
+    private boolean allowed;
 
     @Column(name = GenericDao.REMOVED_COLUMN)
     private Date removed;
@@ -60,7 +60,7 @@ public class AclEntityPermissionVO implements AclEntityPermission {
         this.entityId = entityId;
         this.entityUuid = entityUuid;
         accessType = atype;
-        this.permission = permission;
+        allowed = permission;
     }
 
     @Override
@@ -123,7 +123,11 @@ public class AclEntityPermissionVO implements AclEntityPermission {
 
     @Override
     public boolean isAllowed() {
-        return permission;
+        return allowed;
+    }
+
+    public void setAllowed(boolean allowed) {
+        this.allowed = allowed;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/engine/schema/src/org/apache/cloudstack/acl/AclRolePermissionVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/acl/AclRolePermissionVO.java b/engine/schema/src/org/apache/cloudstack/acl/AclRolePermissionVO.java
index d866d91..b0fb230 100644
--- a/engine/schema/src/org/apache/cloudstack/acl/AclRolePermissionVO.java
+++ b/engine/schema/src/org/apache/cloudstack/acl/AclRolePermissionVO.java
@@ -46,8 +46,12 @@ public class AclRolePermissionVO implements AclRolePermission {
     @Enumerated(value = EnumType.STRING)
     AccessType accessType;
 
+    @Column(name = "scope")
+    @Enumerated(value = EnumType.STRING)
+    PermissionScope scope;
+
     @Column(name = "permission")
-    private boolean permission;
+    private boolean allowed;
 
     public AclRolePermissionVO() {
 
@@ -93,7 +97,21 @@ public class AclRolePermissionVO implements AclRolePermission {
     }
 
     @Override
+    public PermissionScope getScope() {
+        return scope;
+    }
+
+    public void setScope(PermissionScope scope) {
+        this.scope = scope;
+    }
+
+    @Override
     public boolean isAllowed() {
-        return permission;
+        return allowed;
     }
+
+    public void setAllowed(boolean allowed) {
+        this.allowed = allowed;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDao.java b/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDao.java
index 58c3478..74427a1 100644
--- a/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDao.java
+++ b/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDao.java
@@ -16,6 +16,8 @@
 // under the License.
 package org.apache.cloudstack.acl.dao;
 
+import java.util.List;
+
 import org.apache.cloudstack.acl.AclEntityPermissionVO;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 
@@ -25,4 +27,6 @@ public interface AclEntityPermissionDao extends GenericDao<AclEntityPermissionVO
 
     AclEntityPermissionVO findByGroupAndEntity(long groupId, String entityType, long entityId,
AccessType accessType);
 
+    List<Long> findEntityIdByGroupAndPermission(long groupId, String entityType, AccessType
accessType, boolean isAllowed);
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDaoImpl.java
b/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDaoImpl.java
index 482c9f3..aa7aaf4 100644
--- a/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDaoImpl.java
+++ b/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDaoImpl.java
@@ -16,6 +16,8 @@
 // under the License.
 package org.apache.cloudstack.acl.dao;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
 import javax.naming.ConfigurationException;
@@ -47,6 +49,7 @@ public class AclEntityPermissionDaoImpl extends GenericDaoBase<AclEntityPermissi
         findByGroupEntity.and("entityType", findByGroupEntity.entity().getEntityType(), SearchCriteria.Op.EQ);
         findByGroupEntity.and("entityId", findByGroupEntity.entity().getEntityId(), SearchCriteria.Op.EQ);
         findByGroupEntity.and("accessType", findByGroupEntity.entity().getAccessType(), SearchCriteria.Op.EQ);
+        findByGroupEntity.and("allowed", findByGroupEntity.entity().isAllowed(), SearchCriteria.Op.EQ);
         findByGroupEntity.done();
 
         return true;
@@ -61,4 +64,22 @@ public class AclEntityPermissionDaoImpl extends GenericDaoBase<AclEntityPermissi
         sc.setParameters("accessType", accessType);
         return findOneBy(sc);
     }
+
+    @Override
+    public List<Long> findEntityIdByGroupAndPermission(long groupId, String entityType,
AccessType accessType, boolean isAllowed) {
+        List<Long> idList = new ArrayList<Long>();
+        SearchCriteria<AclEntityPermissionVO> sc = findByGroupEntity.create();
+        sc.setParameters("groupId", groupId);
+        sc.setParameters("entityType", entityType);
+        sc.setParameters("allowed", isAllowed);
+        sc.setParameters("accessType", accessType);
+        List<AclEntityPermissionVO> permList = listBy(sc);
+        if (permList != null) {
+            for (AclEntityPermissionVO perm : permList) {
+                idList.add(perm.getEntityId());
+            }
+        }
+        return idList;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDao.java b/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDao.java
index b877e87..d249963 100644
--- a/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDao.java
+++ b/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDao.java
@@ -25,6 +25,10 @@ import com.cloud.utils.db.GenericDao;
 
 public interface AclRolePermissionDao extends GenericDao<AclRolePermissionVO, Long>
{
 
+    AclRolePermissionVO findByRoleEntityAndPermission(long roleId, String entityType, AccessType
accessType, boolean isAllowed);
+
+    AclRolePermissionVO findByRoleAndEntity(long roleId, String entityType, AccessType accessType);
+
     List<AclRolePermissionVO> listByRoleAndEntity(long roleId, String entityType, AccessType
accessType);
 
     List<AclRolePermissionVO> listByRole(long roleId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDaoImpl.java
b/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDaoImpl.java
index ee34470..9ae81b2 100644
--- a/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDaoImpl.java
+++ b/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDaoImpl.java
@@ -49,12 +49,34 @@ public class AclRolePermissionDaoImpl extends GenericDaoBase<AclRolePermissionVO
         findByRoleEntity.or("entityTypeStar", findByRoleEntity.entity().getEntityType(),
SearchCriteria.Op.EQ);
         findByRoleEntity.cp();
         findByRoleEntity.and("accessType", findByRoleEntity.entity().getAccessType(), SearchCriteria.Op.EQ);
+        findByRoleEntity.and("allowed", findByRoleEntity.entity().isAllowed(), SearchCriteria.Op.EQ);
         findByRoleEntity.done();
 
         return true;
     }
 
     @Override
+    public AclRolePermissionVO findByRoleEntityAndPermission(long roleId, String entityType,
AccessType accessType, boolean isAllowed) {
+        SearchCriteria<AclRolePermissionVO> sc = findByRoleEntity.create();
+        sc.setParameters("roleId", roleId);
+        sc.setParameters("entityType", entityType);
+        sc.setParameters("accessType", accessType);
+        sc.setParameters("entityTypeStar", "*");
+        sc.setParameters("allowed", isAllowed);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public AclRolePermissionVO findByRoleAndEntity(long roleId, String entityType, AccessType
accessType) {
+        SearchCriteria<AclRolePermissionVO> sc = findByRoleEntity.create();
+        sc.setParameters("roleId", roleId);
+        sc.setParameters("entityType", entityType);
+        sc.setParameters("accessType", accessType);
+        sc.setParameters("entityTypeStar", "*");
+        return findOneBy(sc);
+    }
+
+    @Override
     public List<AclRolePermissionVO> listByRoleAndEntity(long roleId, String entityType,
AccessType accessType) {
         SearchCriteria<AclRolePermissionVO> sc = findByRoleEntity.create();
         sc.setParameters("roleId", roleId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/server/src/com/cloud/api/query/QueryManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java
index 3f27915..04d5964 100644
--- a/server/src/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
@@ -30,9 +30,12 @@ import javax.inject.Inject;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
+import org.apache.cloudstack.acl.AclEntityType;
 import org.apache.cloudstack.acl.AclGroup;
 import org.apache.cloudstack.acl.AclRole;
+import org.apache.cloudstack.acl.AclService;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 import org.apache.cloudstack.acl.dao.AclGroupDao;
 import org.apache.cloudstack.acl.dao.AclRoleDao;
 import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
@@ -349,6 +352,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService
{
     @Inject
     AclGroupDao _aclGroupDao;
 
+    @Inject
+    AclService _aclService;
+
     /*
      * (non-Javadoc)
      *
@@ -730,6 +736,11 @@ public class QueryManagerImpl extends ManagerBase implements QueryService
{
         Account caller = CallContext.current().getCallingAccount();
         List<Long> permittedAccounts = new ArrayList<Long>();
 
+        // get granted or denied entity instance permissions
+        Pair<List<Long>, List<Long>> idPair = _aclService.getAclEntityPermission(caller.getId(),
AclEntityType.VM.toString(), AccessType.ListEntry);
+        List<Long> grantedIds = idPair.first();
+        List<Long> revokedIds = idPair.second();
+
         boolean listAll = cmd.listAll();
         Long id = cmd.getId();
         Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject
= new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
@@ -745,10 +756,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService
{
 
         // first search distinct vm id by using query criteria and pagination
         SearchBuilder<UserVmJoinVO> sb = _userVmJoinDao.createSearchBuilder();
-        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
-        // ids
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct ids
         _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts,
-                listProjectResourcesCriteria);
+                listProjectResourcesCriteria, grantedIds, revokedIds);
 
         Map<String, String> tags = cmd.getTags();
         String hypervisor = cmd.getHypervisor();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/server/src/com/cloud/user/AccountManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java
index 2e909c8..0fac6ed 100755
--- a/server/src/com/cloud/user/AccountManager.java
+++ b/server/src/com/cloud/user/AccountManager.java
@@ -90,6 +90,9 @@ public interface AccountManager extends AccountService {
     void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb,
Long domainId,
             boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria
listProjectResourcesCriteria);
 
+    void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb,
Long domainId,
+            boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria
listProjectResourcesCriteria, List<Long> grantedIds, List<Long> revokedIds);
+
 	void buildACLSearchCriteria(SearchCriteria<? extends ControlledEntity> sc,
 			Long domainId, boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria
listProjectResourcesCriteria);
 
@@ -140,7 +143,7 @@ public interface AccountManager extends AccountService {
      * @param accountId
      * @return account object
      */
-    Account enableAccount(String accountName, Long domainId, Long accountId); 
+    Account enableAccount(String accountName, Long domainId, Long accountId);
     
     /**
      * Deletes user by Id
@@ -155,7 +158,7 @@ public interface AccountManager extends AccountService {
      * @param userId
      * @return UserAccount object
      */
-    UserAccount updateUser(UpdateUserCmd cmd);   
+    UserAccount updateUser(UpdateUserCmd cmd);
     
     /**
      * Disables a user by userId
@@ -187,5 +190,5 @@ public interface AccountManager extends AccountService {
      * @param accountId
      * @return account object
      */
-    Account lockAccount(String accountName, Long domainId, Long accountId);    
+    Account lockAccount(String accountName, Long domainId, Long accountId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/server/src/com/cloud/user/AccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java
index de528f1..db21b3d 100755
--- a/server/src/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/com/cloud/user/AccountManagerImpl.java
@@ -40,12 +40,17 @@ import javax.naming.ConfigurationException;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.log4j.Logger;
 
+import org.apache.cloudstack.acl.AclEntityType;
 import org.apache.cloudstack.acl.AclGroupAccountMapVO;
+import org.apache.cloudstack.acl.AclRolePermission;
+import org.apache.cloudstack.acl.AclService;
 import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.PermissionScope;
 import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.acl.SecurityChecker;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 import org.apache.cloudstack.acl.dao.AclGroupAccountMapDao;
+import org.apache.cloudstack.acl.dao.AclRolePermissionDao;
 import org.apache.cloudstack.affinity.AffinityGroup;
 import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
 import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
@@ -253,6 +258,12 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager,
M
     private AclGroupAccountMapDao _aclGroupAccountDao;
 
     @Inject
+    private AclService _aclService;
+
+    @Inject
+    private AclRolePermissionDao _aclRolePermissionDao;
+
+    @Inject
     public com.cloud.region.ha.GlobalLoadBalancingRulesService _gslbService;
 
     private List<UserAuthenticator> _userAuthenticators;
@@ -2194,6 +2205,93 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager,
M
         }
     }
 
+//    @Override
+//    public void buildACLSearchParameters(Account caller, Long id, String accountName, Long
projectId, List<Long>
+//    permittedAccounts, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject,
+//            boolean listAll, boolean forProjectInvitation) {
+//        Long domainId = domainIdRecursiveListProject.first();
+//        if (domainId != null) {
+//            Domain domain = _domainDao.findById(domainId);
+//            if (domain == null) {
+//                throw new InvalidParameterValueException("Unable to find domain by id "
+ domainId);
+//            }
+//            // check permissions
+//            checkAccess(caller, domain);
+//        }
+//
+//        if (accountName != null) {
+//            if (projectId != null) {
+//                throw new InvalidParameterValueException("Account and projectId can't be
specified together");
+//            }
+//
+//            Account userAccount = null;
+//            Domain domain = null;
+//            if (domainId != null) {
+//                userAccount = _accountDao.findActiveAccount(accountName, domainId);
+//                domain = _domainDao.findById(domainId);
+//            } else {
+//                userAccount = _accountDao.findActiveAccount(accountName, caller.getDomainId());
+//                domain = _domainDao.findById(caller.getDomainId());
+//            }
+//
+//            if (userAccount != null) {
+//                checkAccess(caller, null, false, userAccount);
+//                //check permissions
+//                permittedAccounts.add(userAccount.getId());
+//            } else {
+//                throw new InvalidParameterValueException("could not find account " + accountName
+ " in domain " + domain.getUuid());
+//            }
+//        }
+//
+//        // set project information
+//        if (projectId != null) {
+//            if (!forProjectInvitation) {
+//                if (projectId.longValue() == -1) {
+//                    if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+//                        permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId()));
+//                    } else {
+//                        domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.ListProjectResourcesOnly);
+//                    }
+//                } else {
+//                    Project project = _projectMgr.getProject(projectId);
+//                    if (project == null) {
+//                        throw new InvalidParameterValueException("Unable to find project
by id " + projectId);
+//                    }
+//                    if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId()))
{
+//                        throw new PermissionDeniedException("Account " + caller + " can't
access project id=" + projectId);
+//                    }
+//                    permittedAccounts.add(project.getProjectAccountId());
+//                }
+//            }
+//        } else {
+//            if (id == null) {
+//                domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources);
+//            }
+//            if (permittedAccounts.isEmpty() && domainId == null) {
+//                if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+//                    permittedAccounts.add(caller.getId());
+//                } else if (!listAll) {
+//                    if (id == null) {
+//                        permittedAccounts.add(caller.getId());
+//                    } else if (!isRootAdmin(caller.getId())) {
+//                        domainIdRecursiveListProject.first(caller.getDomainId());
+//                        domainIdRecursiveListProject.second(true);
+//                    }
+//                } else if (domainId == null) {
+//                    if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
+//                        domainIdRecursiveListProject.first(caller.getDomainId());
+//                        domainIdRecursiveListProject.second(true);
+//                    }
+//                }
+//            } else if (domainId != null) {
+//                if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+//                    permittedAccounts.add(caller.getId());
+//                }
+//            }
+//
+//        }
+//    }
+
     @Override
     public void buildACLSearchParameters(Account caller, Long id, String accountName, Long
projectId, List<Long>
     permittedAccounts, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject,
@@ -2208,6 +2306,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager,
M
             checkAccess(caller, domain);
         }
 
+        if (id != null) {
+            // look for an individual entity, no other permission criteria are needed
+            return;
+        }
+
         if (accountName != null) {
             if (projectId != null) {
                 throw new InvalidParameterValueException("Account and projectId can't be
specified together");
@@ -2253,34 +2356,27 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager,
M
                 }
             }
         } else {
-            if (id == null) {
-                domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources);
-            }
-            if (permittedAccounts.isEmpty() && domainId == null) {
-                if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
-                    permittedAccounts.add(caller.getId());
-                } else if (!listAll) {
-                    if (id == null) {
-                        permittedAccounts.add(caller.getId());
-                    } else if (!isRootAdmin(caller.getId())) {
-                        domainIdRecursiveListProject.first(caller.getDomainId());
-                        domainIdRecursiveListProject.second(true);
-                    }
-                } else if (domainId == null) {
-                    if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
-                        domainIdRecursiveListProject.first(caller.getDomainId());
-                        domainIdRecursiveListProject.second(true);
-                    }
-                }
-            } else if (domainId != null) {
-                if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+            domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources);
+            // get caller role permission on VM List
+            AclRolePermission rolePerm = _aclService.getAclRolePermission(caller.getId(),
AclEntityType.VM.toString(), AccessType.ListEntry);
+            if (rolePerm == null) {
+                // no list entry permission
+                throw new PermissionDeniedException("Caller has no role permission assigned
to list VM");
+            }
+            if (permittedAccounts.isEmpty()) {
+                // no account name is specified
+                if (rolePerm.getScope() == PermissionScope.ACCOUNT || !listAll) {
+                    // only resource owner can see it, only match account
                     permittedAccounts.add(caller.getId());
+                } else {
+                    // match domain tree based on cmd.isRecursive flag or not
+                    domainIdRecursiveListProject.first(caller.getDomainId());
                 }
             }
-
         }
     }
 
+
     @Override
     public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity>
sb, Long domainId,
             boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria
listProjectResourcesCriteria) {
@@ -2305,6 +2401,35 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager,
M
     }
 
     @Override
+    public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity>
sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria, List<Long> grantedIds,
List<Long> revokedIds) {
+        sb.and().op("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN);
+        sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
+
+        if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive))
{
+            // if accountId isn't specified, we can do a domain match for the
+            // admin case if isRecursive is true
+            sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
+        }
+
+        if (listProjectResourcesCriteria != null) {
+            if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly)
{
+                sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.EQ);
+            } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources)
{
+                sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.NEQ);
+            }
+        }
+        if (!grantedIds.isEmpty()) {
+            sb.or("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
+        }
+        sb.cp();
+        if (!revokedIds.isEmpty()) {
+            sb.and("idNIN", sb.entity().getId(), SearchCriteria.Op.NIN);
+        }
+
+    }
+
+    @Override
     public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity>
sc,
             Long domainId, boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria
listProjectResourcesCriteria) {
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/server/src/org/apache/cloudstack/acl/AclServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/acl/AclServiceImpl.java b/server/src/org/apache/cloudstack/acl/AclServiceImpl.java
index c7990eb..85d70ac 100644
--- a/server/src/org/apache/cloudstack/acl/AclServiceImpl.java
+++ b/server/src/org/apache/cloudstack/acl/AclServiceImpl.java
@@ -18,7 +18,9 @@ package org.apache.cloudstack.acl;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import javax.ejb.Local;
 import javax.inject.Inject;
@@ -47,6 +49,7 @@ import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.user.dao.AccountDao;
 import com.cloud.uservm.UserVm;
+import com.cloud.utils.Pair;
 import com.cloud.utils.component.Manager;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.db.DB;
@@ -554,6 +557,67 @@ public class AclServiceImpl extends ManagerBase implements AclService,
Manager {
     }
 
     @Override
+    public AclRolePermission getAclRolePermission(long accountId, String entityType, AccessType
accessType) {
+        List<AclRole> roles = getAclRoles(accountId);
+        AclRolePermission curPerm = null;
+        for (AclRole role : roles) {
+            AclRolePermission perm = _rolePermissionDao.findByRoleEntityAndPermission(role.getId(),
entityType, accessType, true);
+            if (perm == null)
+                continue;
+            if (curPerm == null) {
+                curPerm = perm;
+            } else if (perm.getScope().greaterThan(curPerm.getScope())) {
+                // pick the more relaxed allowed permission
+                curPerm = perm;
+            }
+        }
+
+        return curPerm;
+    }
+
+    @Override
+    public List<AclGroup> getAclGroups(long accountId) {
+
+        GenericSearchBuilder<AclGroupAccountMapVO, Long> groupSB = _aclGroupAccountMapDao.createSearchBuilder(Long.class);
+        groupSB.selectField(groupSB.entity().getAclGroupId());
+        groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ);
+        SearchCriteria<Long> groupSc = groupSB.create();
+
+        List<Long> groupIds = _aclGroupAccountMapDao.customSearch(groupSc, null);
+
+        SearchBuilder<AclGroupVO> sb = _aclGroupDao.createSearchBuilder();
+        sb.and("ids", sb.entity().getId(), Op.IN);
+        SearchCriteria<AclGroupVO> sc = sb.create();
+        sc.setParameters("ids", groupIds.toArray(new Object[groupIds.size()]));
+        List<AclGroupVO> groups = _aclGroupDao.search(sc, null);
+
+        return new ArrayList<AclGroup>(groups);
+    }
+
+    @Override
+    public Pair<List<Long>, List<Long>> getAclEntityPermission(long accountId,
String entityType, AccessType accessType) {
+        List<AclGroup> groups = getAclGroups(accountId);
+        if (groups == null || groups.size() == 0) {
+            return new Pair<List<Long>, List<Long>>(new ArrayList<Long>(),
new ArrayList<Long>());
+        }
+        Set<Long> allowedIds = new HashSet<Long>();
+        Set<Long> deniedIds = new HashSet<Long>();
+        for (AclGroup grp : groups) {
+            // get allowed id  and denied list for each group
+            List<Long> allowedIdList = _entityPermissionDao.findEntityIdByGroupAndPermission(grp.getId(),
entityType, accessType, true);
+            if (allowedIdList != null) {
+                allowedIds.addAll(allowedIdList);
+            }
+            List<Long> deniedIdList = _entityPermissionDao.findEntityIdByGroupAndPermission(grp.getId(),
entityType, accessType, false);
+            if (deniedIdList != null) {
+                deniedIds.addAll(deniedIdList);
+            }
+        }
+        return new Pair<List<Long>, List<Long>>(new ArrayList<Long>(allowedIds),
new ArrayList<Long>(deniedIds))
+        ;
+    }
+
+    @Override
     public boolean isAPIAccessibleForRoles(String apiName, List<AclRole> roles) {
 
         boolean accessible = false;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2b4703b6/server/test/com/cloud/user/MockAccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java
index 3638eb2..a933e70 100644
--- a/server/test/com/cloud/user/MockAccountManagerImpl.java
+++ b/server/test/com/cloud/user/MockAccountManagerImpl.java
@@ -287,6 +287,13 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager,
Acco
     }
 
     @Override
+    public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity>
sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria, List<Long> grantedIds,
List<Long> revokedIds) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
     public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity>
sc, Long domainId,
             boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria
listProjectResourcesCriteria) {
         // TODO Auto-generated method stub


Mime
View raw message