Fix ACL processor and methods in ApiDispatcher and their usages

Signed-off-by: Rohit Yadav <bhaisaab@apache.org>
This commit is contained in:
Rohit Yadav 2013-01-06 17:18:45 -08:00
parent 19cf665094
commit 96b9164e4b
4 changed files with 85 additions and 100 deletions

View File

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

View File

@ -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,60 +148,54 @@ public class ApiDispatcher {
} }
} }
private void doAccessChecks(BaseAsyncCreateCmd cmd, List<ControlledEntity> entitiesToAccess) { private void checkACLOnCommand(BaseCmd cmd) {
// 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.
//one can write another commandACLChecker to check access via custom roles.
}
private List<Role> determineRole(Account caller) {
// TODO Auto-generated method stub
List<Role> effectiveRoles = new ArrayList<Role>();
return effectiveRoles;
}
private void doAccessChecks(BaseCmd cmd, List<Object> entitiesToAccess) {
//owner //owner
Account caller = UserContext.current().getCaller(); Account caller = UserContext.current().getCaller();
Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId()); Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId());
List<Role> callerRoles = determineRole(caller); // REMOVE ME:
List<Role> ownerRoles = determineRole(owner); // 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);
//check permission to call this command for the caller if(cmd instanceof BaseAsyncCreateCmd) {
//this needs checking of static roles of the caller //check that caller can access the owner account.
checkACLOnCommand(cmd); _accountMgr.checkAccess(caller, null, true, owner);
//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
//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.
}
private List<Role> determineRole(Account caller) {
// TODO Auto-generated method stub
List<Role> effectiveRoles = new ArrayList<Role>();
return effectiveRoles;
}
private void checkACLOnEntities(Account caller, List<ControlledEntity> entitiesToAccess){
//checkACLOnEntities
if(!entitiesToAccess.isEmpty()){
for(ControlledEntity entity : entitiesToAccess)
_accountMgr.checkAccess(caller, null, true, entity);
}
}
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);
} }
if(!entitiesToAccess.isEmpty()){
//check that caller can access the owner account.
_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) {
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,58 +452,57 @@ 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){
if (ControlledEntity.class.isAssignableFrom(entity)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("entity name is:" + entity.getName());
}
if (s_instance._daoNameMap.containsKey(entity.getName())) { for (Class entity : entityList) {
Class<? extends GenericDao> daoClass = s_instance._daoNameMap.get(entity.getName()); // Check if the parameter type is a single
GenericDao daoClassInstance = s_instance._locator.getDao(daoClass); // Id or list of id's/name's
switch (fieldType) {
// Check if the parameter type is a single case LIST:
// Id or list of id's/name's CommandType listType = parameterAnnotation.collectionType();
switch (fieldType) { switch (listType) {
case LIST:
CommandType listType = parameterAnnotation.collectionType();
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;
/* /*
* case STRING: List<String> listParam = * case STRING: List<String> listParam =
* new ArrayList<String>(); listParam = * new ArrayList<String>(); listParam =
* (List)field.get(cmd); for(String * (List)field.get(cmd); for(String
* entityName: listParam){ * entityName: listParam){
* ControlledEntity entityObj = * ControlledEntity entityObj =
* (ControlledEntity * (ControlledEntity
* )daoClassInstance(entityId); * )daoClassInstance(entityId);
* entitiesToAccess.add(entityObj); } * entitiesToAccess.add(entityObj); }
* break; * break;
*/ */
default: default:
break; break;
}
break;
case LONG:
case UUID:
Long entityId = (Long) field.get(cmd);
ControlledEntity entityObj = (ControlledEntity) daoClassInstance.findById(entityId);
entitiesToAccess.add(entityObj);
break;
default:
break;
} }
break;
case LONG:
case UUID:
Object entityObj = s_instance._entityMgr.findById(entity, (Long) field.get(cmd));
entitiesToAccess.add(entityObj);
break;
default:
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)

View File

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

View File

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