Search in sources :

Example 1 with GraphQLOperationDTO

use of org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO in project carbon-apimgt by wso2.

the class WebsocketHandlerTestCase method testGraphQLWriteResponse.

@Test
public void testGraphQLWriteResponse() throws Exception {
    InboundMessageContext inboundMessageContext = new InboundMessageContext();
    inboundMessageContext.setElectedAPI(graphQLAPI);
    InboundMessageContextDataHolder.getInstance().addInboundMessageContextForConnection(channelIdString, inboundMessageContext);
    msg = new TextWebSocketFrame("{\"id\":\"1\",\"type\":\"start\",\"payload\":{\"variables\":{}," + "\"extensions\":{},\"operationName\":null," + "\"query\":\"subscription {\\n  liftStatusChange {\\n    id\\n    name\\n    }\\n}\\n\"}}");
    VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
    verbInfoDTO.setHttpVerb(GraphQLConstants.SubscriptionConstants.HTTP_METHOD_NAME);
    verbInfoDTO.setAuthType("OAUTH");
    GraphQLOperationDTO graphQLOperationDTO = new GraphQLOperationDTO(verbInfoDTO, "liftStatusChange");
    inboundMessageContext.addVerbInfoForGraphQLMsgId("1", graphQLOperationDTO);
    InboundProcessorResponseDTO responseDTO = new InboundProcessorResponseDTO();
    PowerMockito.when(InboundWebsocketProcessorUtil.validateScopes(Mockito.anyObject(), Mockito.anyObject(), Mockito.anyObject())).thenReturn(responseDTO);
    PowerMockito.when(InboundWebsocketProcessorUtil.doThrottleForGraphQL(Mockito.anyInt(), Mockito.anyObject(), Mockito.anyObject(), Mockito.anyObject())).thenReturn(responseDTO);
    PowerMockito.when(InboundWebsocketProcessorUtil.authenticateToken(inboundMessageContext)).thenReturn(responseDTO);
    // happy path
    websocketHandler.write(channelHandlerContext, msg, channelPromise);
    Assert.assertTrue((InboundMessageContextDataHolder.getInstance().getInboundMessageContextMap().containsKey(// No error has occurred context exists in data-holder map.
    channelIdString)));
    // close connection error
    responseDTO.setError(true);
    responseDTO.setCloseConnection(true);
    websocketHandler.write(channelHandlerContext, msg, channelPromise);
    Assert.assertFalse(InboundMessageContextDataHolder.getInstance().getInboundMessageContextMap().containsKey(// Closing connection error has occurred
    channelIdString));
    // Websocket frame error has occurred
    InboundMessageContextDataHolder.getInstance().addInboundMessageContextForConnection(channelIdString, inboundMessageContext);
    responseDTO.setError(true);
    responseDTO.setCloseConnection(false);
    websocketHandler.write(channelHandlerContext, msg, channelPromise);
    Assert.assertTrue((InboundMessageContextDataHolder.getInstance().getInboundMessageContextMap().containsKey(channelIdString)));
}
Also used : GraphQLOperationDTO(org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO) VerbInfoDTO(org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO) InboundProcessorResponseDTO(org.wso2.carbon.apimgt.gateway.inbound.websocket.InboundProcessorResponseDTO) TextWebSocketFrame(io.netty.handler.codec.http.websocketx.TextWebSocketFrame) InboundMessageContext(org.wso2.carbon.apimgt.gateway.inbound.InboundMessageContext) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 2 with GraphQLOperationDTO

use of org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO in project carbon-apimgt by wso2.

the class GraphQLResponseProcessorTest method testHandleThrottleOut.

@Test
public void testHandleThrottleOut() {
    InboundMessageContext inboundMessageContext = new InboundMessageContext();
    int msgSize = 100;
    String msgText = "{\"type\":\"data\",\"id\":\"1\",\"payload\":{\"data\":" + "{\"liftStatusChange\":{\"name\":\"Astra Express\"}}}}";
    PowerMockito.mockStatic(InboundWebsocketProcessorUtil.class);
    InboundProcessorResponseDTO responseDTO = new InboundProcessorResponseDTO();
    PowerMockito.when(InboundWebsocketProcessorUtil.authenticateToken(inboundMessageContext)).thenReturn(responseDTO);
    VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
    verbInfoDTO.setHttpVerb("SUBSCRIPTION");
    verbInfoDTO.setThrottling("Unlimited");
    GraphQLOperationDTO graphQLOperationDTO = new GraphQLOperationDTO(verbInfoDTO, "liftStatusChange");
    inboundMessageContext.addVerbInfoForGraphQLMsgId("1", graphQLOperationDTO);
    PowerMockito.when(InboundWebsocketProcessorUtil.validateScopes(inboundMessageContext, "liftStatusChange", "1")).thenReturn(responseDTO);
    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);
    GraphQLResponseProcessor responseProcessor = new GraphQLResponseProcessor();
    InboundProcessorResponseDTO processorResponseDTO = responseProcessor.handleResponse(msgSize, msgText, inboundMessageContext);
    Assert.assertTrue(processorResponseDTO.isError());
    Assert.assertNotNull(processorResponseDTO.getErrorMessage());
    Assert.assertFalse(processorResponseDTO.isCloseConnection());
    Assert.assertEquals(processorResponseDTO.getErrorResponseString(), throttleResponseDTO.getErrorResponseString());
    Assert.assertEquals(processorResponseDTO.getErrorMessage(), throttleResponseDTO.getErrorMessage());
    Assert.assertEquals(processorResponseDTO.getErrorCode(), throttleResponseDTO.getErrorCode());
}
Also used : GraphQLOperationDTO(org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO) GraphQLProcessorResponseDTO(org.wso2.carbon.apimgt.gateway.inbound.websocket.GraphQLProcessorResponseDTO) VerbInfoDTO(org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO) InboundProcessorResponseDTO(org.wso2.carbon.apimgt.gateway.inbound.websocket.InboundProcessorResponseDTO) InboundMessageContext(org.wso2.carbon.apimgt.gateway.inbound.InboundMessageContext) Test(org.junit.Test) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Example 3 with GraphQLOperationDTO

use of org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO in project carbon-apimgt by wso2.

the class GraphQLResponseProcessorTest method testHandleInvalidScope.

@Test
public void testHandleInvalidScope() {
    InboundMessageContext inboundMessageContext = new InboundMessageContext();
    int msgSize = 100;
    String msgText = "{\"type\":\"data\",\"id\":\"1\",\"payload\":{\"data\":" + "{\"liftStatusChange\":{\"name\":\"Astra Express\"}}}}";
    PowerMockito.mockStatic(InboundWebsocketProcessorUtil.class);
    InboundProcessorResponseDTO responseDTO = new InboundProcessorResponseDTO();
    PowerMockito.when(InboundWebsocketProcessorUtil.authenticateToken(inboundMessageContext)).thenReturn(responseDTO);
    VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
    verbInfoDTO.setHttpVerb("SUBSCRIPTION");
    verbInfoDTO.setThrottling("Unlimited");
    verbInfoDTO.setAuthType("Any");
    GraphQLOperationDTO graphQLOperationDTO = new GraphQLOperationDTO(verbInfoDTO, "liftStatusChange");
    inboundMessageContext.addVerbInfoForGraphQLMsgId("1", graphQLOperationDTO);
    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);
    PowerMockito.when(InboundWebsocketProcessorUtil.doThrottleForGraphQL(msgSize, verbInfoDTO, inboundMessageContext, "1")).thenReturn(responseDTO);
    GraphQLResponseProcessor responseProcessor = new GraphQLResponseProcessor();
    InboundProcessorResponseDTO processorResponseDTO = responseProcessor.handleResponse(msgSize, msgText, inboundMessageContext);
    Assert.assertTrue(processorResponseDTO.isError());
    Assert.assertNotNull(processorResponseDTO.getErrorMessage());
    Assert.assertFalse(processorResponseDTO.isCloseConnection());
    Assert.assertEquals(processorResponseDTO.getErrorResponseString(), graphQLProcessorResponseDTO.getErrorResponseString());
    Assert.assertEquals(processorResponseDTO.getErrorMessage(), graphQLProcessorResponseDTO.getErrorMessage());
    Assert.assertEquals(processorResponseDTO.getErrorCode(), graphQLProcessorResponseDTO.getErrorCode());
}
Also used : GraphQLOperationDTO(org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO) GraphQLProcessorResponseDTO(org.wso2.carbon.apimgt.gateway.inbound.websocket.GraphQLProcessorResponseDTO) VerbInfoDTO(org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO) InboundProcessorResponseDTO(org.wso2.carbon.apimgt.gateway.inbound.websocket.InboundProcessorResponseDTO) InboundMessageContext(org.wso2.carbon.apimgt.gateway.inbound.InboundMessageContext) Test(org.junit.Test) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Example 4 with GraphQLOperationDTO

