You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2014/01/30 02:59:56 UTC

git commit: updated refs/heads/rbac to 81323dc

Updated Branches:
  refs/heads/rbac 0063b6070 -> 81323dce5


Add support to grant acl permission to access an individual resource.

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

Branch: refs/heads/rbac
Commit: 81323dce5de93f88f4cb2a3bd4d07306afeed160
Parents: 0063b60
Author: Min Chen <mi...@citrix.com>
Authored: Wed Jan 29 17:59:24 2014 -0800
Committer: Min Chen <mi...@citrix.com>
Committed: Wed Jan 29 17:59:24 2014 -0800

----------------------------------------------------------------------
 .../cloudstack/acl/api/AclApiService.java       |  4 ++
 .../cloudstack/acl/api/AclApiServiceImpl.java   | 50 ++++++++++++++++++++
 .../apache/cloudstack/iam/api/IAMService.java   |  2 +
 .../cloudstack/iam/server/IAMServiceImpl.java   | 23 +++++++++
 utils/src/com/cloud/utils/db/EntityManager.java |  1 +
 5 files changed, 80 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/81323dce/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java
index eb08de5..8b96495 100644
--- a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java
+++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java
@@ -19,6 +19,7 @@ package org.apache.cloudstack.acl.api;
 import java.util.List;
 
 import org.apache.cloudstack.acl.PermissionScope;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 import org.apache.cloudstack.acl.api.response.AclGroupResponse;
 import org.apache.cloudstack.acl.api.response.AclPolicyResponse;
 import org.apache.cloudstack.api.response.ListResponse;
@@ -64,6 +65,9 @@ public interface AclApiService extends PluggableService {
 
     AclPolicyPermission getAclPolicyPermission(long accountId, String entityType, String action);
 
+    /* Utility routine to grant invidivual resource to list of accounts */
+    void grantEntityPermissioinToAccounts(String entityType, Long entityId, AccessType accessType, String action, List<Long> accountIds);
+
     /* Response Generation */
     AclPolicyResponse createAclPolicyResponse(AclPolicy policy);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/81323dce/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java
index c3c9caa..ee33620 100644
--- a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java
+++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java
@@ -17,6 +17,7 @@
 package org.apache.cloudstack.acl.api;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -47,6 +48,7 @@ import org.apache.cloudstack.acl.api.command.RemoveAclPolicyFromAclGroupCmd;
 import org.apache.cloudstack.acl.api.response.AclGroupResponse;
 import org.apache.cloudstack.acl.api.response.AclPermissionResponse;
 import org.apache.cloudstack.acl.api.response.AclPolicyResponse;
+import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseListCmd;
 import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.cloudstack.context.CallContext;
@@ -179,6 +181,22 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
             }
         });
 
+        _messageBus.subscribe(EntityManager.MESSAGE_GRANT_ENTITY_EVENT, new MessageSubscriber() {
+            @Override
+            public void onPublishMessage(String senderAddress, String subject, Object obj) {
+                Map<String, Object> permit = (Map<String, Object>)obj;
+                if (permit != null) {
+                    String entityType = (String)permit.get(ApiConstants.ENTITY_TYPE);
+                    Long entityId = (Long)permit.get(ApiConstants.ENTITY_ID);
+                    AccessType accessType = (AccessType)permit.get(ApiConstants.ACCESS_TYPE);
+                    String action = (String)permit.get(ApiConstants.ACL_ACTION);
+                    List<Long> acctIds = (List<Long>)permit.get(ApiConstants.ACCOUNTS);
+                    s_logger.debug("MessageBus message: grant permission to an entity: (" + entityType + "," + entityId + ")");
+                    grantEntityPermissioinToAccounts(entityType, entityId, accessType, action, acctIds);
+                }
+            }
+        });
+
         return super.configure(name, params);
     }
 
@@ -470,6 +488,38 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
     }
 
     @Override
