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";
}