API response: added new field to @Param - RoleType[] authorized() default {}.
The field defines who is authorized to see this partciluar reponse field. If
not specified, the parameter is returned to everybody
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/21d016b3
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/21d016b3
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/21d016b3
Branch: refs/heads/master
Commit: 21d016b3dd855e47c87c62c3e4a4e2b2ec2fb257
Parents: 2f7bfc0
Author: Alena Prokharchyk <[email protected]>
Authored: Thu Feb 20 17:14:11 2014 -0800
Committer: Alena Prokharchyk <[email protected]>
Committed: Thu Feb 20 17:15:43 2014 -0800
----------------------------------------------------------------------
api/src/com/cloud/serializer/Param.java | 4 ++
.../api/response/IPAddressResponse.java | 3 +-
.../api/response/NetworkResponse.java | 6 +--
.../cloudstack/api/response/UserVmResponse.java | 3 +-
.../cloudstack/api/response/VolumeResponse.java | 3 +-
.../cloudstack/api/response/VpcResponse.java | 3 +-
server/src/com/cloud/api/ApiGsonHelper.java | 4 +-
.../com/cloud/api/ApiResponseGsonHelper.java | 39 +++++++++++++++++++-
.../cloud/api/ResponseObjectTypeAdapter.java | 7 ++--
.../api/response/ApiResponseSerializer.java | 24 ++++++++++++
10 files changed, 81 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21d016b3/api/src/com/cloud/serializer/Param.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/serializer/Param.java
b/api/src/com/cloud/serializer/Param.java
index 02deb6f..3e6f852 100644
--- a/api/src/com/cloud/serializer/Param.java
+++ b/api/src/com/cloud/serializer/Param.java
@@ -19,6 +19,8 @@ package com.cloud.serializer;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import org.apache.cloudstack.acl.RoleType;
+
@Retention(RetentionPolicy.RUNTIME)
public @interface Param {
String name() default "";
@@ -33,4 +35,6 @@ public @interface Param {
boolean includeInApiDoc() default true;
String since() default "";
+
+ RoleType[] authorized() default {};
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21d016b3/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java
b/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java
index 1f51d5a..3c03247 100644
--- a/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java
@@ -19,6 +19,7 @@ package org.apache.cloudstack.api.response;
import java.util.Date;
import java.util.List;
+import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
@@ -146,7 +147,7 @@ public class IPAddressResponse extends BaseResponse
implements ControlledEntityR
private Boolean isPortable;
@SerializedName(ApiConstants.FOR_DISPLAY)
- @Param(description = "is public ip for display to the regular user", since
= "4.4")
+ @Param(description = "is public ip for display to the regular user", since
= "4.4", authorized = {RoleType.Admin})
private Boolean forDisplay;
/*
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21d016b3/api/src/org/apache/cloudstack/api/response/NetworkResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java
b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java
index 58ec956..bf92aa4 100644
--- a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java
@@ -18,8 +18,7 @@ package org.apache.cloudstack.api.response;
import java.util.List;
-import com.google.gson.annotations.SerializedName;
-
+import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
@@ -27,6 +26,7 @@ import org.apache.cloudstack.api.EntityReference;
import com.cloud.network.Network;
import com.cloud.projects.ProjectAccount;
import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
@SuppressWarnings("unused")
@EntityReference(value = {Network.class, ProjectAccount.class})
@@ -209,7 +209,7 @@ public class NetworkResponse extends BaseResponse
implements ControlledEntityRes
private String ip6Cidr;
@SerializedName(ApiConstants.DISPLAY_NETWORK)
- @Param(description = "an optional field, whether to the display the
network to the end user or not.")
+ @Param(description = "an optional field, whether to the display the
network to the end user or not.", authorized = {RoleType.Admin})
private Boolean displayNetwork;
@SerializedName(ApiConstants.ACL_ID)
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21d016b3/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
index 26ecb5b..84d532b 100644
--- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
@@ -21,6 +21,7 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
+import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
@@ -248,7 +249,7 @@ public class UserVmResponse extends BaseResponse implements
ControlledEntityResp
private Set<AffinityGroupResponse> affinityGroupList;
@SerializedName(ApiConstants.DISPLAY_VM)
- @Param(description = "an optional field whether to the display the vm to
the end user or not.")
+ @Param(description = "an optional field whether to the display the vm to
the end user or not.", authorized = {RoleType.Admin})
private Boolean displayVm;
@SerializedName(ApiConstants.IS_DYNAMICALLY_SCALABLE)
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21d016b3/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
index 319a734..27e95de 100644
--- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
@@ -20,6 +20,7 @@ import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Set;
+import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
@@ -188,7 +189,7 @@ public class VolumeResponse extends BaseResponse implements
ControlledViewEntity
private Set<ResourceTagResponse> tags;
@SerializedName(ApiConstants.DISPLAY_VOLUME)
- @Param(description = "an optional field whether to the display the volume
to the end user or not.")
+ @Param(description = "an optional field whether to the display the volume
to the end user or not.", authorized = {RoleType.Admin})
private Boolean displayVolume;
@SerializedName(ApiConstants.PATH)
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21d016b3/api/src/org/apache/cloudstack/api/response/VpcResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/VpcResponse.java
b/api/src/org/apache/cloudstack/api/response/VpcResponse.java
index 928d1b2..eeafb40 100644
--- a/api/src/org/apache/cloudstack/api/response/VpcResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/VpcResponse.java
@@ -19,6 +19,7 @@ package org.apache.cloudstack.api.response;
import java.util.Date;
import java.util.List;
+import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
@@ -107,7 +108,7 @@ public class VpcResponse extends BaseResponse implements
ControlledEntityRespons
private List<ResourceTagResponse> tags;
@SerializedName(ApiConstants.FOR_DISPLAY)
- @Param(description = "is vpc for display to the regular user", since =
"4.4")
+ @Param(description = "is vpc for display to the regular user", since =
"4.4", authorized = {RoleType.Admin})
private Boolean forDisplay;
public void setId(String id) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21d016b3/server/src/com/cloud/api/ApiGsonHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiGsonHelper.java
b/server/src/com/cloud/api/ApiGsonHelper.java
index 58f29ce..faa70c2 100644
--- a/server/src/com/cloud/api/ApiGsonHelper.java
+++ b/server/src/com/cloud/api/ApiGsonHelper.java
@@ -18,10 +18,10 @@ package com.cloud.api;
import java.util.Map;
-import com.google.gson.GsonBuilder;
-
import org.apache.cloudstack.api.ResponseObject;
+import com.google.gson.GsonBuilder;
+
public class ApiGsonHelper {
private static final GsonBuilder s_gBuilder;
static {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21d016b3/server/src/com/cloud/api/ApiResponseGsonHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseGsonHelper.java
b/server/src/com/cloud/api/ApiResponseGsonHelper.java
index 3352cc8..c2cc9d9 100644
--- a/server/src/com/cloud/api/ApiResponseGsonHelper.java
+++ b/server/src/com/cloud/api/ApiResponseGsonHelper.java
@@ -16,9 +16,15 @@
// under the License.
package com.cloud.api;
-import com.google.gson.GsonBuilder;
-
+import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.ResponseObject;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.serializer.Param;
+import com.cloud.user.Account;
+import com.google.gson.ExclusionStrategy;
+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
@@ -31,9 +37,38 @@ public class ApiResponseGsonHelper {
s_gBuilder.setVersion(1.3);
s_gBuilder.registerTypeAdapter(ResponseObject.class, new
ResponseObjectTypeAdapter());
s_gBuilder.registerTypeAdapter(String.class, new
EncodedStringTypeAdapter());
+ s_gBuilder.setExclusionStrategies(new ExclStrat());
}
public static GsonBuilder getBuilder() {
return s_gBuilder;
}
+
+ private static class ExclStrat implements ExclusionStrategy {
+
+ public boolean shouldSkipClass(Class<?> arg0) {
+ return false;
+ }
+ public boolean shouldSkipField(FieldAttributes f) {
+
+ Param param = f.getAnnotation(Param.class);
+ if (param != null) {
+ RoleType[] allowedRoles = param.authorized();
+ if (allowedRoles.length > 0) {
+ boolean permittedParameter = false;
+ Account caller = CallContext.current().getCallingAccount();
+ for (RoleType allowedRole : allowedRoles) {
+ if (allowedRole.getValue() == caller.getType()) {
+ permittedParameter = true;
+ break;
+ }
+ }
+ if (!permittedParameter) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21d016b3/server/src/com/cloud/api/ResponseObjectTypeAdapter.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ResponseObjectTypeAdapter.java
b/server/src/com/cloud/api/ResponseObjectTypeAdapter.java
index a4bc6ca..44baedc 100644
--- a/server/src/com/cloud/api/ResponseObjectTypeAdapter.java
+++ b/server/src/com/cloud/api/ResponseObjectTypeAdapter.java
@@ -19,6 +19,9 @@ package com.cloud.api;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
+import org.apache.cloudstack.api.ResponseObject;
+import org.apache.cloudstack.api.response.ExceptionResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.log4j.Logger;
import com.google.gson.JsonElement;
@@ -26,10 +29,6 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
-import org.apache.cloudstack.api.ResponseObject;
-import org.apache.cloudstack.api.response.ExceptionResponse;
-import org.apache.cloudstack.api.response.SuccessResponse;
-
public class ResponseObjectTypeAdapter implements
JsonSerializer<ResponseObject> {
public static final Logger s_logger =
Logger.getLogger(ResponseObjectTypeAdapter.class.getName());
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21d016b3/server/src/com/cloud/api/response/ApiResponseSerializer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/response/ApiResponseSerializer.java
b/server/src/com/cloud/api/response/ApiResponseSerializer.java
index f276e89..e9633a7 100644
--- a/server/src/com/cloud/api/response/ApiResponseSerializer.java
+++ b/server/src/com/cloud/api/response/ApiResponseSerializer.java
@@ -26,6 +26,7 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.ResponseObject;
@@ -34,11 +35,14 @@ import org.apache.cloudstack.api.response.CreateCmdResponse;
import org.apache.cloudstack.api.response.ExceptionResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.ApiResponseGsonHelper;
import com.cloud.api.ApiServer;
+import com.cloud.serializer.Param;
+import com.cloud.user.Account;
import com.cloud.utils.encoding.URLEncoder;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExceptionProxyObject;
@@ -189,11 +193,31 @@ public class ApiResponseSerializer {
continue; // skip transient fields
}
+
SerializedName serializedName =
field.getAnnotation(SerializedName.class);
if (serializedName == null) {
continue; // skip fields w/o serialized name
}
+ Param param = field.getAnnotation(Param.class);
+ if (param != null) {
+ RoleType[] allowedRoles = param.authorized();
+ if (allowedRoles.length > 0) {
+ boolean permittedParameter = false;
+ Account caller = CallContext.current().getCallingAccount();
+ for (RoleType allowedRole : allowedRoles) {
+ if (allowedRole.getValue() == caller.getType()) {
+ permittedParameter = true;
+ break;
+ }
+ }
+ if (!permittedParameter) {
+ s_logger.trace("Ignoring paremeter " + param.name() +
" as the caller is not authorized to see it");
+ continue;
+ }
+ }
+ }
+
field.setAccessible(true);
Object fieldValue = null;
try {