+    public void grantEntityPermissioinToAccounts(String entityType, Long entityId, AccessType accessType, String action, List<Long> accountIds) {
+        // check if there is already a policy with only this permission added to it
+        AclPolicy policy = _iamSrv.getResourceGrantPolicy(entityType, entityId, accessType.toString(), action);
+        if (policy == null) {
+            // not found, just create a policy with resource grant permission
+            Account caller = CallContext.current().getCallingAccount();
+            String aclPolicyName = "policyGrant" + entityType + entityId;
+            String description = "Policy to grant permission to " + entityType + entityId;
+            policy = createAclPolicy(caller, aclPolicyName, description, null);
+            // add permission to this policy
+            addAclPermissionToAclPolicy(policy.getId(), entityType, PermissionScope.RESOURCE, entityId, action, Permission.Allow);
+        }
+        // attach this policy to list of accounts if not attached already
+        Long policyId = policy.getId();
+        for (Long acctId : accountIds) {
+            if (!isPolicyAttachedToAccount(policyId, acctId)) {
+                attachAclPolicyToAccounts(policyId, Collections.singletonList(acctId));
+            }
+        }
+    }
+
+    private boolean isPolicyAttachedToAccount(Long policyId, Long accountId) {
+        List<AclPolicy> pList = listAclPolicies(accountId);
+        for (AclPolicy p : pList) {
+            if (p.getId() == policyId.longValue()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
     public List<Class<?>> getCommands() {
         List<Class<?>> cmdList = new ArrayList<Class<?>>();
         cmdList.add(CreateAclPolicyCmd.class);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/81323dce/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java
----------------------------------------------------------------------
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java b/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java
index 98aec5d..76fab05 100644
--- a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java
+++ b/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java
@@ -66,6 +66,8 @@ public interface IAMService {
 
     void removeAclPermissionForEntity(final String entityType, final Long entityId);
 
+    AclPolicy getResourceGrantPolicy(String entityType, Long entityId, String accessType, String action);
+
     AclPolicy getResourceOwnerPolicy();
 
     List<AclPolicyPermission> listPolicyPermissions(long policyId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/81323dce/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
----------------------------------------------------------------------
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
index d2b173e..11116b0 100644
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
+++ b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
@@ -24,6 +24,7 @@ import javax.inject.Inject;
 
 import org.apache.log4j.Logger;
 
+import org.apache.cloudstack.acl.PermissionScope;
 import org.apache.cloudstack.iam.api.AclGroup;
 import org.apache.cloudstack.iam.api.AclPolicy;
 import org.apache.cloudstack.iam.api.AclPolicyPermission;
@@ -387,6 +388,7 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager {
         return policies;
     }
 
+
     @SuppressWarnings("unchecked")
     @Override
     public Pair<List<AclPolicy>, Integer> listAclPolicies(Long aclPolicyId, String aclPolicyName, String path, Long startIndex, Long pageSize) {
@@ -706,4 +708,25 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager {
         return _aclPolicyDao.findByName("RESOURCE_OWNER");
     }
 
+    // search for policy with only one resource grant permission
+    @Override
+    public AclPolicy getResourceGrantPolicy(String entityType, Long entityId, String accessType, String action) {
+        List<AclPolicyVO> policyList = _aclPolicyDao.listAll();
+        for (AclPolicyVO policy : policyList){
+            List<AclPolicyPermission> pp = listPolicyPermissions(policy.getId());
+            if ( pp != null && pp.size() == 1){
+                // resource grant policy should only have one ACL permission assigned
+                AclPolicyPermission permit = pp.get(0);
+                if ( permit.getEntityType().equals(entityType) && permit.getScope().equals(PermissionScope.RESOURCE.toString()) && permit.getScopeId().longValue() == entityId.longValue()){
+                    if (accessType != null && permit.getAccessType().equals(accessType)){
+                        return policy;
+                    } else if (action != null && permit.getAction().equals(action)) {
+                        return policy;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/81323dce/utils/src/com/cloud/utils/db/EntityManager.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/EntityManager.java b/utils/src/com/cloud/utils/db/EntityManager.java
index aed5bcb..3226e90 100644
--- a/utils/src/com/cloud/utils/db/EntityManager.java
+++ b/utils/src/com/cloud/utils/db/EntityManager.java
@@ -72,4 +72,5 @@ public interface EntityManager {
     public <T, K extends Serializable> void remove(Class<T> entityType, K id);
 
     public static final String MESSAGE_REMOVE_ENTITY_EVENT = "Message.RemoveEntity.Event";
+    public static final String MESSAGE_GRANT_ENTITY_EVENT = "Message.GrantEntity.Event";
 }