Changes to RoleBasedEntityAccessChecker to replace Role by Policy

This commit is contained in:
Prachi Damle 2013-12-12 16:25:38 -08:00
parent 1a985227b5
commit d2c74bcf14
4 changed files with 39 additions and 79 deletions

View File

@ -22,6 +22,7 @@ import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.cloudstack.acl.APIChecker;
import org.apache.cloudstack.acl.AclPolicy;
import org.apache.cloudstack.acl.AclRole;
import org.apache.cloudstack.acl.AclService;
import org.apache.log4j.Logger;
@ -54,10 +55,10 @@ public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker
throw new PermissionDeniedException("The account id=" + user.getAccountId() + "for user id=" + user.getId() + "is null");
}
List<AclRole> roles = _aclService.listAclPolicies(account.getAccountId());
List<AclPolicy> policies = _aclService.listAclPolicies(account.getAccountId());
boolean isAllowed = _aclService.isAPIAccessibleForPolicies(commandName, roles);
boolean isAllowed = _aclService.isAPIAccessibleForPolicies(commandName, policies);
if (!isAllowed) {
throw new PermissionDeniedException("The API does not exist or is blacklisted. api: " + commandName);
}

View File

@ -21,28 +21,20 @@ import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.acl.AclEntityPermissionVO;
import org.apache.cloudstack.acl.AclEntityType;
import org.apache.cloudstack.acl.AclGroupAccountMapVO;
import org.apache.cloudstack.acl.AclRole;
import org.apache.cloudstack.acl.AclRolePermissionVO;
import org.apache.cloudstack.acl.AclPolicy;
import org.apache.cloudstack.acl.AclPolicyPermissionVO;
import org.apache.cloudstack.acl.AclService;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.AclEntityType;
import org.apache.cloudstack.acl.PermissionScope;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.acl.dao.AclEntityPermissionDao;
import org.apache.cloudstack.acl.dao.AclGroupAccountMapDao;
import org.apache.cloudstack.acl.dao.AclGroupDao;
import org.apache.cloudstack.acl.dao.AclRolePermissionDao;
import org.apache.cloudstack.api.InternalIdentity;
import org.apache.cloudstack.acl.dao.AclPolicyPermissionDao;
import org.apache.log4j.Logger;
import com.cloud.acl.DomainChecker;
import com.cloud.api.ApiDispatcher;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.user.AccountService;
import com.cloud.vm.VirtualMachine;
@ -62,10 +54,8 @@ public class RoleBasedEntityAccessChecker extends DomainChecker implements Secur
AclGroupAccountMapDao _aclGroupAccountMapDao;
@Inject
AclEntityPermissionDao _entityPermissionDao;
AclPolicyPermissionDao _policyPermissionDao;
@Inject
AclRolePermissionDao _rolePermissionDao;
@Override
public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType)
@ -76,71 +66,42 @@ public class RoleBasedEntityAccessChecker extends DomainChecker implements Secur
@Override
public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType, String action)
throws PermissionDeniedException {
if (entity instanceof VirtualMachine) {
String entityType = AclEntityType.VM.toString();
String entityType = entity.getEntityType().toString();
if (accessType == null) {
accessType = AccessType.ListEntry;
}
if (accessType == null) {
accessType = AccessType.ListEntry;
}
// check if explicit allow/deny is present for this entity in
// acl_entity_permission
// get all Policies of this caller w.r.t the entity
List<AclPolicy> policies = _aclService.getEffectivePolicies(caller, entity);
HashMap<AclPolicy, Boolean> policyPermissionMap = new HashMap<AclPolicy, Boolean>();
if (entity instanceof InternalIdentity) {
InternalIdentity entityWithId = (InternalIdentity) entity;
List<AclGroupAccountMapVO> acctGroups = _aclGroupAccountMapDao.listByAccountId(caller.getId());
for (AclGroupAccountMapVO groupMapping : acctGroups) {
AclEntityPermissionVO entityPermission = _entityPermissionDao.findByGroupAndEntity(
groupMapping.getAclGroupId(), entityType, entityWithId.getId(), accessType);
if (entityPermission != null) {
if (entityPermission.isAllowed()) {
return true;
} else {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Account " + caller + " does not have permission to access resource "
+ entity + " for access type: " + accessType);
}
throw new PermissionDeniedException(caller
+ " does not have permission to access resource " + entity);
}
for (AclPolicy policy : policies) {
List<AclPolicyPermissionVO> permissions = _policyPermissionDao.listByPolicyActionAndEntity(policy.getId(),
action, entityType);
for (AclPolicyPermissionVO permission : permissions) {
if (checkPermissionScope(caller, permission.getScope(), entity)) {
if (permission.getEntityType().equals(entityType)) {
policyPermissionMap.put(policy, permission.getPermission().isGranted());
break;
} else if (permission.getEntityType().equals("*")) {
policyPermissionMap.put(policy, permission.getPermission().isGranted());
}
}
}
// get all Roles of this caller w.r.t the entity
List<AclRole> roles = _aclService.getEffectivePolicies(caller, entity);
HashMap<AclRole, Boolean> rolePermissionMap = new HashMap<AclRole, Boolean>();
for (AclRole role : roles) {
List<AclRolePermissionVO> permissions = _rolePermissionDao.listByRoleAndEntity(role.getId(),
entityType, accessType);
for (AclRolePermissionVO permission : permissions) {
if (checkPermissionScope(caller, permission.getScope(), entity)) {
if (permission.getEntityType().equals(entityType)) {
rolePermissionMap.put(role, permission.isAllowed());
break;
} else if (permission.getEntityType().equals("*")) {
rolePermissionMap.put(role, permission.isAllowed());
}
}
}
if (rolePermissionMap.containsKey(role) && rolePermissionMap.get(role)) {
return true;
}
if (policyPermissionMap.containsKey(policy) && policyPermissionMap.get(policy)) {
return true;
}
}
if (!roles.isEmpty()) { // Since we reach this point, none of the
// roles granted access
if (s_logger.isDebugEnabled()) {
s_logger.debug("Account " + caller + " does not have permission to access resource " + entity
+ " for access type: " + accessType);
}
throw new PermissionDeniedException(caller + " does not have permission to access resource " + entity);
if (!policies.isEmpty()) { // Since we reach this point, none of the
// roles granted access
if (s_logger.isDebugEnabled()) {
s_logger.debug("Account " + caller + " does not have permission to access resource " + entity
+ " for access type: " + accessType);
}
throw new PermissionDeniedException(caller + " does not have permission to access resource " + entity);
}
return false;

View File

@ -365,7 +365,7 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
@Override
public List<AclPolicy> listAclPolicies(long accountId) {
// static roles of the account
// static policies of the account
SearchBuilder<AclGroupAccountMapVO> groupSB = _aclGroupAccountMapDao.createSearchBuilder();
groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ);
@ -377,12 +377,12 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
SearchCriteria<Long> policySc = policySB.create();
policySc.setJoinParameters("accountgroupjoin", "account", accountId);
List<Long> roleIds = _aclGroupPolicyMapDao.customSearch(policySc, null);
List<Long> policyIds = _aclGroupPolicyMapDao.customSearch(policySc, null);
SearchBuilder<AclPolicyVO> sb = _aclPolicyDao.createSearchBuilder();
sb.and("ids", sb.entity().getId(), Op.IN);
SearchCriteria<AclPolicyVO> sc = sb.create();
sc.setParameters("ids", roleIds.toArray(new Object[roleIds.size()]));
sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()]));
List<AclPolicyVO> policies = _aclPolicyDao.customSearch(sc, null);
return new ArrayList<AclPolicy>(policies);
@ -647,7 +647,6 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
SearchBuilder<AclPolicyPermissionVO> sb = _policyPermissionDao.createSearchBuilder();
sb.and("action", sb.entity().getAction(), Op.EQ);
sb.and("policyId", sb.entity().getAclPolicyId(), Op.IN);
sb.and("entityType", sb.entity().getEntityType(), Op.NULL);
SearchCriteria<AclPolicyPermissionVO> sc = sb.create();
sc.setParameters("policyId", policyIds.toArray(new Object[policyIds.size()]));
@ -667,7 +666,7 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
// Get the static Policies of the Caller
List<AclPolicy> policies = listAclPolicies(caller.getId());
// add any dynamic roles w.r.t the entity
// add any dynamic policies w.r.t the entity
if (caller.getId() == entity.getAccountId()) {
// The caller owns the entity
AclPolicy owner = _aclPolicyDao.findByName(Domain.ROOT_DOMAIN, "RESOURCE_OWNER");

View File

@ -378,8 +378,7 @@ INSERT IGNORE INTO `cloud`.`acl_policy` (id, name, description, uuid, domain_id,
INSERT IGNORE INTO `cloud`.`acl_policy` (id, name, description, uuid, domain_id, account_id, created, policy_type) VALUES (3, 'DOMAIN_ADMIN', 'Domain admin role', UUID(), 1, 1, Now(), 'Static');
INSERT IGNORE INTO `cloud`.`acl_policy` (id, name, description, uuid, domain_id, account_id, created, policy_type) VALUES (4, 'RESOURCE_DOMAIN_ADMIN', 'Resource domain admin role', UUID(), 1, 1, Now(), 'Static');
INSERT IGNORE INTO `cloud`.`acl_policy` (id, name, description, uuid, domain_id, account_id, created, policy_type) VALUES (5, 'READ_ONLY_ADMIN', 'Read only admin role', UUID(), 1, 1, Now(), 'Static');
-- RESOURCE_OWNER dynamic policy we will handle that inside java logic
-- INSERT IGNORE INTO `cloud`.`acl_policy` (id, name, description, uuid, domain_id, account_id, created, policy_type) VALUES (6, 'RESOURCE_OWNER', 'Resource owner role', UUID(), 1, 1, Now(), 'Dynamic');
INSERT IGNORE INTO `cloud`.`acl_policy` (id, name, description, uuid, domain_id, account_id, created, policy_type) VALUES (6, 'RESOURCE_OWNER', 'Resource owner role', UUID(), 1, 1, Now(), 'Dynamic');
INSERT IGNORE INTO `cloud`.`acl_group` (id, name, description, uuid, domain_id, account_id, created) VALUES (1, 'NORMAL', 'Domain user group', UUID(), 1, 1, Now());