Skip to content

Commit 7aacbcb

Browse files
authored
api: listApis should return params based on caller (#8973)
1 parent fcca3e8 commit 7aacbcb

File tree

3 files changed

+65
-11
lines changed

3 files changed

+65
-11
lines changed

plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.response;
1818

19-
import com.cloud.serializer.Param;
20-
import com.google.gson.annotations.SerializedName;
19+
import java.util.HashSet;
20+
import java.util.Set;
21+
2122
import org.apache.cloudstack.api.ApiConstants;
2223
import org.apache.cloudstack.api.BaseResponse;
2324

24-
import java.util.HashSet;
25-
import java.util.Set;
25+
import com.cloud.serializer.Param;
26+
import com.google.gson.annotations.SerializedName;
2627

2728
@SuppressWarnings("unused")
2829
public class ApiDiscoveryResponse extends BaseResponse {
@@ -64,6 +65,18 @@ public ApiDiscoveryResponse() {
6465
isAsync = false;
6566
}
6667

68+
public ApiDiscoveryResponse(ApiDiscoveryResponse another) {
69+
this.name = another.getName();
70+
this.description = another.getDescription();
71+
this.since = another.getSince();
72+
this.isAsync = another.getAsync();
73+
this.related = another.getRelated();
74+
this.params = new HashSet<>(another.getParams());
75+
this.apiResponse = new HashSet<>(another.getApiResponse());
76+
this.type = another.getType();
77+
this.setObjectName(another.getObjectName());
78+
}
79+
6780
public void setName(String name) {
6881
this.name = name;
6982
}
@@ -123,4 +136,8 @@ public void addApiResponse(ApiResponseResponse apiResponse) {
123136
public Set<ApiResponseResponse> getApiResponse() {
124137
return apiResponse;
125138
}
139+
140+
public String getType() {
141+
return type;
142+
}
126143
}

plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiParameterResponse.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.response;
1818

19-
import com.google.gson.annotations.SerializedName;
19+
import java.util.List;
2020

21+
import org.apache.cloudstack.acl.RoleType;
2122
import org.apache.cloudstack.api.ApiConstants;
2223
import org.apache.cloudstack.api.BaseResponse;
2324

2425
import com.cloud.serializer.Param;
26+
import com.google.gson.annotations.SerializedName;
2527

2628
public class ApiParameterResponse extends BaseResponse {
2729
@SerializedName(ApiConstants.NAME)
@@ -52,6 +54,8 @@ public class ApiParameterResponse extends BaseResponse {
5254
@Param(description = "comma separated related apis to get the parameter")
5355
private String related;
5456

57+
private transient List<RoleType> authorizedRoleTypes = null;
58+
5559
public ApiParameterResponse() {
5660
}
5761

@@ -87,4 +91,11 @@ public void setRelated(String related) {
8791
this.related = related;
8892
}
8993

94+
public void setAuthorizedRoleTypes(List<RoleType> authorizedRoleTypes) {
95+
this.authorizedRoleTypes = authorizedRoleTypes;
96+
}
97+
98+
public List<RoleType> getAuthorizedRoleTypes() {
99+
return authorizedRoleTypes;
100+
}
90101
}

plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818

1919
import java.lang.reflect.Field;
2020
import java.util.ArrayList;
21+
import java.util.Arrays;
2122
import java.util.HashMap;
2223
import java.util.HashSet;
24+
import java.util.Iterator;
2325
import java.util.LinkedHashSet;
2426
import java.util.List;
2527
import java.util.Map;
@@ -28,21 +30,22 @@
2830
import javax.inject.Inject;
2931

3032
import org.apache.cloudstack.acl.APIChecker;
33+
import org.apache.cloudstack.acl.Role;
34+
import org.apache.cloudstack.acl.RoleService;
35+
import org.apache.cloudstack.acl.RoleType;
3136
import org.apache.cloudstack.api.APICommand;
3237
import org.apache.cloudstack.api.BaseAsyncCmd;
3338
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
3439
import org.apache.cloudstack.api.BaseCmd;
3540
import org.apache.cloudstack.api.BaseResponse;
3641
import org.apache.cloudstack.api.Parameter;
37-
import org.apache.cloudstack.acl.Role;
38-
import org.apache.cloudstack.acl.RoleService;
39-
import org.apache.cloudstack.acl.RoleType;
4042
import org.apache.cloudstack.api.command.user.discovery.ListApisCmd;
4143
import org.apache.cloudstack.api.response.ApiDiscoveryResponse;
4244
import org.apache.cloudstack.api.response.ApiParameterResponse;
4345
import org.apache.cloudstack.api.response.ApiResponseResponse;
4446
import org.apache.cloudstack.api.response.ListResponse;
4547
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
48+
import org.apache.commons.collections.CollectionUtils;
4649
import org.apache.commons.lang3.StringUtils;
4750
import org.apache.log4j.Logger;
4851
import org.reflections.ReflectionUtils;
@@ -217,6 +220,9 @@ private ApiDiscoveryResponse getCmdRequestMap(Class<?> cmdClass, APICommand apiC
217220
paramResponse.setSince(parameterAnnotation.since());
218221
}
219222
paramResponse.setRelated(parameterAnnotation.entityType()[0].getName());
223+
if (parameterAnnotation.authorized() != null) {
224+
paramResponse.setAuthorizedRoleTypes(Arrays.asList(parameterAnnotation.authorized()));
225+
}
220226
response.addParam(paramResponse);
221227
}
222228
}
@@ -249,6 +255,7 @@ public ListResponse<? extends BaseResponse> listApis(User user, String name) {
249255

250256
if (user == null)
251257
return null;
258+
Account account = accountService.getAccount(user.getAccountId());
252259

253260
if (name != null) {
254261
if (!s_apiNameDiscoveryResponseMap.containsKey(name))
@@ -262,10 +269,9 @@ public ListResponse<? extends BaseResponse> listApis(User user, String name) {
262269
return null;
263270
}
264271
}
265-
responseList.add(s_apiNameDiscoveryResponseMap.get(name));
272+
responseList.add(getApiDiscoveryResponseWithAccessibleParams(name, account));
266273

267274
} else {
268-
Account account = accountService.getAccount(user.getAccountId());
269275
if (account == null) {
270276
throw new PermissionDeniedException(String.format("The account with id [%s] for user [%s] is null.", user.getAccountId(), user));
271277
}
@@ -286,13 +292,33 @@ public ListResponse<? extends BaseResponse> listApis(User user, String name) {
286292
}
287293

288294
for (String apiName: apisAllowed) {
289-
responseList.add(s_apiNameDiscoveryResponseMap.get(apiName));
295+
responseList.add(getApiDiscoveryResponseWithAccessibleParams(apiName, account));
290296
}
291297
}
292298
response.setResponses(responseList);
293299
return response;
294300
}
295301

