- Adding OperateEntry during loading of commands

- Replace ListEntry By OperateEntry
- ApiDispatcher should pass on the API name
This commit is contained in:
Prachi Damle 2014-01-23 17:50:59 -08:00
parent 39c0a302b4
commit 96a64b933e
11 changed files with 75 additions and 34 deletions

View File

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

View File

@ -36,7 +36,8 @@ public interface SecurityChecker extends Adapter {
ModifyProject,
UseNetwork,
DeleteEntry,
OperateEntry
OperateEntry,
UseEntry
}
/**

View File

@ -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
}

View File

@ -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());
}

View File

@ -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);
}
}

View File

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

View File

@ -49,4 +49,5 @@ public interface AclPolicyPermission {
long getId();
public static final long PERMISSION_SCOPE_ID_CURRENT_CALLER = -1;
}

View File

@ -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);
}

View File

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

View File

@ -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);
}

View File

@ -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);
}