From f6bc7a8b4db5ab7899087af70efdfa8aa9476867 Mon Sep 17 00:00:00 2001 From: Alar Floren Date: Mon, 15 Apr 2024 10:06:45 +0300 Subject: [PATCH] 271 Add Ruuter REST calls with predefined (dynamic) request structure --- DSL/POST/dynamic-body.yml | 11 +++++++ samples/steps/http-post.md | 17 +++++++++++ .../ruuter/domain/steps/http/HttpGetStep.java | 2 +- .../domain/steps/http/HttpPostStep.java | 3 +- .../domain/steps/http/HttpQueryArgs.java | 2 ++ .../helper/ExternalForwardingHelper.java | 4 +-- .../buerokratt/ruuter/helper/HttpHelper.java | 30 +++++++++++-------- 7 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 DSL/POST/dynamic-body.yml diff --git a/DSL/POST/dynamic-body.yml b/DSL/POST/dynamic-body.yml new file mode 100644 index 00000000..8546a6ec --- /dev/null +++ b/DSL/POST/dynamic-body.yml @@ -0,0 +1,11 @@ +dynamicTest: + call: http.post + args: + url: http://host.docker.internal:9001/test_endpoint + dynamicParameters: true + body: + dynamicBody: ${incoming.body.input} + result: value + +returnStep: + return: ${value} diff --git a/samples/steps/http-post.md b/samples/steps/http-post.md index fa5861dd..67c67aae 100644 --- a/samples/steps/http-post.md +++ b/samples/steps/http-post.md @@ -103,6 +103,22 @@ return_value: return: ${the_message.response} ``` +### POST step with "dynamic body" +It is possible to send a pre-defined json body with POST by storing it in +`body.dynamicBody` value and setting `args.dynamicParameters` value to true: + +```yaml +dynamicTest: + call: http.post + args: + url: http://host.docker.internal:9001/test_endpoint + dynamicParameters: true + body: + dynamicBody: ${incoming.body.input} +``` + +This is considered unsafe and should be used only in special cases. + ### HTTP Error handling It is possible to specify the DSL step to follow when POST request gets a @@ -126,4 +142,5 @@ error_step: status: 500 ``` + [Back to Guide](../GUIDE.md#Writing-DSL-files) diff --git a/src/main/java/ee/buerokratt/ruuter/domain/steps/http/HttpGetStep.java b/src/main/java/ee/buerokratt/ruuter/domain/steps/http/HttpGetStep.java index a96c4b92..6755dd4f 100644 --- a/src/main/java/ee/buerokratt/ruuter/domain/steps/http/HttpGetStep.java +++ b/src/main/java/ee/buerokratt/ruuter/domain/steps/http/HttpGetStep.java @@ -22,7 +22,7 @@ public ResponseEntity getRequestResponse(DslInstance di) { Map evaluatedQuery = di.getScriptingHelper().evaluateScripts(args.getQuery(), di.getContext(), di.getRequestBody(), di.getRequestQuery(), di.getRequestHeaders()); Map evaluatedHeaders = di.getScriptingHelper().evaluateScripts(args.getHeaders(), di.getContext(), di.getRequestBody(), di.getRequestQuery(), di.getRequestHeaders()); Map mappedHeaders = di.getMappingHelper().convertMapObjectValuesToString(evaluatedHeaders); - return di.getHttpHelper().doMethod(HttpMethod.GET, evaluatedURL, evaluatedQuery, null, mappedHeaders, null, null, getLimit(), di); + return di.getHttpHelper().doMethod(HttpMethod.GET, evaluatedURL, evaluatedQuery, null, mappedHeaders, null, null, getLimit(), di, args.isDynamicParameters()); } @Override diff --git a/src/main/java/ee/buerokratt/ruuter/domain/steps/http/HttpPostStep.java b/src/main/java/ee/buerokratt/ruuter/domain/steps/http/HttpPostStep.java index d02863e0..7e4a49ae 100644 --- a/src/main/java/ee/buerokratt/ruuter/domain/steps/http/HttpPostStep.java +++ b/src/main/java/ee/buerokratt/ruuter/domain/steps/http/HttpPostStep.java @@ -31,7 +31,8 @@ protected ResponseEntity getRequestResponse(DslInstance di) { evaluatedQuery, evaluatedBody, mappedHeaders, args.getContentType(), "plaintext".equals(args.getContentType()) ? args.getPlaintext() : null, - getLimit(), di); + getLimit(), di, + args.isDynamicParameters()); } @Override diff --git a/src/main/java/ee/buerokratt/ruuter/domain/steps/http/HttpQueryArgs.java b/src/main/java/ee/buerokratt/ruuter/domain/steps/http/HttpQueryArgs.java index e391873f..7e210491 100644 --- a/src/main/java/ee/buerokratt/ruuter/domain/steps/http/HttpQueryArgs.java +++ b/src/main/java/ee/buerokratt/ruuter/domain/steps/http/HttpQueryArgs.java @@ -19,6 +19,8 @@ public class HttpQueryArgs { private String contentType; private String originalUrl = ""; + protected boolean dynamicParameters; + public void addHeaders(Map newHeaders) { newHeaders.forEach(headers::putIfAbsent); } diff --git a/src/main/java/ee/buerokratt/ruuter/helper/ExternalForwardingHelper.java b/src/main/java/ee/buerokratt/ruuter/helper/ExternalForwardingHelper.java index 0b6f804a..bcce507d 100644 --- a/src/main/java/ee/buerokratt/ruuter/helper/ExternalForwardingHelper.java +++ b/src/main/java/ee/buerokratt/ruuter/helper/ExternalForwardingHelper.java @@ -58,10 +58,10 @@ public ResponseEntity forwardRequest(String dsl, Map req .toUriString(); if (methodType.equals(HttpMethod.POST.name())) { - return httpHelper.doMethod(HttpMethod.POST,forwardingUrl, query, body, headers, contentType, null, null, di); + return httpHelper.doMethod(HttpMethod.POST,forwardingUrl, query, body, headers, contentType, null, null, di, false); } if (methodType.equals(HttpMethod.GET.name())) { - return httpHelper.doMethod(HttpMethod.GET, forwardingUrl, query,null, headers, null, null, null, di); + return httpHelper.doMethod(HttpMethod.GET, forwardingUrl, query,null, headers, null, null, null, di, false); } throw new InvalidHttpMethodTypeException(methodType); } diff --git a/src/main/java/ee/buerokratt/ruuter/helper/HttpHelper.java b/src/main/java/ee/buerokratt/ruuter/helper/HttpHelper.java index 733c7f62..19db4d1e 100644 --- a/src/main/java/ee/buerokratt/ruuter/helper/HttpHelper.java +++ b/src/main/java/ee/buerokratt/ruuter/helper/HttpHelper.java @@ -2,6 +2,7 @@ import ee.buerokratt.ruuter.configuration.ApplicationProperties; import ee.buerokratt.ruuter.domain.DslInstance; +import ee.buerokratt.ruuter.util.LoggingUtils; import io.netty.channel.ChannelOption; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; @@ -40,27 +41,27 @@ public class HttpHelper { final private ScriptingHelper scriptingHelper; - public ResponseEntity doPost(String url, Map body, Map query, Map headers, DslInstance di) { - return doPost(url, body, query, headers, this.getClass().getName(), di); + public ResponseEntity doPost(String url, Map body, Map query, Map headers, DslInstance di, boolean dynamicBody) { + return doPost(url, body, query, headers, this.getClass().getName(), di, dynamicBody); } - public ResponseEntity doPost(String url, Map body, Map query, Map headers, String contentType, DslInstance di) { - return doMethod(POST, url, query, body,headers, contentType, null, null, di); + public ResponseEntity doPost(String url, Map body, Map query, Map headers, String contentType, DslInstance di, boolean dynamicBody) { + return doMethod(POST, url, query, body,headers, contentType, null, null, di, dynamicBody); } public ResponseEntity doPostPlaintext(String url, Map body, Map query, Map headers, String plaintext, DslInstance di) { - return doMethod(POST, url, body, query, headers, "plaintext", plaintext, null, di); + return doMethod(POST, url, body, query, headers, "plaintext", plaintext, null, di, false); } public ResponseEntity doGet(String url, Map query, Map headers, DslInstance di) { - return doMethod(HttpMethod.GET, url, query, null, headers, null, null, null, di); + return doMethod(HttpMethod.GET, url, query, null, headers, null, null, null, di, false); } - public ResponseEntity doPut(String url, Map body, Map query, Map headers, String contentType, DslInstance di) { - return doMethod(HttpMethod.PUT, url, query, body,headers, contentType, null, null, di); + public ResponseEntity doPut(String url, Map body, Map query, Map headers, String contentType, DslInstance di, boolean dynamicBody) { + return doMethod(HttpMethod.PUT, url, query, body,headers, contentType, null, null, di, dynamicBody); } public ResponseEntity doDelete(String url, Map body, Map query, Map headers, String contentType, DslInstance di) { - return doMethod(HttpMethod.DELETE, url, query, body, headers, contentType, null, null, di); + return doMethod(HttpMethod.DELETE, url, query, body, headers, contentType, null, null, di, false); } public ResponseEntity doMethod(HttpMethod method, @@ -71,14 +72,14 @@ public ResponseEntity doMethod(HttpMethod method, String contentType, String plaintextValue, Integer limit, - DslInstance instance) { + DslInstance instance, + boolean dynamicBody) { try { MultiValueMap qp = new LinkedMultiValueMap<>( query.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e-> Arrays.asList(e.getValue().toString())))); BodyInserter bodyValue; String mediaType; - if (method == POST && "plaintext".equals(contentType) && plaintextValue != null) { bodyValue = BodyInserters.fromValue(plaintextValue);; @@ -112,7 +113,12 @@ public ResponseEntity doMethod(HttpMethod method, bodyValue = BodyInserters.empty(); mediaType = MediaType.APPLICATION_JSON_VALUE; } else { - bodyValue = BodyInserters.fromValue(body); + if (dynamicBody) { + log.warn("Sending dynamic body request is considered unsecure"); + bodyValue = BodyInserters.fromValue(body.get("dynamicBody")); + } else { + bodyValue = BodyInserters.fromValue(body); + } mediaType = MediaType.APPLICATION_JSON_VALUE; }