diff --git a/api/src/com/cloud/serializer/Param.java b/api/src/com/cloud/serializer/Param.java index 3e6f852128a..26a848a7035 100644 --- a/api/src/com/cloud/serializer/Param.java +++ b/api/src/com/cloud/serializer/Param.java @@ -37,4 +37,6 @@ public @interface Param { String since() default ""; RoleType[] authorized() default {}; + + boolean isSensitive() default false; } diff --git a/api/src/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java b/api/src/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java index 4ed1b53173f..410719fdc4b 100644 --- a/api/src/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java +++ b/api/src/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java @@ -17,13 +17,12 @@ package org.apache.cloudstack.api.response; import com.google.gson.annotations.SerializedName; - import com.cloud.serializer.Param; public class CreateSSHKeyPairResponse extends SSHKeyPairResponse { @SerializedName("privatekey") - @Param(description = "Private key") + @Param(description = "Private key", isSensitive = true) private String privateKey; public CreateSSHKeyPairResponse() { diff --git a/api/src/org/apache/cloudstack/api/response/GetVMPasswordResponse.java b/api/src/org/apache/cloudstack/api/response/GetVMPasswordResponse.java index 7a4543d4379..49603212edc 100644 --- a/api/src/org/apache/cloudstack/api/response/GetVMPasswordResponse.java +++ b/api/src/org/apache/cloudstack/api/response/GetVMPasswordResponse.java @@ -25,7 +25,7 @@ import com.cloud.serializer.Param; public class GetVMPasswordResponse extends BaseResponse { @SerializedName("encryptedpassword") - @Param(description = "The base64 encoded encrypted password of the VM") + @Param(description = "The base64 encoded encrypted password of the VM", isSensitive = true) private String encryptedPassword; public GetVMPasswordResponse() { diff --git a/api/src/org/apache/cloudstack/api/response/LoginCmdResponse.java b/api/src/org/apache/cloudstack/api/response/LoginCmdResponse.java index 3139b6fe51e..55eb2c40a38 100644 --- a/api/src/org/apache/cloudstack/api/response/LoginCmdResponse.java +++ b/api/src/org/apache/cloudstack/api/response/LoginCmdResponse.java @@ -63,7 +63,7 @@ public class LoginCmdResponse extends AuthenticationCmdResponse { private String registered; @SerializedName(value = ApiConstants.SESSIONKEY) - @Param(description = "Session key that can be passed in subsequent Query command calls") + @Param(description = "Session key that can be passed in subsequent Query command calls", isSensitive = true) private String sessionKey; public String getUsername() { diff --git a/api/src/org/apache/cloudstack/api/response/RegisterResponse.java b/api/src/org/apache/cloudstack/api/response/RegisterResponse.java index fd944b0e514..5faedabfc16 100644 --- a/api/src/org/apache/cloudstack/api/response/RegisterResponse.java +++ b/api/src/org/apache/cloudstack/api/response/RegisterResponse.java @@ -24,11 +24,11 @@ import com.cloud.serializer.Param; public class RegisterResponse extends BaseResponse { @SerializedName("apikey") - @Param(description = "the api key of the registered user") + @Param(description = "the api key of the registered user", isSensitive = true) private String apiKey; @SerializedName("secretkey") - @Param(description = "the secret key of the registered user") + @Param(description = "the secret key of the registered user", isSensitive = true) private String secretKey; public String getApiKey() { diff --git a/api/src/org/apache/cloudstack/api/response/RemoteAccessVpnResponse.java b/api/src/org/apache/cloudstack/api/response/RemoteAccessVpnResponse.java index 28d788b427b..0e078bea5bd 100644 --- a/api/src/org/apache/cloudstack/api/response/RemoteAccessVpnResponse.java +++ b/api/src/org/apache/cloudstack/api/response/RemoteAccessVpnResponse.java @@ -42,7 +42,7 @@ public class RemoteAccessVpnResponse extends BaseResponse implements ControlledE private String ipRange; @SerializedName("presharedkey") - @Param(description = "the ipsec preshared key") + @Param(description = "the ipsec preshared key", isSensitive = true) private String presharedKey; @SerializedName(ApiConstants.ACCOUNT) diff --git a/api/src/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java b/api/src/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java index 8a6ccd08b4e..2bda8f93f4d 100644 --- a/api/src/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java +++ b/api/src/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java @@ -51,7 +51,7 @@ public class Site2SiteCustomerGatewayResponse extends BaseResponse implements Co private String guestCidrList; @SerializedName(ApiConstants.IPSEC_PSK) - @Param(description = "IPsec preshared-key of customer gateway") + @Param(description = "IPsec preshared-key of customer gateway", isSensitive = true) private String ipsecPsk; @SerializedName(ApiConstants.IKE_POLICY) diff --git a/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java b/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java index 4c572566f85..c00a4d4aa52 100644 --- a/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java +++ b/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java @@ -58,7 +58,7 @@ public class Site2SiteVpnConnectionResponse extends BaseResponse implements Cont private String guestCidrList; @SerializedName(ApiConstants.IPSEC_PSK) - @Param(description = "IPsec Preshared-Key of the customer gateway") + @Param(description = "IPsec Preshared-Key of the customer gateway", isSensitive = true) //from CustomerGateway private String ipsecPsk; diff --git a/api/src/org/apache/cloudstack/api/response/UserResponse.java b/api/src/org/apache/cloudstack/api/response/UserResponse.java index 40e1561cb8d..36611ae7385 100644 --- a/api/src/org/apache/cloudstack/api/response/UserResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserResponse.java @@ -78,11 +78,11 @@ public class UserResponse extends BaseResponse { private String timezone; @SerializedName("apikey") - @Param(description = "the api key of the user") + @Param(description = "the api key of the user", isSensitive = true) private String apiKey; @SerializedName("secretkey") - @Param(description = "the secret key of the user") + @Param(description = "the secret key of the user", isSensitive = true) private String secretKey; @SerializedName("accountid") diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java index 36d82de993f..e8d1a9ed890 100644 --- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java @@ -221,7 +221,7 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp private Set securityGroupList; @SerializedName(ApiConstants.PASSWORD) - @Param(description = "the password (if exists) of the virtual machine") + @Param(description = "the password (if exists) of the virtual machine", isSensitive = true) private String password; @SerializedName("nic") diff --git a/plugins/network-elements/bigswitch/src/com/cloud/api/response/BigSwitchBcfDeviceResponse.java b/plugins/network-elements/bigswitch/src/com/cloud/api/response/BigSwitchBcfDeviceResponse.java index 1d1fe442430..e93f99d7d73 100644 --- a/plugins/network-elements/bigswitch/src/com/cloud/api/response/BigSwitchBcfDeviceResponse.java +++ b/plugins/network-elements/bigswitch/src/com/cloud/api/response/BigSwitchBcfDeviceResponse.java @@ -54,7 +54,7 @@ public class BigSwitchBcfDeviceResponse extends BaseResponse { @SerializedName(ApiConstants.USERNAME) @Param(description="the controller username") private String username; - @SerializedName(ApiConstants.PASSWORD) @Param(description="the controller password") + @SerializedName(ApiConstants.PASSWORD) @Param(description="the controller password", isSensitive = true) private String password; @SerializedName(BcfConstants.BIGSWITCH_BCF_DEVICE_NAT) diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LDAPConfigResponse.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LDAPConfigResponse.java index 8570bacab06..0f06e78020a 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LDAPConfigResponse.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LDAPConfigResponse.java @@ -53,7 +53,7 @@ public class LDAPConfigResponse extends BaseResponse { private String bindDN; @SerializedName(ApiConstants.BIND_PASSWORD) - @Param(description = "DN password") + @Param(description = "DN password", isSensitive = true) private String bindPassword; public String getHostname() { diff --git a/server/src/com/cloud/api/ApiResponseGsonHelper.java b/server/src/com/cloud/api/ApiResponseGsonHelper.java index c2cc9d92dbb..1708fa764d7 100644 --- a/server/src/com/cloud/api/ApiResponseGsonHelper.java +++ b/server/src/com/cloud/api/ApiResponseGsonHelper.java @@ -27,30 +27,40 @@ import com.google.gson.FieldAttributes; import com.google.gson.GsonBuilder; /** - * The ApiResonseGsonHelper is different from ApiGsonHelper - it registeres one more adapter for String type required for api response encoding + * The ApiResonseGsonHelper is different from ApiGsonHelper - it registers one more adapter for String type required for api response encoding */ public class ApiResponseGsonHelper { private static final GsonBuilder s_gBuilder; + private static final GsonBuilder s_gLogBuilder; static { s_gBuilder = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); s_gBuilder.setVersion(1.3); s_gBuilder.registerTypeAdapter(ResponseObject.class, new ResponseObjectTypeAdapter()); s_gBuilder.registerTypeAdapter(String.class, new EncodedStringTypeAdapter()); - s_gBuilder.setExclusionStrategies(new ExclStrat()); + s_gBuilder.setExclusionStrategies(new ApiResponseExclusionStrategy()); + + s_gLogBuilder = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + s_gLogBuilder.setVersion(1.3); + s_gLogBuilder.registerTypeAdapter(ResponseObject.class, new ResponseObjectTypeAdapter()); + s_gLogBuilder.registerTypeAdapter(String.class, new EncodedStringTypeAdapter()); + s_gLogBuilder.setExclusionStrategies(new LogExclusionStrategy()); } public static GsonBuilder getBuilder() { return s_gBuilder; } - private static class ExclStrat implements ExclusionStrategy { + public static GsonBuilder getLogBuilder() { + return s_gLogBuilder; + } + private static class ApiResponseExclusionStrategy implements ExclusionStrategy { public boolean shouldSkipClass(Class arg0) { return false; } - public boolean shouldSkipField(FieldAttributes f) { + public boolean shouldSkipField(FieldAttributes f) { Param param = f.getAnnotation(Param.class); if (param != null) { RoleType[] allowedRoles = param.authorized(); @@ -71,4 +81,19 @@ public class ApiResponseGsonHelper { return false; } } + + private static class LogExclusionStrategy extends ApiResponseExclusionStrategy implements ExclusionStrategy { + public boolean shouldSkipClass(Class arg0) { + return false; + } + + public boolean shouldSkipField(FieldAttributes f) { + Param param = f.getAnnotation(Param.class); + boolean skip = (param != null && param.isSensitive()); + if (!skip) { + skip = super.shouldSkipField(f); + } + return skip; + } + } } diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 1459dc28325..e5ae09725b3 100644 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -525,14 +525,9 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer cmdObj.setHttpMethod(paramMap.get(ApiConstants.HTTPMETHOD).toString()); // This is where the command is either serialized, or directly dispatched - response = queueCommand(cmdObj, paramMap); - if (annotation.responseHasSensitiveInfo()) - { - buildAuditTrail(auditTrailSb, command[0], - StringUtils.cleanString(response)); - } - else - buildAuditTrail(auditTrailSb, command[0], response); + StringBuilder log = new StringBuilder(); + response = queueCommand(cmdObj, paramMap, log); + buildAuditTrail(auditTrailSb, command[0], log.toString()); } else { final String errorString = "Unknown API command: " + command[0]; s_logger.warn(errorString); @@ -617,7 +612,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer return ApiResponseSerializer.toSerializedString(response, cmd.getResponseType()); } - private String queueCommand(final BaseCmd cmdObj, final Map params) throws Exception { + private String queueCommand(final BaseCmd cmdObj, final Map params, StringBuilder log) throws Exception { final CallContext ctx = CallContext.current(); final Long callerUserId = ctx.getCallingUserId(); final Account caller = ctx.getCallingAccount(); @@ -717,7 +712,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer } SerializationContext.current().setUuidTranslation(true); - return ApiResponseSerializer.toSerializedString((ResponseObject)cmdObj.getResponseObject(), cmdObj.getResponseType()); + return ApiResponseSerializer.toSerializedStringWithSecureLogs((ResponseObject)cmdObj.getResponseObject(), cmdObj.getResponseType(), log); } } diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 4322154a947..51827daf1d2 100644 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -147,8 +147,9 @@ public class ApiServlet extends HttpServlet { // logging the request start and end in management log for easy debugging String reqStr = ""; + String cleanQueryString = StringUtils.cleanString(req.getQueryString()); if (s_logger.isDebugEnabled()) { - reqStr = auditTrailSb.toString() + " " + StringUtils.cleanString(req.getQueryString()); + reqStr = auditTrailSb.toString() + " " + cleanQueryString; s_logger.debug("===START=== " + reqStr); } @@ -233,7 +234,7 @@ public class ApiServlet extends HttpServlet { } } - auditTrailSb.append(StringUtils.cleanString(req.getQueryString())); + auditTrailSb.append(cleanQueryString); final boolean isNew = ((session == null) ? true : session.isNew()); // Initialize an empty context and we will update it after we have verified the request below, diff --git a/server/src/com/cloud/api/response/ApiResponseSerializer.java b/server/src/com/cloud/api/response/ApiResponseSerializer.java index 19d26710540..59426e65742 100644 --- a/server/src/com/cloud/api/response/ApiResponseSerializer.java +++ b/server/src/com/cloud/api/response/ApiResponseSerializer.java @@ -27,6 +27,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExceptionProxyObject; import com.google.gson.Gson; import com.google.gson.annotations.SerializedName; + import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; @@ -56,9 +57,18 @@ public class ApiResponseSerializer { public static String toSerializedString(ResponseObject result, String responseType) { s_logger.trace("===Serializing Response==="); if (HttpUtils.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - return toJSONSerializedString(result); + return toJSONSerializedString(result, new StringBuilder()); } else { - return toXMLSerializedString(result); + return toXMLSerializedString(result, new StringBuilder()); + } + } + + public static String toSerializedStringWithSecureLogs(ResponseObject result, String responseType, StringBuilder log) { + s_logger.trace("===Serializing Response==="); + if (HttpUtils.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { + return toJSONSerializedString(result, log); + } else { + return toXMLSerializedString(result, log); } } @@ -73,51 +83,65 @@ public class ApiResponseSerializer { return str; } - public static String toJSONSerializedString(ResponseObject result) { - if (result != null) { - Gson gson = ApiResponseGsonHelper.getBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create(); + public static String toJSONSerializedString(ResponseObject result, StringBuilder log) { + if (result != null && log != null) { + Gson responseBuilder = ApiResponseGsonHelper.getBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create(); + Gson logBuilder = ApiResponseGsonHelper.getLogBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create(); StringBuilder sb = new StringBuilder(); sb.append("{\"").append(result.getResponseName()).append("\":"); + log.append("{\"").append(result.getResponseName()).append("\":"); if (result instanceof ListResponse) { List responses = ((ListResponse)result).getResponses(); Integer count = ((ListResponse)result).getCount(); boolean nonZeroCount = (count != null && count.longValue() != 0); if (nonZeroCount) { sb.append("{\"").append(ApiConstants.COUNT).append("\":").append(count); + log.append("{\"").append(ApiConstants.COUNT).append("\":").append(count); } if ((responses != null) && !responses.isEmpty()) { - String jsonStr = gson.toJson(responses.get(0)); + String jsonStr = responseBuilder.toJson(responses.get(0)); jsonStr = unescape(jsonStr); + String logStr = logBuilder.toJson(responses.get(0)); + logStr = unescape(logStr); if (nonZeroCount) { sb.append(",\"").append(responses.get(0).getObjectName()).append("\":[").append(jsonStr); + log.append(",\"").append(responses.get(0).getObjectName()).append("\":[").append(logStr); } for (int i = 1; i < ((ListResponse)result).getResponses().size(); i++) { - jsonStr = gson.toJson(responses.get(i)); + jsonStr = responseBuilder.toJson(responses.get(i)); jsonStr = unescape(jsonStr); + logStr = logBuilder.toJson(responses.get(i)); + logStr = unescape(logStr); sb.append(",").append(jsonStr); + log.append(",").append(logStr); } sb.append("]}"); + log.append("]}"); } else { if (!nonZeroCount) { sb.append("{"); + log.append("{"); } sb.append("}"); + log.append("}"); } } else if (result instanceof SuccessResponse) { sb.append("{\"success\":\"").append(((SuccessResponse)result).getSuccess()).append("\"}"); + log.append("{\"success\":\"").append(((SuccessResponse)result).getSuccess()).append("\"}"); } else if (result instanceof ExceptionResponse) { - String jsonErrorText = gson.toJson(result); + String jsonErrorText = responseBuilder.toJson(result); jsonErrorText = unescape(jsonErrorText); sb.append(jsonErrorText); + log.append(jsonErrorText); } else { - String jsonStr = gson.toJson(result); - if ((jsonStr != null) && !"".equals(jsonStr)) { + String jsonStr = responseBuilder.toJson(result); + if (jsonStr != null && !jsonStr.isEmpty()) { jsonStr = unescape(jsonStr); if (result instanceof AsyncJobResponse || result instanceof CreateCmdResponse || result instanceof AuthenticationCmdResponse) { sb.append(jsonStr); @@ -127,53 +151,74 @@ public class ApiResponseSerializer { } else { sb.append("{}"); } + String logStr = logBuilder.toJson(result); + if (logStr != null && !logStr.isEmpty()) { + logStr = unescape(logStr); + if (result instanceof AsyncJobResponse || result instanceof CreateCmdResponse || result instanceof AuthenticationCmdResponse) { + log.append(logStr); + } else { + log.append("{\"").append(result.getObjectName()).append("\":").append(logStr).append("}"); + } + } else { + log.append("{}"); + } } sb.append("}"); + log.append("}"); return sb.toString(); } return null; } - private static String toXMLSerializedString(ResponseObject result) { - StringBuilder sb = new StringBuilder(); - sb.append(""); - sb.append("<").append(result.getResponseName()).append(" cloud-stack-version=\"").append(ApiDBUtils.getVersion()).append("\">"); + private static String toXMLSerializedString(ResponseObject result, StringBuilder log) { + if (result != null && log != null) { + StringBuilder sb = new StringBuilder(); + sb.append(""); + sb.append("<").append(result.getResponseName()).append(" cloud-stack-version=\"").append(ApiDBUtils.getVersion()).append("\">"); + log.append(""); + log.append("<").append(result.getResponseName()).append(" cloud-stack-version=\"").append(ApiDBUtils.getVersion()).append("\">"); - if (result instanceof ListResponse) { - Integer count = ((ListResponse)result).getCount(); + if (result instanceof ListResponse) { + Integer count = ((ListResponse)result).getCount(); - if (count != null && count != 0) { - sb.append("<").append(ApiConstants.COUNT).append(">").append(((ListResponse)result).getCount()).append(""); - } - List responses = ((ListResponse)result).getResponses(); - if ((responses != null) && !responses.isEmpty()) { - for (ResponseObject obj : responses) { - serializeResponseObjXML(sb, obj); + if (count != null && count != 0) { + sb.append("<").append(ApiConstants.COUNT).append(">").append(((ListResponse)result).getCount()).append(""); + log.append("<").append(ApiConstants.COUNT).append(">").append(((ListResponse)result).getCount()).append(""); + } + List responses = ((ListResponse)result).getResponses(); + if ((responses != null) && !responses.isEmpty()) { + for (ResponseObject obj : responses) { + serializeResponseObjXML(sb, log, obj); + } + } + } else { + if (result instanceof CreateCmdResponse || result instanceof AsyncJobResponse || result instanceof AuthenticationCmdResponse) { + serializeResponseObjFieldsXML(sb, log, result); + } else { + serializeResponseObjXML(sb, log, result); } } - } else { - if (result instanceof CreateCmdResponse || result instanceof AsyncJobResponse || result instanceof AuthenticationCmdResponse) { - serializeResponseObjFieldsXML(sb, result); - } else { - serializeResponseObjXML(sb, result); - } - } - sb.append(""); - return sb.toString(); + sb.append(""); + log.append(""); + return sb.toString(); + } + return null; } - private static void serializeResponseObjXML(StringBuilder sb, ResponseObject obj) { + private static void serializeResponseObjXML(StringBuilder sb, StringBuilder log, ResponseObject obj) { if (!(obj instanceof SuccessResponse) && !(obj instanceof ExceptionResponse)) { sb.append("<").append(obj.getObjectName()).append(">"); + log.append("<").append(obj.getObjectName()).append(">"); } - serializeResponseObjFieldsXML(sb, obj); + serializeResponseObjFieldsXML(sb, log, obj); if (!(obj instanceof SuccessResponse) && !(obj instanceof ExceptionResponse)) { sb.append(""); + log.append(""); } } - public static Field[] getFlattenFields(Class clz) { + private static Field[] getFlattenFields(Class clz) { List fields = new ArrayList(); fields.addAll(Arrays.asList(clz.getDeclaredFields())); if (clz.getSuperclass() != null) { @@ -182,24 +227,23 @@ public class ApiResponseSerializer { return fields.toArray(new Field[] {}); } - private static void serializeResponseObjFieldsXML(StringBuilder sb, ResponseObject obj) { + private static void serializeResponseObjFieldsXML(StringBuilder sb, StringBuilder log, ResponseObject obj) { boolean isAsync = false; if (obj instanceof AsyncJobResponse) isAsync = true; - //Field[] fields = obj.getClass().getDeclaredFields(); Field[] fields = getFlattenFields(obj.getClass()); for (Field field : fields) { if ((field.getModifiers() & Modifier.TRANSIENT) != 0) { continue; // skip transient fields } - SerializedName serializedName = field.getAnnotation(SerializedName.class); if (serializedName == null) { continue; // skip fields w/o serialized name } + boolean logField = true; Param param = field.getAnnotation(Param.class); if (param != null) { RoleType[] allowedRoles = param.authorized(); @@ -213,10 +257,13 @@ public class ApiResponseSerializer { } } if (!permittedParameter) { - s_logger.trace("Ignoring paremeter " + param.name() + " as the caller is not authorized to see it"); + s_logger.trace("Ignoring parameter " + param.name() + " as the caller is not authorized to see it"); continue; } } + if (param.isSensitive()) { + logField = false; + } } field.setAccessible(true); @@ -233,10 +280,12 @@ public class ApiResponseSerializer { ResponseObject subObj = (ResponseObject)fieldValue; if (isAsync) { sb.append(""); + log.append(""); } - serializeResponseObjXML(sb, subObj); + serializeResponseObjXML(sb, log, subObj); if (isAsync) { sb.append(""); + log.append(""); } } else if (fieldValue instanceof Collection) { Collection subResponseList = (Collection)fieldValue; @@ -247,7 +296,7 @@ public class ApiResponseSerializer { if (serializedName != null) { subObj.setObjectName(serializedName.value()); } - serializeResponseObjXML(sb, subObj); + serializeResponseObjXML(sb, log, subObj); } else if (value instanceof ExceptionProxyObject) { // Only exception reponses carry a list of // ExceptionProxyObject objects. @@ -256,30 +305,32 @@ public class ApiResponseSerializer { // encountered, put in a uuidList tag. if (!usedUuidList) { sb.append("<" + serializedName.value() + ">"); + log.append("<" + serializedName.value() + ">"); usedUuidList = true; } sb.append("<" + "uuid" + ">" + idProxy.getUuid() + ""); + log.append("<" + "uuid" + ">" + idProxy.getUuid() + ""); // Append the new descriptive property also. String idFieldName = idProxy.getDescription(); if (idFieldName != null) { sb.append("<" + "uuidProperty" + ">" + idFieldName + ""); + log.append("<" + "uuidProperty" + ">" + idFieldName + ""); } } else if (value instanceof String) { sb.append("<").append(serializedName.value()).append(">").append(value).append(""); + if (logField) { + log.append("<").append(serializedName.value()).append(">").append(value).append(""); + } } } if (usedUuidList) { // close the uuidList. sb.append(""); + log.append(""); } } else if (fieldValue instanceof Date) { - sb.append("<") - .append(serializedName.value()) - .append(">") - .append(BaseCmd.getDateString((Date)fieldValue)) - .append(""); + sb.append("<").append(serializedName.value()).append(">").append(BaseCmd.getDateString((Date)fieldValue)).append(""); + log.append("<").append(serializedName.value()).append(">").append(BaseCmd.getDateString((Date)fieldValue)).append(""); } else { String resultString = escapeSpecialXmlChars(fieldValue.toString()); if (!(obj instanceof ExceptionResponse)) { @@ -287,6 +338,9 @@ public class ApiResponseSerializer { } sb.append("<").append(serializedName.value()).append(">").append(resultString).append(""); + if (logField) { + log.append("<").append(serializedName.value()).append(">").append(resultString).append(""); + } } } }