mirror of https://github.com/apache/cloudstack.git
- Adding OperateEntry during loading of commands
- Replace ListEntry By OperateEntry - ApiDispatcher should pass on the API name
This commit is contained in:
parent
39c0a302b4
commit
96a64b933e
|
|
@ -108,6 +108,9 @@ public interface AccountService {
|
|||
|
||||
void checkAccess(Account account, AccessType accessType, boolean sameOwner, ControlledEntity... entities) throws PermissionDeniedException;
|
||||
|
||||
void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName,
|
||||
ControlledEntity... entities) throws PermissionDeniedException;
|
||||
|
||||
//TO be implemented, to check accessibility for an entity owned by domain
|
||||
void checkAccess(Account account, AccessType accessType, boolean sameOwner, PartOf... entities) throws PermissionDeniedException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ public interface SecurityChecker extends Adapter {
|
|||
ModifyProject,
|
||||
UseNetwork,
|
||||
DeleteEntry,
|
||||
OperateEntry
|
||||
OperateEntry,
|
||||
UseEntry
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import org.apache.cloudstack.acl.InfrastructureEntity;
|
|||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.ACL;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
|
|
@ -107,19 +108,14 @@ public class ApiDispatcher {
|
|||
|
||||
private void doAccessChecks(BaseCmd cmd, Map<Object, AccessType> entitiesToAccess) {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId());
|
||||
|
||||
if (cmd instanceof BaseAsyncCreateCmd) {
|
||||
//check that caller can access the owner account.
|
||||
_accountMgr.checkAccess(caller, null, true, owner);
|
||||
}
|
||||
APICommand commandAnnotation = cmd.getClass().getAnnotation(APICommand.class);
|
||||
String apiName = commandAnnotation != null ? commandAnnotation.name() : null;
|
||||
|
||||
if (!entitiesToAccess.isEmpty()) {
|
||||
//check that caller can access the owner account.
|
||||
_accountMgr.checkAccess(caller, null, true, owner);
|
||||
for (Object entity : entitiesToAccess.keySet()) {
|
||||
if (entity instanceof ControlledEntity) {
|
||||
_accountMgr.checkAccess(caller, entitiesToAccess.get(entity), true, (ControlledEntity)entity);
|
||||
_accountMgr.checkAccess(caller, entitiesToAccess.get(entity), false, apiName, (ControlledEntity) entity);
|
||||
} else if (entity instanceof InfrastructureEntity) {
|
||||
//FIXME: Move this code in adapter, remove code from Account manager
|
||||
}
|
||||
|
|
|
|||
|
|
@ -447,6 +447,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
@Override
|
||||
public void checkAccess(Account caller, AccessType accessType, boolean sameOwner, ControlledEntity... entities) {
|
||||
checkAccess(caller, accessType, sameOwner, null, entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkAccess(Account caller, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) {
|
||||
//check for the same owner
|
||||
Long ownerId = null;
|
||||
ControlledEntity prevEntity = null;
|
||||
|
|
@ -492,7 +497,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
}
|
||||
boolean granted = false;
|
||||
for (SecurityChecker checker : _securityCheckers) {
|
||||
if (checker.checkAccess(caller, entity, accessType)) {
|
||||
if (checker.checkAccess(caller, entity, accessType, apiName)) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Access to " + entity + " granted to " + caller + " by " + checker.getName());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,11 @@ import org.apache.log4j.Logger;
|
|||
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.BaseListCmd;
|
||||
import org.apache.cloudstack.iam.api.AclPolicy;
|
||||
import org.apache.cloudstack.iam.api.AclPolicyPermission;
|
||||
import org.apache.cloudstack.iam.api.AclPolicyPermission.Permission;
|
||||
import org.apache.cloudstack.iam.api.IAMService;
|
||||
|
||||
|
|
@ -205,7 +207,9 @@ public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker
|
|||
try {
|
||||
cmdObj = (BaseCmd) cmdClass.newInstance();
|
||||
if (cmdObj instanceof BaseListCmd) {
|
||||
accessType = AccessType.ListEntry;
|
||||
accessType = AccessType.UseEntry;
|
||||
} else if (!(cmdObj instanceof BaseAsyncCreateCmd)) {
|
||||
accessType = AccessType.OperateEntry;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException(String.format(
|
||||
|
|
@ -238,11 +242,11 @@ public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker
|
|||
|
||||
|
||||
if (entityTypes == null || entityTypes.length == 0) {
|
||||
_iamSrv.addAclPermissionToAclPolicy(policyId, null, permissionScope.toString(), new Long(-1),
|
||||
_iamSrv.addAclPermissionToAclPolicy(policyId, null, permissionScope.toString(), new Long(AclPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER),
|
||||
apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow);
|
||||
} else {
|
||||
for (AclEntityType entityType : entityTypes) {
|
||||
_iamSrv.addAclPermissionToAclPolicy(policyId, entityType.toString(), permissionScope.toString(), new Long(-1),
|
||||
_iamSrv.addAclPermissionToAclPolicy(policyId, entityType.toString(), permissionScope.toString(), new Long(AclPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER),
|
||||
apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import javax.inject.Inject;
|
|||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import org.apache.cloudstack.iam.api.AclPolicy;
|
||||
import org.apache.cloudstack.iam.api.AclPolicyPermission;
|
||||
import org.apache.cloudstack.iam.api.IAMService;
|
||||
|
|
@ -71,7 +72,7 @@ public class RoleBasedEntityAccessChecker extends DomainChecker implements Secur
|
|||
String entityType = entity.getEntityType().toString();
|
||||
|
||||
if (accessType == null) {
|
||||
accessType = AccessType.ListEntry;
|
||||
accessType = AccessType.UseEntry;
|
||||
}
|
||||
|
||||
// get all Policies of this caller w.r.t the entity
|
||||
|
|
@ -82,13 +83,21 @@ public class RoleBasedEntityAccessChecker extends DomainChecker implements Secur
|
|||
List<AclPolicyPermission> permissions = new ArrayList<AclPolicyPermission>();
|
||||
|
||||
if (action != null) {
|
||||
permissions = _iamSrv.listPolicyPermissionByEntityType(policy.getId(), action, entityType);
|
||||
permissions = _iamSrv.listPolicyPermissionByActionAndEntity(policy.getId(), action, entityType);
|
||||
if (permissions.isEmpty()) {
|
||||
if (accessType != null) {
|
||||
permissions.addAll(_iamSrv.listPolicyPermissionByAccessAndEntity(policy.getId(),
|
||||
accessType.toString(), entityType));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
permissions = _iamSrv.listPolicyPermissionByAccessType(policy.getId(), accessType.toString(),
|
||||
entityType, action);
|
||||
if (accessType != null) {
|
||||
permissions.addAll(_iamSrv.listPolicyPermissionByAccessAndEntity(policy.getId(),
|
||||
accessType.toString(), entityType));
|
||||
}
|
||||
}
|
||||
for (AclPolicyPermission permission : permissions) {
|
||||
if (checkPermissionScope(caller, permission.getScope(), entity)) {
|
||||
if (checkPermissionScope(caller, permission.getScope(), permission.getScopeId(), entity)) {
|
||||
if (permission.getEntityType().equals(entityType)) {
|
||||
policyPermissionMap.put(policy, permission.getPermission().isGranted());
|
||||
break;
|
||||
|
|
@ -114,18 +123,38 @@ public class RoleBasedEntityAccessChecker extends DomainChecker implements Secur
|
|||
return false;
|
||||
}
|
||||
|
||||
private boolean checkPermissionScope(Account caller, String scope, ControlledEntity entity) {
|
||||
private boolean checkPermissionScope(Account caller, String scope, Long scopeId, ControlledEntity entity) {
|
||||
|
||||
if (scope.equals(PermissionScope.ACCOUNT.name())) {
|
||||
if(caller.getAccountId() == entity.getAccountId()){
|
||||
return true;
|
||||
if(scopeId != null && !scopeId.equals(new Long(AclPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER))){
|
||||
//scopeId is set
|
||||
if (scope.equals(PermissionScope.ACCOUNT.name())) {
|
||||
if(scopeId == entity.getAccountId()){
|
||||
return true;
|
||||
}
|
||||
} else if (scope.equals(PermissionScope.DOMAIN.name())) {
|
||||
if (_domainDao.isChildDomain(scopeId, entity.getDomainId())) {
|
||||
return true;
|
||||
}
|
||||
} else if (scope.equals(PermissionScope.RESOURCE.name())) {
|
||||
if (entity instanceof InternalIdentity) {
|
||||
InternalIdentity entityWithId = (InternalIdentity) entity;
|
||||
if(scopeId.equals(entityWithId.getId())){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (scope.equals(PermissionScope.DOMAIN.name())) {
|
||||
if (_domainDao.isChildDomain(caller.getDomainId(), entity.getDomainId())) {
|
||||
return true;
|
||||
} else if (scopeId == null || scopeId.equals(new Long(AclPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER))) {
|
||||
if (scope.equals(PermissionScope.ACCOUNT.name())) {
|
||||
if(caller.getAccountId() == entity.getAccountId()){
|
||||
return true;
|
||||
}
|
||||
} else if (scope.equals(PermissionScope.DOMAIN.name())) {
|
||||
if (_domainDao.isChildDomain(caller.getDomainId(), entity.getDomainId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,4 +49,5 @@ public interface AclPolicyPermission {
|
|||
|
||||
long getId();
|
||||
|
||||
public static final long PERMISSION_SCOPE_ID_CURRENT_CALLER = -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public interface IAMService {
|
|||
|
||||
List<AclPolicyPermission> listPolicyPermissionsByScope(long policyId, String action, String scope);
|
||||
|
||||
List<AclPolicyPermission> listPolicyPermissionByEntityType(long policyId, String action, String entityType);
|
||||
List<AclPolicyPermission> listPolicyPermissionByActionAndEntity(long policyId, String action, String entityType);
|
||||
|
||||
boolean isActionAllowedForPolicies(String action, List<AclPolicy> policies);
|
||||
|
||||
|
|
@ -74,6 +74,7 @@ public interface IAMService {
|
|||
|
||||
AclPolicy resetAclPolicy(long aclPolicyId);
|
||||
|
||||
List<AclPolicyPermission> listPolicyPermissionByAccessType(long policyId, String accessType, String entityType, String action);
|
||||
List<AclPolicyPermission> listPolicyPermissionByAccessAndEntity(long policyId, String accessType,
|
||||
String entityType);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -670,7 +670,8 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<AclPolicyPermission> listPolicyPermissionByEntityType(long policyId, String action, String entityType) {
|
||||
public List<AclPolicyPermission> listPolicyPermissionByActionAndEntity(long policyId, String action,
|
||||
String entityType) {
|
||||
@SuppressWarnings("rawtypes")
|
||||
List pp = _policyPermissionDao.listByPolicyActionAndEntity(policyId, action, entityType);
|
||||
return pp;
|
||||
|
|
@ -678,9 +679,10 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<AclPolicyPermission> listPolicyPermissionByAccessType(long policyId, String accessType, String entityType, String action) {
|
||||
public List<AclPolicyPermission> listPolicyPermissionByAccessAndEntity(long policyId, String accessType,
|
||||
String entityType) {
|
||||
@SuppressWarnings("rawtypes")
|
||||
List pp = _policyPermissionDao.listByPolicyAccessAndEntity(policyId, accessType, entityType, action);
|
||||
List pp = _policyPermissionDao.listByPolicyAccessAndEntity(policyId, accessType, entityType);
|
||||
return pp;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,6 @@ public interface AclPolicyPermissionDao extends GenericDao<AclPolicyPermissionVO
|
|||
|
||||
List<AclPolicyPermissionVO> listByPolicyActionAndEntity(long policyId, String action, String entityType);
|
||||
|
||||
List<AclPolicyPermissionVO> listByPolicyAccessAndEntity(long id, String accessType, String entityType, String action);
|
||||
List<AclPolicyPermissionVO> listByPolicyAccessAndEntity(long policyId, String accessType, String entityType);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,12 +104,11 @@ public class AclPolicyPermissionDaoImpl extends GenericDaoBase<AclPolicyPermissi
|
|||
|
||||
@Override
|
||||
public List<AclPolicyPermissionVO> listByPolicyAccessAndEntity(long policyId, String accessType,
|
||||
String entityType, String action) {
|
||||
String entityType) {
|
||||
SearchCriteria<AclPolicyPermissionVO> sc = fullSearch.create();
|
||||
sc.setParameters("policyId", policyId);
|
||||
sc.setParameters("entityType", entityType);
|
||||
sc.setParameters("accessType", accessType);
|
||||
sc.setParameters("action", action);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue