-
Notifications
You must be signed in to change notification settings - Fork 639
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update retrieval of URITemplates, scopes and roles from swagger in the local entry #7401
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,8 @@ | |
import org.apache.synapse.rest.RESTUtils; | ||
import org.apache.synapse.rest.Resource; | ||
import org.apache.synapse.rest.dispatch.RESTDispatcher; | ||
import org.wso2.carbon.apimgt.api.APIDefinition; | ||
import org.wso2.carbon.apimgt.api.APIManagementException; | ||
import org.wso2.carbon.apimgt.api.model.URITemplate; | ||
import org.wso2.carbon.apimgt.gateway.APIMgtGatewayConstants; | ||
import org.wso2.carbon.apimgt.gateway.MethodStats; | ||
|
@@ -39,6 +41,8 @@ | |
import org.wso2.carbon.apimgt.impl.APIConstants; | ||
import org.wso2.carbon.apimgt.impl.APIManagerConfiguration; | ||
import org.wso2.carbon.apimgt.impl.caching.CacheProvider; | ||
import org.wso2.carbon.apimgt.impl.definitions.OAS2Parser; | ||
import org.wso2.carbon.apimgt.impl.definitions.OASParserUtil; | ||
import org.wso2.carbon.apimgt.impl.dto.APIInfoDTO; | ||
import org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO; | ||
import org.wso2.carbon.apimgt.impl.dto.ResourceInfoDTO; | ||
|
@@ -81,6 +85,8 @@ public class APIKeyValidator { | |
|
||
protected Log log = LogFactory.getLog(getClass()); | ||
|
||
private ArrayList<URITemplate> uriTemplates = null; | ||
|
||
public APIKeyValidator(AxisConfiguration axisConfig) { | ||
//check the client type from config | ||
String keyValidatorClientType = getKeyValidatorClientType(); | ||
|
@@ -294,7 +300,7 @@ public String getResourceAuthenticationScheme(MessageContext synCtx) throws APIS | |
for (VerbInfoDTO verb : verbInfoList) { | ||
authType = verb.getAuthType(); | ||
if (authType == null) { | ||
authType = StringUtils.capitalize(APIConstants.AUTH_TYPE_NONE.toLowerCase());; | ||
authType = StringUtils.capitalize(APIConstants.AUTH_APPLICATION_OR_USER_LEVEL_TOKEN.toLowerCase()); | ||
} | ||
if (!StringUtils.capitalize(APIConstants.AUTH_TYPE_NONE.toLowerCase()).equals(authType)) { | ||
break; | ||
|
@@ -461,9 +467,9 @@ public List<VerbInfoDTO> findMatchingVerb(MessageContext synCtx) throws Resource | |
String apiType = (String) synCtx.getProperty(APIMgtGatewayConstants.API_TYPE); | ||
|
||
if (APIConstants.ApiTypes.PRODUCT_API.name().equalsIgnoreCase(apiType)) { | ||
apiInfoDTO = doGetAPIProductInfo(apiContext, apiVersion); | ||
apiInfoDTO = doGetAPIProductInfo(synCtx, apiContext, apiVersion); | ||
} else { | ||
apiInfoDTO = doGetAPIInfo(apiContext, apiVersion); | ||
apiInfoDTO = doGetAPIInfo(synCtx, apiContext, apiVersion); | ||
} | ||
|
||
if (Util.tracingEnabled()) { | ||
|
@@ -539,15 +545,15 @@ private boolean isResourcePathMatching(String resourceString, ResourceInfoDTO re | |
} | ||
|
||
@MethodStats | ||
private APIInfoDTO doGetAPIInfo(String context, String apiVersion) throws APISecurityException { | ||
ArrayList<URITemplate> uriTemplates = getAllURITemplates(context, apiVersion); | ||
private APIInfoDTO doGetAPIInfo(MessageContext messageContext, String context, String apiVersion) throws APISecurityException { | ||
ArrayList<URITemplate> uriTemplates = getAllURITemplates(messageContext, context, apiVersion); | ||
|
||
return mapToAPIInfo(uriTemplates, context, apiVersion); | ||
} | ||
|
||
@MethodStats | ||
private APIInfoDTO doGetAPIProductInfo(String context, String apiVersion) throws APISecurityException { | ||
ArrayList<URITemplate> uriTemplates = getAPIProductURITemplates(context, apiVersion); | ||
private APIInfoDTO doGetAPIProductInfo(MessageContext messageContext, String context, String apiVersion) throws APISecurityException { | ||
ArrayList<URITemplate> uriTemplates = getAPIProductURITemplates(messageContext, context, apiVersion); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here, seems we are exceeding 120 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in #9250 |
||
|
||
return mapToAPIInfo(uriTemplates, context, apiVersion); | ||
} | ||
|
@@ -589,13 +595,14 @@ private APIInfoDTO mapToAPIInfo(ArrayList<URITemplate> uriTemplates, String cont | |
} | ||
|
||
/** | ||
* @param messageContext The message context | ||
* @param context API context of API | ||
* @param apiVersion Version of API | ||
* @param requestPath Incoming request path | ||
* @param httpMethod http method of request | ||
* @return verbInfoDTO which contains throttling tier for given resource and verb+resource key | ||
*/ | ||
public VerbInfoDTO getVerbInfoDTOFromAPIData(String context, String apiVersion, String requestPath, String httpMethod) | ||
public VerbInfoDTO getVerbInfoDTOFromAPIData(MessageContext messageContext, String context, String apiVersion, String requestPath, String httpMethod) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exceeding the max length There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in #9250 |
||
throws APISecurityException { | ||
|
||
String cacheKey = context + ':' + apiVersion; | ||
|
@@ -604,7 +611,7 @@ public VerbInfoDTO getVerbInfoDTOFromAPIData(String context, String apiVersion, | |
apiInfoDTO = (APIInfoDTO) getResourceCache().get(cacheKey); | ||
} | ||
if (apiInfoDTO == null) { | ||
apiInfoDTO = doGetAPIInfo(context, apiVersion); | ||
apiInfoDTO = doGetAPIInfo(messageContext, context, apiVersion); | ||
if (isGatewayAPIResourceValidationEnabled) { | ||
getResourceCache().put(cacheKey, apiInfoDTO); | ||
} | ||
|
@@ -701,15 +708,53 @@ public VerbInfoDTO getVerbInfoDTOFromAPIData(String context, String apiVersion, | |
|
||
|
||
@MethodStats | ||
protected ArrayList<URITemplate> getAllURITemplates(String context, String apiVersion) | ||
protected ArrayList<URITemplate> getAllURITemplates(MessageContext messageContext, String context, String apiVersion) | ||
throws APISecurityException { | ||
return dataStore.getAllURITemplates(context, apiVersion); | ||
if (uriTemplates == null) { | ||
synchronized (this) { | ||
if (uriTemplates == null) { | ||
ChamodDamitha marked this conversation as resolved.
Show resolved
Hide resolved
|
||
String swagger = (String) messageContext.getProperty(APIMgtGatewayConstants.OPEN_API_STRING); | ||
if (swagger != null) { | ||
APIDefinition oasParser; | ||
try { | ||
oasParser = OASParserUtil.getOASParser(swagger); | ||
uriTemplates = new ArrayList<>(); | ||
uriTemplates.addAll(oasParser.getURITemplates(swagger)); | ||
return uriTemplates; | ||
} catch (APIManagementException e) { | ||
log.error("Error while parsing swagger content to get URI Templates", e); | ||
} | ||
} | ||
uriTemplates = dataStore.getAllURITemplates(context, apiVersion); | ||
} | ||
} | ||
} | ||
return uriTemplates; | ||
} | ||
|
||
@MethodStats | ||
protected ArrayList<URITemplate> getAPIProductURITemplates(String context, String apiVersion) | ||
protected ArrayList<URITemplate> getAPIProductURITemplates(MessageContext messageContext, String context, String apiVersion) | ||
throws APISecurityException { | ||
return dataStore.getAPIProductURITemplates(context, apiVersion); | ||
if (uriTemplates == null) { | ||
synchronized (this) { | ||
if (uriTemplates == null) { | ||
String swagger = (String) messageContext.getProperty(APIMgtGatewayConstants.OPEN_API_STRING); | ||
if (swagger != null) { | ||
APIDefinition oasParser; | ||
try { | ||
oasParser = OASParserUtil.getOASParser(swagger); | ||
uriTemplates = new ArrayList<>(); | ||
uriTemplates.addAll(oasParser.getURITemplates(swagger)); | ||
return uriTemplates; | ||
} catch (APIManagementException e) { | ||
log.error("Error while parsing swagger content to get URI Templates", e); | ||
} | ||
} | ||
uriTemplates = dataStore.getAPIProductURITemplates(context, apiVersion); | ||
} | ||
} | ||
} | ||
return uriTemplates; | ||
} | ||
|
||
protected void setGatewayAPIResourceValidationEnabled(boolean gatewayAPIResourceValidationEnabled) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,35 +71,71 @@ public static String getResourceAuthenticationScheme(OpenAPI openAPI, MessageCon | |
public static String getScopesOfResource(OpenAPI openAPI, MessageContext synCtx) { | ||
Map<String, Object> vendorExtensions = getPathItemExtensions(synCtx, openAPI); | ||
if (vendorExtensions != null) { | ||
return (String) vendorExtensions.get(APIConstants.SWAGGER_X_SCOPE); | ||
String resourceScope = (String) vendorExtensions.get(APIConstants.SWAGGER_X_SCOPE); | ||
if (resourceScope == null) { | ||
// If x-scope not found in swagger, check for the scopes in security | ||
ArrayList<String> securityScopes = getPathItemSecurityScopes(synCtx, openAPI); | ||
if (securityScopes == null || securityScopes.isEmpty()) { | ||
return null; | ||
} else { | ||
return securityScopes.get(0); | ||
} | ||
} else { | ||
return resourceScope; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
/** | ||
* Return the scope-role mapping of an API | ||
* Return the roles of a given scope attached to a resource using the API swagger. | ||
* | ||
* @param openAPI OpenAPI of the API | ||
* @param synCtx The message containing resource request | ||
* @return the scope-role mapping | ||
* @param resourceScope The scope of the resource | ||
* @return the roles of the scope in the comma separated format | ||
*/ | ||
public static ArrayList<LinkedHashMap> getScopeToRoleMappingOfApi(OpenAPI openAPI, MessageContext synCtx) { | ||
Map<String, Object> vendorExtensions = getPathItemExtensions(synCtx, openAPI); | ||
public static String getRolesOfScope(OpenAPI openAPI, MessageContext synCtx, String resourceScope) { | ||
String resourceRoles = null; | ||
|
||
Map<String, Object> vendorExtensions = getPathItemExtensions(synCtx, openAPI); | ||
if (vendorExtensions != null) { | ||
String resourceScope = getScopesOfResource(openAPI, synCtx); | ||
if (StringUtils.isNotBlank(resourceScope)) { | ||
LinkedHashMap swaggerWSO2Security = (LinkedHashMap) openAPI.getExtensions() | ||
.get(APIConstants.SWAGGER_X_WSO2_SECURITY); | ||
if (swaggerWSO2Security != null) { | ||
LinkedHashMap swaggerObjectAPIM = (LinkedHashMap) swaggerWSO2Security | ||
.get(APIConstants.SWAGGER_OBJECT_NAME_APIM); | ||
if (swaggerObjectAPIM != null) { | ||
return (ArrayList<LinkedHashMap>) swaggerObjectAPIM.get(APIConstants.SWAGGER_X_WSO2_SCOPES); | ||
if (openAPI.getExtensions() != null && | ||
openAPI.getExtensions().get(APIConstants.SWAGGER_X_WSO2_SECURITY) != null) { | ||
LinkedHashMap swaggerWSO2Security = (LinkedHashMap) openAPI.getExtensions() | ||
.get(APIConstants.SWAGGER_X_WSO2_SECURITY); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you need to do a Null check for openAPI.getExtensions().get(APIConstants.SWAGGER_X_WSO2_SECURITY) as well because there could be a NPE when casting to LinkedHashMap when there is no when get(APIConstants.SWAGGER_X_WSO2_SECURITY) becomes null. We could add the null check to the if condition There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
if (swaggerWSO2Security != null && | ||
swaggerWSO2Security.get(APIConstants.SWAGGER_OBJECT_NAME_APIM) != null) { | ||
LinkedHashMap swaggerObjectAPIM = (LinkedHashMap) swaggerWSO2Security | ||
.get(APIConstants.SWAGGER_OBJECT_NAME_APIM); | ||
if (swaggerObjectAPIM != null && swaggerObjectAPIM.get(APIConstants.SWAGGER_X_WSO2_SCOPES) != null) { | ||
ArrayList<LinkedHashMap> apiScopes = | ||
(ArrayList<LinkedHashMap>) swaggerObjectAPIM.get(APIConstants.SWAGGER_X_WSO2_SCOPES); | ||
for (LinkedHashMap scope: apiScopes) { | ||
if (resourceScope.equals(scope.get(APIConstants.SWAGGER_SCOPE_KEY))) { | ||
resourceRoles = (String) scope.get(APIConstants.SWAGGER_ROLES); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
if (resourceRoles == null) { | ||
Map<String, Object> extensions = openAPI.getComponents().getSecuritySchemes() | ||
.get(APIConstants.SWAGGER_APIM_DEFAULT_SECURITY).getExtensions(); | ||
if (extensions != null && extensions.get(APIConstants.SWAGGER_X_SCOPES_BINDINGS) != null) { | ||
LinkedHashMap<String, Object> scopeBindings = | ||
(LinkedHashMap<String, Object>) extensions.get(APIConstants.SWAGGER_X_SCOPES_BINDINGS); | ||
if (scopeBindings != null) { | ||
return (String) scopeBindings.get(resourceScope); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
} | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
|
||
|
@@ -151,4 +187,41 @@ private static Map<String, Object> getPathItemExtensions(MessageContext synCtx, | |
} | ||
return null; | ||
} | ||
|
||
private static ArrayList<String> getPathItemSecurityScopes(MessageContext synCtx, OpenAPI openAPI) { | ||
if (openAPI != null) { | ||
String apiElectedResource = (String) synCtx.getProperty(APIConstants.API_ELECTED_RESOURCE); | ||
org.apache.axis2.context.MessageContext axis2MessageContext = | ||
((Axis2MessageContext) synCtx).getAxis2MessageContext(); | ||
String httpMethod = (String) axis2MessageContext.getProperty(APIConstants.DigestAuthConstants.HTTP_METHOD); | ||
PathItem path = openAPI.getPaths().get(apiElectedResource); | ||
|
||
if (path != null) { | ||
switch (httpMethod) { | ||
case APIConstants.HTTP_GET: | ||
return (ArrayList<String>) path.getGet().getSecurity().get(0) | ||
.get(APIConstants.SWAGGER_APIM_DEFAULT_SECURITY); | ||
case APIConstants.HTTP_POST: | ||
return (ArrayList<String>) path.getPost().getSecurity().get(0) | ||
.get(APIConstants.SWAGGER_APIM_DEFAULT_SECURITY); | ||
case APIConstants.HTTP_PUT: | ||
return (ArrayList<String>) path.getPut().getSecurity().get(0) | ||
.get(APIConstants.SWAGGER_APIM_DEFAULT_SECURITY); | ||
case APIConstants.HTTP_DELETE: | ||
return (ArrayList<String>) path.getDelete().getSecurity().get(0) | ||
.get(APIConstants.SWAGGER_APIM_DEFAULT_SECURITY); | ||
case APIConstants.HTTP_HEAD: | ||
return (ArrayList<String>) path.getHead().getSecurity().get(0) | ||
.get(APIConstants.SWAGGER_APIM_DEFAULT_SECURITY); | ||
case APIConstants.HTTP_OPTIONS: | ||
return (ArrayList<String>) path.getOptions().getSecurity().get(0) | ||
.get(APIConstants.SWAGGER_APIM_DEFAULT_SECURITY); | ||
case APIConstants.HTTP_PATCH: | ||
return (ArrayList<String>) path.getPatch().getSecurity().get(0) | ||
.get(APIConstants.SWAGGER_APIM_DEFAULT_SECURITY); | ||
} | ||
} | ||
} | ||
return null; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
arent we exceeding the max column length? 120
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in #9250