mirror of https://github.com/apache/cloudstack.git
Add support to grant acl permission to access an individual resource.
This commit is contained in:
parent
0063b60701
commit
81323dce5d
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -469,6 +487,38 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
|
|||
return response;
|
||||
}
|
||||
|
||||
@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<?>>();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue