mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
Changes to RoleBasedEntityAccessChecker to replace Role by Policy
This commit is contained in:
parent
1a985227b5
commit
d2c74bcf14
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user