mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Fix ACL processor and methods in ApiDispatcher and their usages
Signed-off-by: Rohit Yadav <bhaisaab@apache.org>
This commit is contained in:
parent
19cf665094
commit
96b9164e4b
@ -39,7 +39,6 @@ public class StopVMCmd extends BaseAsyncCmd {
|
|||||||
// ////////////// API parameters /////////////////////
|
// ////////////// API parameters /////////////////////
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
|
|
||||||
@ACL
|
|
||||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType=UserVmResponse.class,
|
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType=UserVmResponse.class,
|
||||||
required = true, description = "The ID of the virtual machine")
|
required = true, description = "The ID of the virtual machine")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import java.util.regex.Matcher;
|
|||||||
|
|
||||||
import com.cloud.dao.EntityManager;
|
import com.cloud.dao.EntityManager;
|
||||||
import org.apache.cloudstack.acl.ControlledEntity;
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
|
import org.apache.cloudstack.acl.InfrastructureEntity;
|
||||||
import org.apache.cloudstack.acl.Role;
|
import org.apache.cloudstack.acl.Role;
|
||||||
import org.apache.cloudstack.api.*;
|
import org.apache.cloudstack.api.*;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
@ -106,10 +107,7 @@ public class ApiDispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void dispatchCreateCmd(BaseAsyncCreateCmd cmd, Map<String, String> params) {
|
public void dispatchCreateCmd(BaseAsyncCreateCmd cmd, Map<String, String> params) {
|
||||||
List<ControlledEntity> entitiesToAccess = new ArrayList<ControlledEntity>();
|
processParameters(cmd, params);
|
||||||
setupParameters(cmd, params, entitiesToAccess);
|
|
||||||
|
|
||||||
doAccessChecks(cmd, entitiesToAccess);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
UserContext ctx = UserContext.current();
|
UserContext ctx = UserContext.current();
|
||||||
@ -150,26 +148,7 @@ public class ApiDispatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doAccessChecks(BaseAsyncCreateCmd cmd, List<ControlledEntity> entitiesToAccess) {
|
private void checkACLOnCommand(BaseCmd cmd) {
|
||||||
//owner
|
|
||||||
Account caller = UserContext.current().getCaller();
|
|
||||||
Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId());
|
|
||||||
|
|
||||||
List<Role> callerRoles = determineRole(caller);
|
|
||||||
List<Role> ownerRoles = determineRole(owner);
|
|
||||||
|
|
||||||
//check permission to call this command for the caller
|
|
||||||
//this needs checking of static roles of the caller
|
|
||||||
checkACLOnCommand(cmd);
|
|
||||||
|
|
||||||
//check that caller can access the owner account.
|
|
||||||
_accountMgr.checkAccess(caller, null, true, owner);
|
|
||||||
|
|
||||||
checkACLOnEntities(caller, entitiesToAccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void checkACLOnCommand(BaseAsyncCreateCmd cmd) {
|
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
//need to write an commandACLChecker adapter framework to check ACL on commands - default one will use the static roles by referring to commands.properties.
|
//need to write an commandACLChecker adapter framework to check ACL on commands - default one will use the static roles by referring to commands.properties.
|
||||||
//one can write another commandACLChecker to check access via custom roles.
|
//one can write another commandACLChecker to check access via custom roles.
|
||||||
@ -182,28 +161,41 @@ public class ApiDispatcher {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkACLOnEntities(Account caller, List<ControlledEntity> entitiesToAccess){
|
private void doAccessChecks(BaseCmd cmd, List<Object> entitiesToAccess) {
|
||||||
//checkACLOnEntities
|
//owner
|
||||||
|
Account caller = UserContext.current().getCaller();
|
||||||
|
Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId());
|
||||||
|
|
||||||
|
// REMOVE ME:
|
||||||
|
// List<Role> callerRoles = determineRole(caller);
|
||||||
|
// List<Role> ownerRoles = determineRole(owner);
|
||||||
|
// check permission to call this command for the caller
|
||||||
|
// this needs checking of static roles of the caller
|
||||||
|
// Role based acl is done in ApiServer before api gets to ApiDispatcher
|
||||||
|
// checkACLOnCommand(cmd);
|
||||||
|
|
||||||
|
if(cmd instanceof BaseAsyncCreateCmd) {
|
||||||
|
//check that caller can access the owner account.
|
||||||
|
_accountMgr.checkAccess(caller, null, true, owner);
|
||||||
|
}
|
||||||
|
|
||||||
if(!entitiesToAccess.isEmpty()){
|
if(!entitiesToAccess.isEmpty()){
|
||||||
for(ControlledEntity entity : entitiesToAccess)
|
//check that caller can access the owner account.
|
||||||
_accountMgr.checkAccess(caller, null, true, entity);
|
_accountMgr.checkAccess(caller, null, true, owner);
|
||||||
|
for(Object entity : entitiesToAccess) {
|
||||||
|
if (entity instanceof ControlledEntity) {
|
||||||
|
_accountMgr.checkAccess(caller, null, true, (ControlledEntity) entity);
|
||||||
|
}
|
||||||
|
else if (entity instanceof InfrastructureEntity) {
|
||||||
|
//do something here:D
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispatch(BaseCmd cmd, Map<String, String> params) {
|
public void dispatch(BaseCmd cmd, Map<String, String> params) {
|
||||||
List<ControlledEntity> entitiesToAccess = new ArrayList<ControlledEntity>();
|
|
||||||
setupParameters(cmd, params, entitiesToAccess);
|
|
||||||
|
|
||||||
if(!entitiesToAccess.isEmpty()){
|
|
||||||
//owner
|
|
||||||
Account caller = UserContext.current().getCaller();
|
|
||||||
Account owner = s_instance._accountMgr.getActiveAccountById(cmd.getEntityOwnerId());
|
|
||||||
s_instance._accountMgr.checkAccess(caller, null, true, owner);
|
|
||||||
for(ControlledEntity entity : entitiesToAccess)
|
|
||||||
s_instance._accountMgr.checkAccess(caller, null, true, entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
processParameters(cmd, params);
|
||||||
UserContext ctx = UserContext.current();
|
UserContext ctx = UserContext.current();
|
||||||
ctx.setAccountId(cmd.getEntityOwnerId());
|
ctx.setAccountId(cmd.getEntityOwnerId());
|
||||||
if (cmd instanceof BaseAsyncCmd) {
|
if (cmd instanceof BaseAsyncCmd) {
|
||||||
@ -362,7 +354,8 @@ public class ApiDispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
public static void setupParameters(BaseCmd cmd, Map<String, String> params, List<ControlledEntity> entitiesToAccess) {
|
public static void processParameters(BaseCmd cmd, Map<String, String> params) {
|
||||||
|
List<Object> entitiesToAccess = new ArrayList<Object>();
|
||||||
Map<String, Object> unpackedParams = cmd.unpackParams(params);
|
Map<String, Object> unpackedParams = cmd.unpackParams(params);
|
||||||
|
|
||||||
if (cmd instanceof BaseListCmd) {
|
if (cmd instanceof BaseListCmd) {
|
||||||
@ -459,16 +452,8 @@ public class ApiDispatcher {
|
|||||||
// find the controlled entity DBid by uuid
|
// find the controlled entity DBid by uuid
|
||||||
if (parameterAnnotation.entityType() != null) {
|
if (parameterAnnotation.entityType() != null) {
|
||||||
Class<?>[] entityList = parameterAnnotation.entityType()[0].getAnnotation(EntityReference.class).value();
|
Class<?>[] entityList = parameterAnnotation.entityType()[0].getAnnotation(EntityReference.class).value();
|
||||||
|
|
||||||
for (Class entity : entityList) {
|
for (Class entity : entityList) {
|
||||||
if (ControlledEntity.class.isAssignableFrom(entity)) {
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
|
||||||
s_logger.debug("entity name is:" + entity.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_instance._daoNameMap.containsKey(entity.getName())) {
|
|
||||||
Class<? extends GenericDao> daoClass = s_instance._daoNameMap.get(entity.getName());
|
|
||||||
GenericDao daoClassInstance = s_instance._locator.getDao(daoClass);
|
|
||||||
|
|
||||||
// Check if the parameter type is a single
|
// Check if the parameter type is a single
|
||||||
// Id or list of id's/name's
|
// Id or list of id's/name's
|
||||||
switch (fieldType) {
|
switch (fieldType) {
|
||||||
@ -476,11 +461,11 @@ public class ApiDispatcher {
|
|||||||
CommandType listType = parameterAnnotation.collectionType();
|
CommandType listType = parameterAnnotation.collectionType();
|
||||||
switch (listType) {
|
switch (listType) {
|
||||||
case LONG:
|
case LONG:
|
||||||
|
case UUID:
|
||||||
List<Long> listParam = new ArrayList<Long>();
|
List<Long> listParam = new ArrayList<Long>();
|
||||||
listParam = (List) field.get(cmd);
|
listParam = (List) field.get(cmd);
|
||||||
|
|
||||||
for (Long entityId : listParam) {
|
for (Long entityId : listParam) {
|
||||||
ControlledEntity entityObj = (ControlledEntity) daoClassInstance.findById(entityId);
|
Object entityObj = s_instance._entityMgr.findById(entity, (Long) field.get(cmd));
|
||||||
entitiesToAccess.add(entityObj);
|
entitiesToAccess.add(entityObj);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -501,16 +486,23 @@ public class ApiDispatcher {
|
|||||||
break;
|
break;
|
||||||
case LONG:
|
case LONG:
|
||||||
case UUID:
|
case UUID:
|
||||||
Long entityId = (Long) field.get(cmd);
|
Object entityObj = s_instance._entityMgr.findById(entity, (Long) field.get(cmd));
|
||||||
ControlledEntity entityObj = (ControlledEntity) daoClassInstance.findById(entityId);
|
|
||||||
entitiesToAccess.add(entityObj);
|
entitiesToAccess.add(entityObj);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ControlledEntity.class.isAssignableFrom(entity)) {
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("ControlledEntity name is:" + entity.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (InfrastructureEntity.class.isAssignableFrom(entity)) {
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("InfrastructureEntity name is:" + entity.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,6 +521,8 @@ public class ApiDispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//check access on the entities.
|
//check access on the entities.
|
||||||
|
s_instance.doAccessChecks(cmd, entitiesToAccess);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Long translateUuidToInternalId(String uuid, Parameter annotation)
|
private static Long translateUuidToInternalId(String uuid, Parameter annotation)
|
||||||
|
|||||||
@ -412,15 +412,7 @@ public class ApiServer implements HttpRequestHandler {
|
|||||||
objectEntityTable = createCmd.getEntityTable();
|
objectEntityTable = createCmd.getEntityTable();
|
||||||
params.put("id", objectId.toString());
|
params.put("id", objectId.toString());
|
||||||
} else {
|
} else {
|
||||||
List<ControlledEntity> entitiesToAccess = new ArrayList<ControlledEntity>();
|
ApiDispatcher.processParameters(cmdObj, params);
|
||||||
ApiDispatcher.setupParameters(cmdObj, params, entitiesToAccess);
|
|
||||||
|
|
||||||
if(!entitiesToAccess.isEmpty()){
|
|
||||||
Account owner = s_instance._accountMgr.getActiveAccountById(cmdObj.getEntityOwnerId());
|
|
||||||
s_instance._accountMgr.checkAccess(caller, null, true, owner);
|
|
||||||
|
|
||||||
s_instance._accountMgr.checkAccess(caller, null, true, (ControlledEntity[])entitiesToAccess.toArray());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseAsyncCmd asyncCmd = (BaseAsyncCmd) cmdObj;
|
BaseAsyncCmd asyncCmd = (BaseAsyncCmd) cmdObj;
|
||||||
|
|||||||
@ -349,7 +349,7 @@ public class AutoScaleManagerImpl<Type> implements AutoScaleManager, AutoScaleSe
|
|||||||
* For ex. if projectId is given as a string instead of an long value, this
|
* For ex. if projectId is given as a string instead of an long value, this
|
||||||
* will be throwing an error.
|
* will be throwing an error.
|
||||||
*/
|
*/
|
||||||
ApiDispatcher.setupParameters(new DeployVMCmd(), deployParams, new ArrayList<ControlledEntity>());
|
ApiDispatcher.processParameters(new DeployVMCmd(), deployParams);
|
||||||
|
|
||||||
if (autoscaleUserId == null) {
|
if (autoscaleUserId == null) {
|
||||||
autoscaleUserId = UserContext.current().getCallerUserId();
|
autoscaleUserId = UserContext.current().getCallerUserId();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user