api: listApis should return params based on caller (#8973)

This commit is contained in:
Abhishek Kumar 2024-06-11 11:28:08 +05:30 committed by GitHub
parent fcca3e8f39
commit 7aacbcb559
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 65 additions and 11 deletions

View File

@ -16,13 +16,14 @@
// under the License.
package org.apache.cloudstack.api.response;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import java.util.HashSet;
import java.util.Set;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import java.util.HashSet;
import java.util.Set;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
@SuppressWarnings("unused")
public class ApiDiscoveryResponse extends BaseResponse {
@ -64,6 +65,18 @@ public class ApiDiscoveryResponse extends BaseResponse {
isAsync = false;
}
public ApiDiscoveryResponse(ApiDiscoveryResponse another) {
this.name = another.getName();
this.description = another.getDescription();
this.since = another.getSince();
this.isAsync = another.getAsync();
this.related = another.getRelated();
this.params = new HashSet<>(another.getParams());
this.apiResponse = new HashSet<>(another.getApiResponse());
this.type = another.getType();
this.setObjectName(another.getObjectName());
}
public void setName(String name) {
this.name = name;
}
@ -123,4 +136,8 @@ public class ApiDiscoveryResponse extends BaseResponse {
public Set<ApiResponseResponse> getApiResponse() {
return apiResponse;
}
public String getType() {
return type;
}
}

View File

@ -16,12 +16,14 @@
// under the License.
package org.apache.cloudstack.api.response;
import com.google.gson.annotations.SerializedName;
import java.util.List;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
public class ApiParameterResponse extends BaseResponse {
@SerializedName(ApiConstants.NAME)
@ -52,6 +54,8 @@ public class ApiParameterResponse extends BaseResponse {
@Param(description = "comma separated related apis to get the parameter")
private String related;
private transient List<RoleType> authorizedRoleTypes = null;
public ApiParameterResponse() {
}
@ -87,4 +91,11 @@ public class ApiParameterResponse extends BaseResponse {
this.related = related;
}
public void setAuthorizedRoleTypes(List<RoleType> authorizedRoleTypes) {
this.authorizedRoleTypes = authorizedRoleTypes;
}
public List<RoleType> getAuthorizedRoleTypes() {
return authorizedRoleTypes;
}
}

View File

@ -18,8 +18,10 @@ package org.apache.cloudstack.discovery;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@ -28,21 +30,22 @@ import java.util.Set;
import javax.inject.Inject;
import org.apache.cloudstack.acl.APIChecker;
import org.apache.cloudstack.acl.Role;
import org.apache.cloudstack.acl.RoleService;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.acl.Role;
import org.apache.cloudstack.acl.RoleService;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.command.user.discovery.ListApisCmd;
import org.apache.cloudstack.api.response.ApiDiscoveryResponse;
import org.apache.cloudstack.api.response.ApiParameterResponse;
import org.apache.cloudstack.api.response.ApiResponseResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.reflections.ReflectionUtils;
@ -217,6 +220,9 @@ public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements A
paramResponse.setSince(parameterAnnotation.since());
}
paramResponse.setRelated(parameterAnnotation.entityType()[0].getName());
if (parameterAnnotation.authorized() != null) {
paramResponse.setAuthorizedRoleTypes(Arrays.asList(parameterAnnotation.authorized()));
}
response.addParam(paramResponse);
}
}
@ -249,6 +255,7 @@ public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements A
if (user == null)
return null;
Account account = accountService.getAccount(user.getAccountId());
if (name != null) {
if (!s_apiNameDiscoveryResponseMap.containsKey(name))
@ -262,10 +269,9 @@ public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements A
return null;
}
}
responseList.add(s_apiNameDiscoveryResponseMap.get(name));
responseList.add(getApiDiscoveryResponseWithAccessibleParams(name, account));
} else {
Account account = accountService.getAccount(user.getAccountId());
if (account == null) {
throw new PermissionDeniedException(String.format("The account with id [%s] for user [%s] is null.", user.getAccountId(), user));
}
@ -286,13 +292,33 @@ public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements A
}
for (String apiName: apisAllowed) {
responseList.add(s_apiNameDiscoveryResponseMap.get(apiName));
responseList.add(getApiDiscoveryResponseWithAccessibleParams(apiName, account));
}
}
response.setResponses(responseList);
return response;
}
private static ApiDiscoveryResponse getApiDiscoveryResponseWithAccessibleParams(String name, Account account) {
if (Account.Type.ADMIN.equals(account.getType())) {
return s_apiNameDiscoveryResponseMap.get(name);
}
ApiDiscoveryResponse apiDiscoveryResponse =
new ApiDiscoveryResponse(s_apiNameDiscoveryResponseMap.get(name));
Iterator<ApiParameterResponse> iterator = apiDiscoveryResponse.getParams().iterator();
while (iterator.hasNext()) {
ApiParameterResponse parameterResponse = iterator.next();
List<RoleType> authorizedRoleTypes = parameterResponse.getAuthorizedRoleTypes();
RoleType accountRoleType = RoleType.getByAccountType(account.getType());
if (CollectionUtils.isNotEmpty(parameterResponse.getAuthorizedRoleTypes()) &&
accountRoleType != null &&
!authorizedRoleTypes.contains(accountRoleType)) {
iterator.remove();
}
}
return apiDiscoveryResponse;
}
@Override
public List<Class<?>> getCommands() {
List<Class<?>> cmdList = new ArrayList<Class<?>>();