use of org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO in project carbon-apimgt by wso2.

the class GraphQLRequestProcessor method handleRequest.

/**
 * Handle inbound websocket requests for GraphQL subscriptions and perform authentication, authorization,
 * payload validation, query depth and complexity analysis and throttling.
 *
 * @param msgSize               Message size of graphQL subscription payload
 * @param msgText               The GraphQL subscription payload text
 * @param inboundMessageContext InboundMessageContext
 * @return InboundProcessorResponseDTO
 */
@Override
public InboundProcessorResponseDTO handleRequest(int msgSize, String msgText, InboundMessageContext inboundMessageContext) {
    InboundProcessorResponseDTO responseDTO;
    JSONObject graphQLMsg = new JSONObject(msgText);
    responseDTO = InboundWebsocketProcessorUtil.authenticateToken(inboundMessageContext);
    Parser parser = new Parser();
    // for gql subscription operation payloads
    if (!responseDTO.isError() && checkIfSubscribeMessage(graphQLMsg)) {
        String operationId = graphQLMsg.getString(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_ID);
        if (validatePayloadFields(graphQLMsg)) {
            String graphQLSubscriptionPayload = ((JSONObject) graphQLMsg.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_PAYLOAD)).getString(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_QUERY);
            Document document = parser.parseDocument(graphQLSubscriptionPayload);
            // Extract the operation type and operations from the payload
            OperationDefinition operation = getOperationFromPayload(document);
            if (operation != null) {
                if (checkIfValidSubscribeOperation(operation)) {
                    responseDTO = validateQueryPayload(inboundMessageContext, document, operationId);
                    if (!responseDTO.isError()) {
                        // subscription operation name
                        String subscriptionOperation = GraphQLProcessorUtil.getOperationList(operation, inboundMessageContext.getGraphQLSchemaDTO().getTypeDefinitionRegistry());
                        // extract verb info dto with throttle policy for matching verb
                        VerbInfoDTO verbInfoDTO = InboundWebsocketProcessorUtil.findMatchingVerb(subscriptionOperation, inboundMessageContext);
                        String authType = verbInfoDTO.getAuthType();
                        // validate scopes based on subscription payload when security is enabled
                        if (!StringUtils.capitalize(APIConstants.AUTH_TYPE_NONE.toLowerCase()).equals(authType)) {
                            responseDTO = InboundWebsocketProcessorUtil.validateScopes(inboundMessageContext, subscriptionOperation, operationId);
                        }
                        if (!responseDTO.isError()) {
                            SubscriptionAnalyzer subscriptionAnalyzer = new SubscriptionAnalyzer(inboundMessageContext.getGraphQLSchemaDTO().getGraphQLSchema());
                            // analyze query depth and complexity
                            responseDTO = validateQueryDepthAndComplexity(subscriptionAnalyzer, inboundMessageContext, graphQLSubscriptionPayload, operationId);
                            if (!responseDTO.isError()) {
                                // throttle for matching resource
                                responseDTO = InboundWebsocketProcessorUtil.doThrottleForGraphQL(msgSize, verbInfoDTO, inboundMessageContext, operationId);
                                // add verb info dto for the successful invoking subscription operation request
                                inboundMessageContext.addVerbInfoForGraphQLMsgId(graphQLMsg.getString(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_ID), new GraphQLOperationDTO(verbInfoDTO, subscriptionOperation));
                            }
                        }
                    }
                } else {
                    responseDTO = InboundWebsocketProcessorUtil.getBadRequestGraphQLFrameErrorDTO("Invalid operation. Only allowed Subscription type operations", operationId);
                }
            } else {
                responseDTO = InboundWebsocketProcessorUtil.getBadRequestGraphQLFrameErrorDTO("Operation definition cannot be empty", operationId);
            }
        } else {
            responseDTO = InboundWebsocketProcessorUtil.getBadRequestGraphQLFrameErrorDTO("Invalid operation payload", operationId);
        }
    }
    return responseDTO;
}
Also used : GraphQLOperationDTO(org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO) JSONObject(org.json.JSONObject) VerbInfoDTO(org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO) InboundProcessorResponseDTO(org.wso2.carbon.apimgt.gateway.inbound.websocket.InboundProcessorResponseDTO) Document(graphql.language.Document) OperationDefinition(graphql.language.OperationDefinition) SubscriptionAnalyzer(org.wso2.carbon.apimgt.gateway.handlers.graphQL.analyzer.SubscriptionAnalyzer) Parser(graphql.parser.Parser)

