mirror of
https://github.com/apache/cloudstack
synced 2026-08-02 13:35:41 +00:00
Add response objects for CreateDiskOffering and CreateDomain. Move validation of parameters for CreateDiskOffering and CreateDomain to business logic, add getResponse logic for these commands.
580 lines
25 KiB
Java
580 lines
25 KiB
Java
/**
|
|
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
|
*
|
|
* This software is licensed under the GNU General Public License v3 or later.
|
|
*
|
|
* It is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or any later version.
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
package com.cloud.api;
|
|
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.net.URLDecoder;
|
|
import java.text.DateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import org.apache.log4j.Logger;
|
|
|
|
import com.cloud.async.AsyncJobResult;
|
|
import com.cloud.async.AsyncJobVO;
|
|
import com.cloud.serializer.SerializerHelper;
|
|
import com.cloud.server.ManagementServer;
|
|
import com.cloud.user.Account;
|
|
import com.cloud.utils.Pair;
|
|
|
|
public abstract class BaseCmd {
|
|
private static final Logger s_logger = Logger.getLogger(BaseCmd.class.getName());
|
|
public static final int PROGRESS_INSTANCE_CREATED = 1;
|
|
|
|
public static final String RESPONSE_TYPE_XML = "xml";
|
|
public static final String RESPONSE_TYPE_JSON = "json";
|
|
|
|
public enum CommandType {
|
|
BOOLEAN, DATE, FLOAT, INTEGER, LIST, LONG, OBJECT, MAP, STRING, TZDATE
|
|
}
|
|
|
|
public enum Manager {
|
|
ConfigManager, ManagementServer, NetworkManager, StorageManager, UserVmManager
|
|
}
|
|
|
|
// FIXME: Extract these out into a separate file
|
|
// Client error codes
|
|
public static final int MALFORMED_PARAMETER_ERROR = 430;
|
|
public static final int VM_INVALID_PARAM_ERROR = 431;
|
|
public static final int NET_INVALID_PARAM_ERROR = 432;
|
|
public static final int VM_ALLOCATION_ERROR = 433;
|
|
public static final int IP_ALLOCATION_ERROR = 434;
|
|
public static final int SNAPSHOT_INVALID_PARAM_ERROR = 435;
|
|
public static final int PARAM_ERROR = 436;
|
|
|
|
// Server error codes
|
|
public static final int INTERNAL_ERROR = 530;
|
|
public static final int ACCOUNT_ERROR = 531;
|
|
public static final int UNSUPPORTED_ACTION_ERROR = 532;
|
|
|
|
public static final int VM_DEPLOY_ERROR = 540;
|
|
public static final int VM_DESTROY_ERROR = 541;
|
|
public static final int VM_REBOOT_ERROR = 542;
|
|
public static final int VM_START_ERROR = 543;
|
|
public static final int VM_STOP_ERROR = 544;
|
|
public static final int VM_RESET_PASSWORD_ERROR = 545;
|
|
public static final int VM_CHANGE_SERVICE_ERROR = 546;
|
|
public static final int VM_LIST_ERROR = 547;
|
|
public static final int VM_RECOVER_ERROR = 548;
|
|
public static final int SNAPSHOT_LIST_ERROR = 549;
|
|
public static final int CREATE_VOLUME_FROM_SNAPSHOT_ERROR = 550;
|
|
public static final int VM_INSUFFICIENT_CAPACITY = 551;
|
|
public static final int CREATE_PRIVATE_TEMPLATE_ERROR = 552;
|
|
public static final int VM_HOST_LICENSE_EXPIRED = 553;
|
|
|
|
public static final int NET_IP_ASSOC_ERROR = 560;
|
|
public static final int NET_IP_DIASSOC_ERROR = 561;
|
|
public static final int NET_CREATE_IPFW_RULE_ERROR = 562;
|
|
public static final int NET_DELETE_IPFW_RULE_ERROR = 563;
|
|
public static final int NET_CONFLICT_IPFW_RULE_ERROR = 564;
|
|
public static final int NET_CREATE_LB_RULE_ERROR = 566;
|
|
public static final int NET_DELETE_LB_RULE_ERROR = 567;
|
|
public static final int NET_CONFLICT_LB_RULE_ERROR = 568;
|
|
public static final int NET_LIST_ERROR = 570;
|
|
|
|
public static final int STORAGE_RESOURCE_IN_USE = 580;
|
|
|
|
|
|
public static final DateFormat INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
|
|
private static final DateFormat _outputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
|
|
|
|
private Object _responseObject = null;
|
|
|
|
public abstract String getName();
|
|
public abstract String getResponse();
|
|
|
|
public Object getResponseObject() {
|
|
return _responseObject;
|
|
}
|
|
|
|
public void setResponseObject(Object responseObject) {
|
|
_responseObject = responseObject;
|
|
}
|
|
|
|
|
|
public String getDateString(Date date) {
|
|
if (date == null) {
|
|
return "";
|
|
}
|
|
String formattedString = null;
|
|
synchronized(_outputFormat) {
|
|
formattedString = _outputFormat.format(date);
|
|
}
|
|
return formattedString;
|
|
}
|
|
|
|
public Map<String, Object> validateParams(Map<String, String> params, boolean decode) {
|
|
// List<Pair<Enum, Boolean>> properties = getProperties();
|
|
|
|
// step 1 - all parameter names passed in will be converted to lowercase
|
|
Map<String, Object> processedParams = lowercaseParams(params, decode);
|
|
return processedParams;
|
|
|
|
/*
|
|
// step 2 - make sure all required params exist, and all existing params adhere to the appropriate data type
|
|
Map<String, Object> validatedParams = new HashMap<String, Object>();
|
|
for (Pair<Enum, Boolean> propertyPair : properties) {
|
|
Properties prop = (Properties)propertyPair.first();
|
|
Object param = processedParams.get(prop.getName());
|
|
// possible validation errors are
|
|
// - NULL (not specified)
|
|
// - MALFORMED
|
|
if (param != null) {
|
|
short propertyType = prop.getDataType();
|
|
String decodedParam = null;
|
|
if ((propertyType != TYPE_OBJECT) && (propertyType != TYPE_OBJECT_MAP)) {
|
|
decodedParam = (String)param;
|
|
if (decode) {
|
|
try {
|
|
decodedParam = URLDecoder.decode((String)param, "UTF-8");
|
|
} catch (UnsupportedEncodingException usex) {
|
|
s_logger.warn(prop.getName() + " could not be decoded, value = " + param);
|
|
throw new ServerApiException(PARAM_ERROR, prop.getName() + " could not be decoded");
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (propertyType) {
|
|
case TYPE_INT:
|
|
try {
|
|
validatedParams.put(prop.getName(), Integer.valueOf(Integer.parseInt(decodedParam)));
|
|
} catch (NumberFormatException ex) {
|
|
s_logger.warn(prop.getName() + " (type is int) is malformed, value = " + decodedParam);
|
|
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, prop.getName() + " is malformed");
|
|
}
|
|
break;
|
|
case TYPE_LONG:
|
|
try {
|
|
validatedParams.put(prop.getName(), Long.valueOf(Long.parseLong(decodedParam)));
|
|
} catch (NumberFormatException ex) {
|
|
s_logger.warn(prop.getName() + " (type is long) is malformed, value = " + decodedParam);
|
|
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, prop.getName() + " is malformed");
|
|
}
|
|
break;
|
|
case TYPE_DATE:
|
|
try {
|
|
synchronized(_format) { // SimpleDataFormat is not thread safe, synchronize on it to avoid parse errors
|
|
validatedParams.put(prop.getName(), _format.parse(decodedParam));
|
|
}
|
|
} catch (ParseException ex) {
|
|
s_logger.warn(prop.getName() + " (type is date) is malformed, value = " + decodedParam);
|
|
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, prop.getName() + " uses an unsupported date format");
|
|
}
|
|
break;
|
|
case TYPE_TZDATE:
|
|
try {
|
|
validatedParams.put(prop.getName(), DateUtil.parseTZDateString(decodedParam));
|
|
} catch (ParseException ex) {
|
|
s_logger.warn(prop.getName() + " (type is date) is malformed, value = " + decodedParam);
|
|
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, prop.getName() + " uses an unsupported date format");
|
|
}
|
|
break;
|
|
case TYPE_FLOAT:
|
|
try {
|
|
validatedParams.put(prop.getName(), Float.valueOf(Float.parseFloat(decodedParam)));
|
|
} catch (NumberFormatException ex) {
|
|
s_logger.warn(prop.getName() + " (type is float) is malformed, value = " + decodedParam);
|
|
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, prop.getName() + " is malformed");
|
|
}
|
|
break;
|
|
case TYPE_BOOLEAN:
|
|
validatedParams.put(prop.getName(), Boolean.valueOf(Boolean.parseBoolean(decodedParam)));
|
|
break;
|
|
case TYPE_STRING:
|
|
validatedParams.put(prop.getName(), decodedParam);
|
|
break;
|
|
default:
|
|
validatedParams.put(prop.getName(), param);
|
|
break;
|
|
}
|
|
} else if (propertyPair.second().booleanValue() == true) {
|
|
s_logger.warn("missing parameter, " + prop.getTagName() + " is not specified");
|
|
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, prop.getTagName() + " is not specified");
|
|
}
|
|
}
|
|
|
|
return validatedParams;
|
|
*/
|
|
}
|
|
|
|
private Map<String, Object> lowercaseParams(Map<String, String> params, boolean decode) {
|
|
Map<String, Object> lowercaseParams = new HashMap<String, Object>();
|
|
for (String key : params.keySet()) {
|
|
lowercaseParams.put(key.toLowerCase(), params.get(key));
|
|
}
|
|
return lowercaseParams;
|
|
}
|
|
|
|
// FIXME: move this to a utils method so that maps can be unpacked and integer/long values can be appropriately cast
|
|
@SuppressWarnings("unchecked")
|
|
public Map<String, Object> unpackParams(Map<String, String> params) {
|
|
Map<String, Object> lowercaseParams = new HashMap<String, Object>();
|
|
for (String key : params.keySet()) {
|
|
int arrayStartIndex = key.indexOf('[');
|
|
int arrayStartLastIndex = key.lastIndexOf('[');
|
|
if (arrayStartIndex != arrayStartLastIndex) {
|
|
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key + "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
|
|
}
|
|
|
|
if (arrayStartIndex > 0) {
|
|
int arrayEndIndex = key.indexOf(']');
|
|
int arrayEndLastIndex = key.lastIndexOf(']');
|
|
if ((arrayEndIndex < arrayStartIndex) || (arrayEndIndex != arrayEndLastIndex)) {
|
|
// malformed parameter
|
|
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key + "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
|
|
}
|
|
|
|
// Now that we have an array object, check for a field name in the case of a complex object
|
|
int fieldIndex = key.indexOf('.');
|
|
String fieldName = null;
|
|
if (fieldIndex < arrayEndIndex) {
|
|
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key + "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
|
|
} else {
|
|
fieldName = key.substring(fieldIndex + 1);
|
|
}
|
|
|
|
// parse the parameter name as the text before the first '[' character
|
|
String paramName = key.substring(0, arrayStartIndex);
|
|
paramName = paramName.toLowerCase();
|
|
|
|
Map<Integer, Map> mapArray = null;
|
|
Map<String, Object> mapValue = null;
|
|
String indexStr = key.substring(arrayStartIndex+1, arrayEndIndex);
|
|
int index = 0;
|
|
boolean parsedIndex = false;
|
|
try {
|
|
if (indexStr != null) {
|
|
index = Integer.parseInt(indexStr);
|
|
parsedIndex = true;
|
|
}
|
|
} catch (NumberFormatException nfe) {
|
|
s_logger.warn("Invalid parameter " + key + " received, unable to parse object array, returning an error.");
|
|
}
|
|
|
|
if (!parsedIndex) {
|
|
throw new ServerApiException(MALFORMED_PARAMETER_ERROR, "Unable to decode parameter " + key + "; if specifying an object array, please use parameter[index].field=XXX, e.g. userGroupList[0].group=httpGroup");
|
|
}
|
|
|
|
Object value = lowercaseParams.get(paramName);
|
|
if (value == null) {
|
|
// for now, assume object array with sub fields
|
|
mapArray = new HashMap<Integer, Map>();
|
|
mapValue = new HashMap<String, Object>();
|
|
mapArray.put(Integer.valueOf(index), mapValue);
|
|
} else if (value instanceof Map) {
|
|
mapArray = (HashMap)value;
|
|
mapValue = mapArray.get(Integer.valueOf(index));
|
|
if (mapValue == null) {
|
|
mapValue = new HashMap<String, Object>();
|
|
mapArray.put(Integer.valueOf(index), mapValue);
|
|
}
|
|
}
|
|
|
|
// we are ready to store the value for a particular field into the map for this object
|
|
mapValue.put(fieldName, (String)params.get(key));
|
|
|
|
lowercaseParams.put(paramName, mapArray);
|
|
} else {
|
|
lowercaseParams.put(key.toLowerCase(), params.get(key));
|
|
}
|
|
}
|
|
return lowercaseParams;
|
|
}
|
|
|
|
public String buildResponse(ServerApiException apiException, String responseType) {
|
|
StringBuffer sb = new StringBuffer();
|
|
if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
|
|
// JSON response
|
|
sb.append("{ \"" + getName() + "\" : { \"errorcode\" : \"" + apiException.getErrorCode() + "\", \"description\" : \"" + apiException.getDescription() + "\" } }");
|
|
} else {
|
|
sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
|
|
sb.append("<" + getName() + ">");
|
|
sb.append("<errorcode>" + apiException.getErrorCode() + "</errorcode>");
|
|
sb.append("<description>" + escapeXml(apiException.getDescription()) + "</description>");
|
|
sb.append("</" + getName() + ">");
|
|
}
|
|
return sb.toString();
|
|
}
|
|
|
|
public String buildResponse(List<Pair<String, Object>> tagList, String responseType) {
|
|
StringBuffer sb = new StringBuffer();
|
|
|
|
// set up the return value with the name of the response
|
|
if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
|
|
sb.append("{ \"" + getName() + "\" : { ");
|
|
} else {
|
|
sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
|
|
sb.append("<" + getName() + ">");
|
|
}
|
|
|
|
int i = 0;
|
|
for (Pair<String, Object> tagData : tagList) {
|
|
String tagName = tagData.first();
|
|
Object tagValue = tagData.second();
|
|
if (tagValue instanceof Object[]) {
|
|
Object[] subObjects = (Object[])tagValue;
|
|
if (subObjects.length < 1) continue;
|
|
writeObjectArray(responseType, sb, i++, tagName, subObjects);
|
|
} else {
|
|
writeNameValuePair(sb, tagName, tagValue, responseType, i++);
|
|
}
|
|
}
|
|
|
|
// close the response
|
|
if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
|
|
sb.append("} }");
|
|
} else {
|
|
sb.append("</" + getName() + ">");
|
|
}
|
|
return sb.toString();
|
|
}
|
|
|
|
private void writeNameValuePair(StringBuffer sb, String tagName, Object tagValue, String responseType, int propertyCount) {
|
|
if (tagValue == null) {
|
|
return;
|
|
}
|
|
|
|
if (tagValue instanceof Object[]) {
|
|
Object[] subObjects = (Object[])tagValue;
|
|
if (subObjects.length < 1) return;
|
|
writeObjectArray(responseType, sb, propertyCount, tagName, subObjects);
|
|
} else {
|
|
if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
|
|
String seperator = ((propertyCount > 0) ? ", " : "");
|
|
sb.append(seperator + "\"" + tagName + "\" : \"" + escapeJSON(tagValue.toString()) + "\"");
|
|
} else {
|
|
sb.append("<" + tagName + ">" + escapeXml(tagValue.toString()) + "</" + tagName + ">");
|
|
}
|
|
}
|
|
}
|
|
|
|
private void writeObjectArray(String responseType, StringBuffer sb, int propertyCount, String tagName, Object[] subObjects) {
|
|
if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
|
|
String separator = ((propertyCount > 0) ? ", " : "");
|
|
sb.append(separator);
|
|
}
|
|
int j = 0;
|
|
for (Object subObject : subObjects) {
|
|
if (subObject instanceof List) {
|
|
List subObjList = (List)subObject;
|
|
writeSubObject(sb, tagName, subObjList, responseType, j++);
|
|
}
|
|
}
|
|
|
|
if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
|
|
sb.append("]");
|
|
}
|
|
}
|
|
|
|
private void writeSubObject(StringBuffer sb, String tagName, List tagList, String responseType, int objectCount) {
|
|
if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
|
|
sb.append(((objectCount == 0) ? "\"" + tagName + "\" : [ { " : ", { "));
|
|
} else {
|
|
sb.append("<" + tagName + ">");
|
|
}
|
|
|
|
int i = 0;
|
|
for (Object tag : tagList) {
|
|
if (tag instanceof Pair) {
|
|
Pair nameValuePair = (Pair)tag;
|
|
writeNameValuePair(sb, (String)nameValuePair.first(), nameValuePair.second(), responseType, i++);
|
|
}
|
|
}
|
|
|
|
if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
|
|
sb.append("}");
|
|
} else {
|
|
sb.append("</" + tagName + ">");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Escape xml response set to false by default. API commands to override this method to allow escaping
|
|
*/
|
|
public boolean requireXmlEscape() {
|
|
return true;
|
|
}
|
|
|
|
private String escapeXml(String xml){
|
|
if(!requireXmlEscape()){
|
|
return xml;
|
|
}
|
|
int iLen = xml.length();
|
|
if (iLen == 0)
|
|
return xml;
|
|
StringBuffer sOUT = new StringBuffer(iLen + 256);
|
|
int i = 0;
|
|
for (; i < iLen; i++) {
|
|
char c = xml.charAt(i);
|
|
if (c == '<')
|
|
sOUT.append("<");
|
|
else if (c == '>')
|
|
sOUT.append(">");
|
|
else if (c == '&')
|
|
sOUT.append("&");
|
|
else if (c == '"')
|
|
sOUT.append(""");
|
|
else if (c == '\'')
|
|
sOUT.append("'");
|
|
else
|
|
sOUT.append(c);
|
|
}
|
|
return sOUT.toString();
|
|
}
|
|
|
|
private static String escapeJSON(String str) {
|
|
if (str == null) {
|
|
return str;
|
|
}
|
|
|
|
return str.replace("\"", "\\\"");
|
|
}
|
|
|
|
protected long waitInstanceCreation(long jobId) {
|
|
ManagementServer mgr = getManagementServer();
|
|
|
|
long instanceId = 0;
|
|
AsyncJobVO job = null;
|
|
boolean interruped = false;
|
|
|
|
// as job may be executed in other management server, we need to do a database polling here
|
|
try {
|
|
boolean quit = false;
|
|
while(!quit) {
|
|
job = mgr.findAsyncJobById(jobId);
|
|
if(job == null) {
|
|
s_logger.error("Async command " + this.getClass().getName() + " waitInstanceCreation error: job-" + jobId + " no longer exists");
|
|
break;
|
|
}
|
|
|
|
switch(job.getStatus()) {
|
|
case AsyncJobResult.STATUS_IN_PROGRESS :
|
|
if(job.getProcessStatus() == BaseCmd.PROGRESS_INSTANCE_CREATED) {
|
|
Long id = (Long)SerializerHelper.fromSerializedString(job.getResult());
|
|
if(id != null) {
|
|
instanceId = id.longValue();
|
|
if(s_logger.isDebugEnabled())
|
|
s_logger.debug("Async command " + this.getClass().getName() + " succeeded in waiting for new instance to be created, instance Id: " + instanceId);
|
|
} else {
|
|
s_logger.warn("Async command " + this.getClass().getName() + " has new instance created, but value as null?");
|
|
}
|
|
quit = true;
|
|
}
|
|
break;
|
|
|
|
case AsyncJobResult.STATUS_SUCCEEDED :
|
|
instanceId = getInstanceIdFromJobSuccessResult(job.getResult());
|
|
quit = true;
|
|
break;
|
|
|
|
case AsyncJobResult.STATUS_FAILED :
|
|
s_logger.error("Async command " + this.getClass().getName() + " executing job-" + jobId + " failed, result: " + job.getResult());
|
|
quit = true;
|
|
break;
|
|
}
|
|
|
|
if(quit)
|
|
break;
|
|
|
|
try {
|
|
Thread.sleep(1000);
|
|
} catch (InterruptedException e) {
|
|
interruped = true;
|
|
}
|
|
}
|
|
} finally {
|
|
if(interruped)
|
|
Thread.currentThread().interrupt();
|
|
}
|
|
return instanceId;
|
|
}
|
|
|
|
protected long getInstanceIdFromJobSuccessResult(String result) {
|
|
s_logger.debug("getInstanceIdFromJobSuccessResult not overridden in subclass " + this.getClass().getName());
|
|
return 0;
|
|
}
|
|
|
|
public static boolean isAdmin(short accountType) {
|
|
return ((accountType == Account.ACCOUNT_TYPE_ADMIN) ||
|
|
(accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) ||
|
|
(accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN));
|
|
}
|
|
|
|
private Account getAccount(Map<String, Object> params) throws ServerApiException {
|
|
// FIXME: This should go into the context!
|
|
Long domainId = (Long) params.get("domainid");
|
|
Account account = (Account)params.get("accountobj");
|
|
String accountName = (String) params.get("account");
|
|
|
|
Long accountId = null;
|
|
Account finalAccount = null;
|
|
ManagementServer managementServer = getManagementServer();
|
|
if ((account == null) || isAdmin(account.getType())) {
|
|
if (domainId != null) {
|
|
if ((account != null) && !managementServer.isChildDomain(account.getDomainId(), domainId)) {
|
|
throw new ServerApiException(PARAM_ERROR, "Invalid domain id (" + domainId + ") ");
|
|
}
|
|
if (accountName != null) {
|
|
Account userAccount = managementServer.findActiveAccount(accountName, domainId);
|
|
if (userAccount == null) {
|
|
throw new ServerApiException(PARAM_ERROR, "Unable to find account " + accountName + " in domain " + domainId);
|
|
}
|
|
accountId = userAccount.getId();
|
|
}
|
|
} else {
|
|
accountId = ((account != null) ? account.getId() : null);
|
|
}
|
|
} else {
|
|
accountId = account.getId();
|
|
}
|
|
|
|
if (accountId != null) {
|
|
finalAccount = managementServer.findAccountById(accountId);
|
|
}
|
|
return finalAccount;
|
|
}
|
|
|
|
protected Long checkAccountPermissions(Map<String, Object> params,
|
|
long targetAccountId,
|
|
long targetDomainId,
|
|
String targetDesc,
|
|
long targetId)
|
|
throws ServerApiException
|
|
{
|
|
Long accountId = null;
|
|
|
|
Account account = getAccount(params);
|
|
if (account != null) {
|
|
if (!isAdmin(account.getType())) {
|
|
if (account.getId().longValue() != targetAccountId) {
|
|
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find a " + targetDesc + " with id " + targetId + " for this account");
|
|
}
|
|
} else if (!getManagementServer().isChildDomain(account.getDomainId(), targetDomainId)) {
|
|
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to perform operation for " + targetDesc + " with id " + targetId + ", permission denied.");
|
|
}
|
|
accountId = account.getId();
|
|
}
|
|
|
|
return accountId;
|
|
}
|
|
}
|