use of org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO in project carbon-apimgt by wso2.
the class APIKeyValidator method getVerbInfoDTOFromAPIData.
/**
* @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(MessageContext messageContext, String context, String apiVersion, String requestPath, String httpMethod) throws APISecurityException {
String cacheKey = context + ':' + apiVersion;
APIInfoDTO apiInfoDTO = null;
if (isGatewayAPIResourceValidationEnabled) {
apiInfoDTO = (APIInfoDTO) getResourceCache().get(cacheKey);
}
if (apiInfoDTO == null) {
apiInfoDTO = doGetAPIInfo(messageContext, context, apiVersion);
if (isGatewayAPIResourceValidationEnabled) {
getResourceCache().put(cacheKey, apiInfoDTO);
}
}
// Match the case where the direct api context is matched
if ("/".equals(requestPath)) {
String requestCacheKey = context + '/' + apiVersion + requestPath + ':' + httpMethod;
// Get decision from cache.
VerbInfoDTO matchingVerb = null;
if (isGatewayAPIResourceValidationEnabled) {
matchingVerb = (VerbInfoDTO) getResourceCache().get(requestCacheKey);
}
// On a cache hit
if (matchingVerb != null) {
matchingVerb.setRequestKey(requestCacheKey);
return matchingVerb;
} else {
if (apiInfoDTO.getResources() != null) {
for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) {
String urlPattern = resourceInfoDTO.getUrlPattern();
// If the request patch is '/', it can only be matched with a resource whose url-context is '/*'
if ("/*".equals(urlPattern)) {
for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) {
if (verbDTO.getHttpVerb().equals(httpMethod)) {
// Store verb in cache
if (isGatewayAPIResourceValidationEnabled) {
getResourceCache().put(requestCacheKey, verbDTO);
}
verbDTO.setRequestKey(requestCacheKey);
return verbDTO;
}
}
}
}
}
}
}
// Remove the ending '/' from request
requestPath = RESTUtils.trimTrailingSlashes(requestPath);
while (requestPath.length() > 1) {
String requestCacheKey = context + '/' + apiVersion + requestPath + ':' + httpMethod;
// Get decision from cache.
VerbInfoDTO matchingVerb = null;
if (isGatewayAPIResourceValidationEnabled) {
matchingVerb = (VerbInfoDTO) getResourceCache().get(requestCacheKey);
}
// On a cache hit
if (matchingVerb != null) {
matchingVerb.setRequestKey(requestCacheKey);
return matchingVerb;
} else // On a cache miss
{
for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) {
String urlPattern = resourceInfoDTO.getUrlPattern();
if (urlPattern.endsWith("/*")) {
// Remove the ending '/*'
urlPattern = urlPattern.substring(0, urlPattern.length() - 2);
}
// If the urlPattern ends with a '/', remove that as well.
urlPattern = RESTUtils.trimTrailingSlashes(urlPattern);
if (requestPath.endsWith(urlPattern)) {
for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) {
if (verbDTO.getHttpVerb().equals(httpMethod)) {
// Store verb in cache
if (isGatewayAPIResourceValidationEnabled) {
getResourceCache().put(requestCacheKey, verbDTO);
}
verbDTO.setRequestKey(requestCacheKey);
return verbDTO;
}
}
}
}
}
// Remove the section after the last occurrence of the '/' character
int index = requestPath.lastIndexOf('/');
requestPath = requestPath.substring(0, index <= 0 ? 0 : index);
}
// nothing found. return the highest level of security
return null;
}
use of org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO in project carbon-apimgt by wso2.
the class MutualSSLAuthenticator method setAuthContext.
/**
* To set the authentication context in current message context.
*
* @param messageContext Relevant message context.
* @param x509Certificate SSL certificate.
* @throws APISecurityException API Security Exception.
*/
private void setAuthContext(MessageContext messageContext, X509Certificate x509Certificate) throws APISecurityException {
String subjectDN = x509Certificate.getSubjectDN().getName();
String uniqueIdentifier = (x509Certificate.getSerialNumber() + "_" + x509Certificate.getIssuerDN()).replaceAll(",", "#").replaceAll("\"", "'").trim();
String tier = certificates.get(uniqueIdentifier);
if (StringUtils.isEmpty(tier)) {
if (log.isDebugEnabled()) {
log.debug("The client certificate presented is available in gateway, however it was not added against " + "the API " + getAPIIdentifier(messageContext));
}
if (isMandatory) {
log.error("Mutual SSL authentication failure. API is not associated with the certificate");
}
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, APISecurityConstants.API_AUTH_INVALID_CREDENTIALS_MESSAGE);
}
AuthenticationContext authContext = new AuthenticationContext();
authContext.setAuthenticated(true);
authContext.setUsername(subjectDN);
try {
LdapName ldapDN = new LdapName(subjectDN);
for (Rdn rdn : ldapDN.getRdns()) {
if (APIConstants.CERTIFICATE_COMMON_NAME.equalsIgnoreCase(rdn.getType())) {
authContext.setUsername((String) rdn.getValue());
}
}
} catch (InvalidNameException e) {
log.warn("Cannot get the CN name from certificate:" + e.getMessage() + ". Please make sure the " + "certificate to include a proper common name that follows naming convention.");
authContext.setUsername(subjectDN);
}
authContext.setApiTier(apiLevelPolicy);
APIIdentifier apiIdentifier = getAPIIdentifier(messageContext);
authContext.setKeyType(APIConstants.API_KEY_TYPE_PRODUCTION);
authContext.setStopOnQuotaReach(true);
authContext.setApiKey(uniqueIdentifier + "_" + apiIdentifier.toString());
authContext.setTier(tier);
/* For the mutual SSL based authenticated request, the resource level throttling is not considered, hence
assigning the unlimited tier for that. */
List<VerbInfoDTO> verbInfoList = new ArrayList<>(1);
VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
verbInfoDTO.setThrottling(APIConstants.UNLIMITED_TIER);
verbInfoList.add(verbInfoDTO);
messageContext.setProperty(APIConstants.VERB_INFO_DTO, verbInfoList);
if (log.isDebugEnabled()) {
log.debug("Auth context for the API " + getAPIIdentifier(messageContext) + ": Username[" + authContext.getUsername() + "APIKey[(" + authContext.getApiKey() + "] Tier[" + authContext.getTier() + "]");
}
APISecurityUtils.setAuthenticationContext(messageContext, authContext, null);
}
use of org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO in project carbon-apimgt by wso2.
the class GraphQLRequestProcessorTest method testHandleRequestThrottle.
@Test
public void testHandleRequestThrottle() throws Exception {
InboundMessageContext inboundMessageContext = new InboundMessageContext();
int msgSize = 100;
String msgText = "{\"id\":\"1\",\"type\":\"start\",\"payload\":{\"variables\":{},\"extensions\":{}," + "\"operationName\":null,\"query\":\"subscription {\\n " + "liftStatusChange {\\n id\\n name\\n }\\n}\\n\"}}";
PowerMockito.mockStatic(InboundWebsocketProcessorUtil.class);
InboundProcessorResponseDTO responseDTO = new InboundProcessorResponseDTO();
PowerMockito.when(InboundWebsocketProcessorUtil.authenticateToken(inboundMessageContext)).thenReturn(responseDTO);
// Get schema and parse
String graphqlDirPath = "graphQL" + File.separator;
String relativePath = graphqlDirPath + "schema_with_additional_props.graphql";
String schemaString = IOUtils.toString(getClass().getClassLoader().getResourceAsStream(relativePath));
SchemaParser schemaParser = new SchemaParser();
TypeDefinitionRegistry registry = schemaParser.parse(schemaString);
GraphQLSchema schema = UnExecutableSchemaGenerator.makeUnExecutableSchema(registry);
GraphQLSchemaDTO schemaDTO = new GraphQLSchemaDTO(schema, registry);
inboundMessageContext.setGraphQLSchemaDTO(schemaDTO);
PowerMockito.when(InboundWebsocketProcessorUtil.validateScopes(inboundMessageContext, "liftStatusChange", "1")).thenReturn(responseDTO);
VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
verbInfoDTO.setHttpVerb("SUBSCRIPTION");
verbInfoDTO.setThrottling("Unlimited");
PowerMockito.when(InboundWebsocketProcessorUtil.findMatchingVerb("liftStatusChange", inboundMessageContext)).thenReturn(verbInfoDTO);
APIKeyValidationInfoDTO infoDTO = new APIKeyValidationInfoDTO();
infoDTO.setGraphQLMaxComplexity(4);
infoDTO.setGraphQLMaxDepth(3);
inboundMessageContext.setInfoDTO(infoDTO);
GraphQLProcessorResponseDTO throttleResponseDTO = new GraphQLProcessorResponseDTO();
throttleResponseDTO.setError(true);
throttleResponseDTO.setErrorCode(WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR);
throttleResponseDTO.setErrorMessage(WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR_MESSAGE);
throttleResponseDTO.setId("1");
PowerMockito.when(InboundWebsocketProcessorUtil.doThrottleForGraphQL(msgSize, verbInfoDTO, inboundMessageContext, "1")).thenReturn(throttleResponseDTO);
GraphQLRequestProcessor graphQLRequestProcessor = new GraphQLRequestProcessor();
InboundProcessorResponseDTO processorResponseDTO = graphQLRequestProcessor.handleRequest(msgSize, msgText, inboundMessageContext);
Assert.assertTrue(processorResponseDTO.isError());
Assert.assertTrue(processorResponseDTO.getErrorMessage().contains(WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR_MESSAGE));
Assert.assertEquals(processorResponseDTO.getErrorCode(), WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR);
Assert.assertNotNull(processorResponseDTO.getErrorResponseString());
JSONParser jsonParser = new JSONParser();
JSONObject errorJson = (JSONObject) jsonParser.parse(processorResponseDTO.getErrorResponseString());
Assert.assertEquals(errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_TYPE), GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_TYPE_ERROR);
Assert.assertEquals(errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_ID), "1");
JSONObject payload = (JSONObject) errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_PAYLOAD);
Assert.assertTrue(((String) payload.get(WebSocketApiConstants.FrameErrorConstants.ERROR_MESSAGE)).contains(WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR_MESSAGE));
Assert.assertEquals(String.valueOf(payload.get(WebSocketApiConstants.FrameErrorConstants.ERROR_CODE)), String.valueOf(WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR));
Assert.assertFalse(processorResponseDTO.isCloseConnection());
}
use of org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO in project carbon-apimgt by wso2.
the class GraphQLRequestProcessorTest method testHandleRequestTooDeep.
@Test
public void testHandleRequestTooDeep() throws Exception {
InboundMessageContext inboundMessageContext = new InboundMessageContext();
int msgSize = 100;
String msgText = "{\"id\":\"1\",\"type\":\"start\",\"payload\":{\"variables\":{},\"extensions\":{}," + "\"operationName\":null,\"query\":\"subscription {\\n " + "liftStatusChange {\\n id\\n name\\n }\\n}\\n\"}}";
PowerMockito.mockStatic(InboundWebsocketProcessorUtil.class);
InboundProcessorResponseDTO responseDTO = new InboundProcessorResponseDTO();
PowerMockito.when(InboundWebsocketProcessorUtil.authenticateToken(inboundMessageContext)).thenReturn(responseDTO);
// Get schema and parse
String graphqlDirPath = "graphQL" + File.separator;
String relativePath = graphqlDirPath + "schema_with_additional_props.graphql";
String schemaString = IOUtils.toString(getClass().getClassLoader().getResourceAsStream(relativePath));
SchemaParser schemaParser = new SchemaParser();
TypeDefinitionRegistry registry = schemaParser.parse(schemaString);
GraphQLSchema schema = UnExecutableSchemaGenerator.makeUnExecutableSchema(registry);
GraphQLSchemaDTO schemaDTO = new GraphQLSchemaDTO(schema, registry);
inboundMessageContext.setGraphQLSchemaDTO(schemaDTO);
PowerMockito.when(InboundWebsocketProcessorUtil.validateScopes(inboundMessageContext, "liftStatusChange", "1")).thenReturn(responseDTO);
VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
verbInfoDTO.setHttpVerb("SUBSCRIPTION");
verbInfoDTO.setThrottling("Unlimited");
PowerMockito.when(InboundWebsocketProcessorUtil.findMatchingVerb("liftStatusChange", inboundMessageContext)).thenReturn(verbInfoDTO);
APIKeyValidationInfoDTO infoDTO = new APIKeyValidationInfoDTO();
infoDTO.setGraphQLMaxComplexity(4);
infoDTO.setGraphQLMaxDepth(1);
inboundMessageContext.setInfoDTO(infoDTO);
GraphQLRequestProcessor graphQLRequestProcessor = new GraphQLRequestProcessor();
InboundProcessorResponseDTO processorResponseDTO = graphQLRequestProcessor.handleRequest(msgSize, msgText, inboundMessageContext);
Assert.assertTrue(processorResponseDTO.isError());
Assert.assertTrue(processorResponseDTO.getErrorMessage().contains(WebSocketApiConstants.FrameErrorConstants.GRAPHQL_QUERY_TOO_DEEP_MESSAGE));
Assert.assertEquals(processorResponseDTO.getErrorCode(), WebSocketApiConstants.FrameErrorConstants.GRAPHQL_QUERY_TOO_DEEP);
Assert.assertNotNull(processorResponseDTO.getErrorResponseString());
JSONParser jsonParser = new JSONParser();
JSONObject errorJson = (JSONObject) jsonParser.parse(processorResponseDTO.getErrorResponseString());
Assert.assertEquals(errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_TYPE), GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_TYPE_ERROR);
Assert.assertEquals(errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_ID), "1");
JSONObject payload = (JSONObject) errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_PAYLOAD);
Assert.assertTrue(((String) payload.get(WebSocketApiConstants.FrameErrorConstants.ERROR_MESSAGE)).contains(WebSocketApiConstants.FrameErrorConstants.GRAPHQL_QUERY_TOO_DEEP_MESSAGE));
Assert.assertEquals(String.valueOf(payload.get(WebSocketApiConstants.FrameErrorConstants.ERROR_CODE)), String.valueOf(WebSocketApiConstants.FrameErrorConstants.GRAPHQL_QUERY_TOO_DEEP));
Assert.assertFalse(processorResponseDTO.isCloseConnection());
}
use of org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO in project carbon-apimgt by wso2.
the class GraphQLRequestProcessorTest method testHandleRequestInvalidScope.
@Test
public void testHandleRequestInvalidScope() throws Exception {
InboundMessageContext inboundMessageContext = new InboundMessageContext();
int msgSize = 100;
String msgText = "{\"id\":\"1\",\"type\":\"start\",\"payload\":{\"variables\":{},\"extensions\":{}," + "\"operationName\":null,\"query\":\"subscription {\\n " + "liftStatusChange {\\n id\\n name\\n }\\n}\\n\"}}";
PowerMockito.mockStatic(InboundWebsocketProcessorUtil.class);
InboundProcessorResponseDTO responseDTO = new InboundProcessorResponseDTO();
PowerMockito.when(InboundWebsocketProcessorUtil.authenticateToken(inboundMessageContext)).thenReturn(responseDTO);
// Get schema and parse
String graphqlDirPath = "graphQL" + File.separator;
String relativePath = graphqlDirPath + "schema_with_additional_props.graphql";
String schemaString = IOUtils.toString(getClass().getClassLoader().getResourceAsStream(relativePath));
SchemaParser schemaParser = new SchemaParser();
TypeDefinitionRegistry registry = schemaParser.parse(schemaString);
GraphQLSchema schema = UnExecutableSchemaGenerator.makeUnExecutableSchema(registry);
GraphQLSchemaDTO schemaDTO = new GraphQLSchemaDTO(schema, registry);
inboundMessageContext.setGraphQLSchemaDTO(schemaDTO);
VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
verbInfoDTO.setHttpVerb("SUBSCRIPTION");
verbInfoDTO.setThrottling("Unlimited");
verbInfoDTO.setAuthType("Any");
PowerMockito.when(InboundWebsocketProcessorUtil.findMatchingVerb("liftStatusChange", inboundMessageContext)).thenReturn(verbInfoDTO);
GraphQLProcessorResponseDTO graphQLProcessorResponseDTO = new GraphQLProcessorResponseDTO();
graphQLProcessorResponseDTO.setError(true);
graphQLProcessorResponseDTO.setErrorCode(WebSocketApiConstants.FrameErrorConstants.RESOURCE_FORBIDDEN_ERROR);
graphQLProcessorResponseDTO.setErrorMessage("User is NOT authorized to access the Resource");
graphQLProcessorResponseDTO.setCloseConnection(false);
graphQLProcessorResponseDTO.setId("1");
PowerMockito.when(InboundWebsocketProcessorUtil.validateScopes(inboundMessageContext, "liftStatusChange", "1")).thenReturn(graphQLProcessorResponseDTO);
GraphQLRequestProcessor graphQLRequestProcessor = new GraphQLRequestProcessor();
InboundProcessorResponseDTO processorResponseDTO = graphQLRequestProcessor.handleRequest(msgSize, msgText, inboundMessageContext);
Assert.assertTrue(processorResponseDTO.isError());
Assert.assertEquals(processorResponseDTO.getErrorMessage(), "User is NOT authorized to access the Resource");
Assert.assertEquals(processorResponseDTO.getErrorCode(), WebSocketApiConstants.FrameErrorConstants.RESOURCE_FORBIDDEN_ERROR);
Assert.assertNotNull(processorResponseDTO.getErrorResponseString());
JSONParser jsonParser = new JSONParser();
JSONObject errorJson = (JSONObject) jsonParser.parse(processorResponseDTO.getErrorResponseString());
Assert.assertEquals(errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_TYPE), GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_TYPE_ERROR);
Assert.assertEquals(errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_ID), "1");
JSONObject payload = (JSONObject) errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_PAYLOAD);
Assert.assertEquals(payload.get(WebSocketApiConstants.FrameErrorConstants.ERROR_MESSAGE), "User is NOT authorized to access the Resource");
Assert.assertEquals(String.valueOf(payload.get(WebSocketApiConstants.FrameErrorConstants.ERROR_CODE)), String.valueOf(WebSocketApiConstants.FrameErrorConstants.RESOURCE_FORBIDDEN_ERROR));
Assert.assertFalse(processorResponseDTO.isCloseConnection());
}
Aggregations