Example 5 with GraphQLOperationDTO

use of org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO in project carbon-apimgt by wso2.

the class GraphQLResponseProcessorTest method testHandleResponseScopeValidationSkipWhenSecurityDisabled.

@Test
public void testHandleResponseScopeValidationSkipWhenSecurityDisabled() {
    InboundMessageContext inboundMessageContext = new InboundMessageContext();
    int msgSize = 100;
    String msgText = "{\"type\":\"data\",\"id\":\"1\",\"payload\":{\"data\":" + "{\"liftStatusChange\":{\"name\":\"Astra Express\"}}}}";
    PowerMockito.mockStatic(InboundWebsocketProcessorUtil.class);
    InboundProcessorResponseDTO responseDTO = new InboundProcessorResponseDTO();
    PowerMockito.when(InboundWebsocketProcessorUtil.authenticateToken(inboundMessageContext)).thenReturn(responseDTO);
    // VerbInfoDTO with security disabled
    VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
    verbInfoDTO.setHttpVerb("SUBSCRIPTION");
    verbInfoDTO.setThrottling("Unlimited");
    verbInfoDTO.setAuthType("None");
    GraphQLOperationDTO graphQLOperationDTO = new GraphQLOperationDTO(verbInfoDTO, "liftStatusChange");
    inboundMessageContext.addVerbInfoForGraphQLMsgId("1", graphQLOperationDTO);
    // Creating response for scope validation
    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);
    PowerMockito.when(InboundWebsocketProcessorUtil.doThrottleForGraphQL(msgSize, verbInfoDTO, inboundMessageContext, "1")).thenReturn(responseDTO);
    GraphQLResponseProcessor responseProcessor = new GraphQLResponseProcessor();
    InboundProcessorResponseDTO processorResponseDTO = responseProcessor.handleResponse(msgSize, msgText, inboundMessageContext);
    Assert.assertFalse(processorResponseDTO.isError());
    Assert.assertNull(processorResponseDTO.getErrorMessage());
    Assert.assertNotEquals(processorResponseDTO.getErrorMessage(), "User is NOT authorized to access the Resource");
}
Also used : GraphQLOperationDTO(org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO) GraphQLProcessorResponseDTO(org.wso2.carbon.apimgt.gateway.inbound.websocket.GraphQLProcessorResponseDTO) VerbInfoDTO(org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO) InboundProcessorResponseDTO(org.wso2.carbon.apimgt.gateway.inbound.websocket.InboundProcessorResponseDTO) InboundMessageContext(org.wso2.carbon.apimgt.gateway.inbound.InboundMessageContext) Test(org.junit.Test) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Aggregations

GraphQLOperationDTO (org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO)7 InboundProcessorResponseDTO (org.wso2.carbon.apimgt.gateway.inbound.websocket.InboundProcessorResponseDTO)7 VerbInfoDTO (org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO)6 Test (org.junit.Test)5 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)5 InboundMessageContext (org.wso2.carbon.apimgt.gateway.inbound.InboundMessageContext)5 GraphQLProcessorResponseDTO (org.wso2.carbon.apimgt.gateway.inbound.websocket.GraphQLProcessorResponseDTO)3 JSONObject (org.json.JSONObject)2 Document (graphql.language.Document)1 OperationDefinition (graphql.language.OperationDefinition)1 Parser (graphql.parser.Parser)1 TextWebSocketFrame (io.netty.handler.codec.http.websocketx.TextWebSocketFrame)1 SubscriptionAnalyzer (org.wso2.carbon.apimgt.gateway.handlers.graphQL.analyzer.SubscriptionAnalyzer)1