302+
private static ApiDiscoveryResponse getApiDiscoveryResponseWithAccessibleParams(String name, Account account) {
303+
if (Account.Type.ADMIN.equals(account.getType())) {
304+
return s_apiNameDiscoveryResponseMap.get(name);
305+
}
306+
ApiDiscoveryResponse apiDiscoveryResponse =
307+
new ApiDiscoveryResponse(s_apiNameDiscoveryResponseMap.get(name));
308+
Iterator<ApiParameterResponse> iterator = apiDiscoveryResponse.getParams().iterator();
309+
while (iterator.hasNext()) {
310+
ApiParameterResponse parameterResponse = iterator.next();
311+
List<RoleType> authorizedRoleTypes = parameterResponse.getAuthorizedRoleTypes();
312+
RoleType accountRoleType = RoleType.getByAccountType(account.getType());
313+
if (CollectionUtils.isNotEmpty(parameterResponse.getAuthorizedRoleTypes()) &&
314+
accountRoleType != null &&
315+
!authorizedRoleTypes.contains(accountRoleType)) {
316+
iterator.remove();
317+
}
318+
}
319+
return apiDiscoveryResponse;
320+
}
321+
296322
@Override
297323
public List<Class<?>> getCommands() {
298324
List<Class<?>> cmdList = new ArrayList<Class<?>>();

0 commit comments

Comments
 (0)