From 08694886fa9335e06516d1874d85d0345f075ca0 Mon Sep 17 00:00:00 2001 From: ayushaga14 Date: Tue, 16 Apr 2024 16:17:33 +0530 Subject: [PATCH 1/3] support variables in override url input --- .../akto/test_editor/execution/Executor.java | 92 +++++++++++-------- .../java/com/akto/testing/TestExecutor.java | 8 +- .../java/com/akto/testing/ApiExecutor.java | 43 +++++++++ 3 files changed, 102 insertions(+), 41 deletions(-) diff --git a/apps/testing/src/main/java/com/akto/test_editor/execution/Executor.java b/apps/testing/src/main/java/com/akto/test_editor/execution/Executor.java index f468d763a4..c54066b386 100644 --- a/apps/testing/src/main/java/com/akto/test_editor/execution/Executor.java +++ b/apps/testing/src/main/java/com/akto/test_editor/execution/Executor.java @@ -4,6 +4,8 @@ import com.akto.dao.billing.OrganizationsDao; import com.akto.dao.billing.TokensDao; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.akto.dao.CustomAuthTypeDao; import com.akto.dao.context.Context; @@ -44,12 +46,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.net.URI; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; import org.json.JSONObject; @@ -76,7 +72,7 @@ public class Executor { public YamlTestResult execute(ExecutorNode node, RawApi rawApi, Map varMap, String logId, AuthMechanism authMechanism, FilterNode validatorNode, ApiInfo.ApiInfoKey apiInfoKey, TestingRunConfig testingRunConfig, List customAuthTypes, boolean debug, List testLogs) { List result = new ArrayList<>(); - + ExecutionListBuilder executionListBuilder = new ExecutionListBuilder(); List executorNodes = new ArrayList<>(); ExecutionOrderResp executionOrderResp = executionListBuilder.parseExecuteOperations(node, executorNodes); @@ -171,35 +167,6 @@ public YamlTestResult execute(ExecutorNode node, RawApi rawApi, Map originalHostHeaders = rawApi.getRequest().getHeaders().getOrDefault(_HOST, new ArrayList<>()); - List attemptHostHeaders = testReq.getRequest().getHeaders().getOrDefault(_HOST, new ArrayList<>()); - - if (!originalHostHeaders.isEmpty() - && originalHostHeaders.get(0) != null - && !attemptHostHeaders.isEmpty() - && attemptHostHeaders.get(0) != null - && originalHostHeaders.get(0).equals(attemptHostHeaders.get(0)) - && testingRunConfig != null - && !StringUtils.isEmpty(testingRunConfig.getOverriddenTestAppUrl())) { - - String url = ApiExecutor.prepareUrl(testReq.getRequest(), testingRunConfig); - URI uri = new URI(url); - String host = uri.getHost(); - if (uri.getPort() != -1) { - host += ":" + uri.getPort(); - } - testReq.getRequest().getHeaders().put(_HOST, Collections.singletonList(host)); - } - - } catch (Exception e) { - testLogs.add(new TestingRunResult.TestLog(TestingRunResult.TestLogType.ERROR, "unable to update host header for overridden test URL")); - loggerMaker.errorAndAddToDb(e,"unable to update host header for overridden test URL", - LogDb.TESTING); - } - // follow redirects = true for now testResponse = ApiExecutor.sendRequest(testReq.getRequest(), followRedirect, testingRunConfig, debug, testLogs); requestSent = true; @@ -230,6 +197,59 @@ public YamlTestResult execute(ExecutorNode node, RawApi rawApi, Map originalHostHeaders = rawApi.getRequest().getHeaders().getOrDefault(_HOST, new ArrayList<>()); + if (!originalHostHeaders.isEmpty() && testingRunConfig != null + && !StringUtils.isEmpty(testingRunConfig.getOverriddenTestAppUrl())) { + + Pattern pattern = Pattern.compile("\\$\\{[^}]*\\}"); + Matcher matcher = pattern.matcher(testingRunConfig.getOverriddenTestAppUrl()); + if (matcher.find()) { + String match = matcher.group(0); + match = match.substring(2, match.length()); + match = match.substring(0, match.length() - 1); + String[] params = match.split("\\+"); + for (int i = 0; i < params.length; i++) { + url += resolveParam(params[i], rawApi); + } + testingRunConfig.setOverriddenTestAppUrl(url); + } else { + url = testingRunConfig.getOverriddenTestAppUrl(); + } + + String newUrl = ApiExecutor.replacePathFromConfig(rawApi.getRequest().getUrl(), testingRunConfig); + URI uri = new URI(newUrl); + String host = uri.getHost(); + if (uri.getPort() != -1) { + host += ":" + uri.getPort(); + } + rawApi.getRequest().getHeaders().put(_HOST, Collections.singletonList(host)); + rawApi.getRequest().setUrl(newUrl); + + } + + } catch (Exception e) { + //testLogs.add(new TestingRunResult.TestLog(TestingRunResult.TestLogType.ERROR, "unable to update host header for overridden test URL")); + loggerMaker.errorAndAddToDb(e,"unable to update host header for overridden test URL", + LogDb.TESTING); + } + } + + public String resolveParam(String param, RawApi rawApi) { + param = param.trim(); + String[] params = param.split("\\."); + + if (params.length == 1) { + return params[0]; + } + + String key = params[params.length - 1]; + String val = rawApi.getRequest().getHeaders().get(key).get(0); + return val; + } + private void overrideAuth(RawApi rawApi, AuthMechanism authMechanism) { List authParams = authMechanism.getAuthParams(); if (authParams == null || authParams.isEmpty()) { diff --git a/apps/testing/src/main/java/com/akto/testing/TestExecutor.java b/apps/testing/src/main/java/com/akto/testing/TestExecutor.java index a4222c151e..aa124d4192 100644 --- a/apps/testing/src/main/java/com/akto/testing/TestExecutor.java +++ b/apps/testing/src/main/java/com/akto/testing/TestExecutor.java @@ -34,6 +34,7 @@ import com.akto.store.AuthMechanismStore; import com.akto.store.SampleMessageStore; import com.akto.store.TestingUtil; +import com.akto.test_editor.execution.Executor; import com.akto.test_editor.execution.VariableResolver; import com.akto.testing.yaml_tests.YamlTestTemplate; import com.akto.testing_issues.TestingIssuesHandler; @@ -46,11 +47,6 @@ import com.mongodb.MongoInterruptedException; import org.apache.commons.lang3.StringUtils; import com.mongodb.BasicDBObject; -import com.mongodb.client.model.Aggregates; -import com.mongodb.client.model.Filters; -import com.mongodb.client.model.Projections; -import com.mongodb.client.model.Sorts; -import com.mongodb.client.model.Updates; import com.mongodb.client.model.*; import org.bson.conversions.Bson; @@ -678,6 +674,8 @@ public TestingRunResult runTestNew(ApiInfo.ApiInfoKey apiInfoKey, ObjectId testR List customAuthTypes = testingUtil.getCustomAuthTypes(); // TestingUtil -> authMechanism // TestingConfig -> auth + com.akto.test_editor.execution.Executor executor = new Executor(); + executor.overrideTestUrl(rawApi, testingRunConfig); YamlTestTemplate yamlTestTemplate = new YamlTestTemplate(apiInfoKey,filterNode, validatorNode, executorNode, rawApi, varMap, auth, testingUtil.getAuthMechanism(), testExecutionLogId, testingRunConfig, customAuthTypes, testConfig.getStrategy()); YamlTestResult testResults = yamlTestTemplate.run(debug, testLogs); diff --git a/libs/utils/src/main/java/com/akto/testing/ApiExecutor.java b/libs/utils/src/main/java/com/akto/testing/ApiExecutor.java index 65900b0083..6c8b1c9639 100644 --- a/libs/utils/src/main/java/com/akto/testing/ApiExecutor.java +++ b/libs/utils/src/main/java/com/akto/testing/ApiExecutor.java @@ -144,6 +144,49 @@ public static String replaceHostFromConfig(String url, TestingRunConfig testingR return url; } + public static String replacePathFromConfig(String url, TestingRunConfig testingRunConfig) { + if (testingRunConfig != null && !StringUtils.isEmpty(testingRunConfig.getOverriddenTestAppUrl())) { + URI typedUrl = null; + try { + typedUrl = new URI(url); + + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + + String newUrl = testingRunConfig.getOverriddenTestAppUrl(); + + URI newUri = null; + try { + newUri = new URI(newUrl); + + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + + String newPath = newUri.getPath(); + + if (newPath.equals("") || newPath.equals("/")) { + newPath = typedUrl.getPath(); + } + + String newHost = newUri.getHost(); + if (newUri.getHost().equals("")) { + newHost = typedUrl.getHost(); + } + + try { + String newScheme = newUri.getScheme() == null ? typedUrl.getScheme() : newUri.getScheme(); + int newPort = newUri.getPort() == -1 ? typedUrl.getPort() : newUri.getPort(); + + url = new URI(newScheme, null, newHost, newPort, newPath, typedUrl.getQuery(), typedUrl.getFragment()).toString(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + return url; + } + public static String prepareUrl(OriginalHttpRequest request, TestingRunConfig testingRunConfig) throws Exception{ String url = request.getUrl(); url = url.trim(); From dd1d118c164f3fb154b4a6fa89ee774028a66ef8 Mon Sep 17 00:00:00 2001 From: ayushaga14 Date: Tue, 16 Apr 2024 16:18:20 +0530 Subject: [PATCH 2/3] allow variable string in run test input --- apps/dashboard/src/main/java/com/akto/utils/Utils.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/dashboard/src/main/java/com/akto/utils/Utils.java b/apps/dashboard/src/main/java/com/akto/utils/Utils.java index 5731a4dc20..91370c4ca4 100644 --- a/apps/dashboard/src/main/java/com/akto/utils/Utils.java +++ b/apps/dashboard/src/main/java/com/akto/utils/Utils.java @@ -158,6 +158,11 @@ public static boolean isValidURL(String url) { new URL(url).toURI(); return true; } catch (MalformedURLException | URISyntaxException e) { + Pattern pattern = Pattern.compile("\\$\\{[^}]*\\}"); + Matcher matcher = pattern.matcher(url); + if (matcher.find()) { + return true; + } return false; } } From a2895d387612928234718dadc3f615d1d34dd4d4 Mon Sep 17 00:00:00 2001 From: ayushaga14 Date: Wed, 17 Apr 2024 10:06:02 +0530 Subject: [PATCH 3/3] add logs --- .../src/main/java/com/akto/test_editor/execution/Executor.java | 1 + libs/utils/src/main/java/com/akto/testing/ApiExecutor.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/apps/testing/src/main/java/com/akto/test_editor/execution/Executor.java b/apps/testing/src/main/java/com/akto/test_editor/execution/Executor.java index c54066b386..672463b188 100644 --- a/apps/testing/src/main/java/com/akto/test_editor/execution/Executor.java +++ b/apps/testing/src/main/java/com/akto/test_editor/execution/Executor.java @@ -200,6 +200,7 @@ public YamlTestResult execute(ExecutorNode node, RawApi rawApi, Map originalHostHeaders = rawApi.getRequest().getHeaders().getOrDefault(_HOST, new ArrayList<>()); if (!originalHostHeaders.isEmpty() && testingRunConfig != null && !StringUtils.isEmpty(testingRunConfig.getOverriddenTestAppUrl())) { diff --git a/libs/utils/src/main/java/com/akto/testing/ApiExecutor.java b/libs/utils/src/main/java/com/akto/testing/ApiExecutor.java index 6c8b1c9639..c4bf4e0d6c 100644 --- a/libs/utils/src/main/java/com/akto/testing/ApiExecutor.java +++ b/libs/utils/src/main/java/com/akto/testing/ApiExecutor.java @@ -151,6 +151,7 @@ public static String replacePathFromConfig(String url, TestingRunConfig testingR typedUrl = new URI(url); } catch (URISyntaxException e) { + loggerMaker.errorAndAddToDb(e, "error converting req url to uri " + url, LogDb.TESTING); throw new RuntimeException(e); } @@ -161,6 +162,7 @@ public static String replacePathFromConfig(String url, TestingRunConfig testingR newUri = new URI(newUrl); } catch (URISyntaxException e) { + loggerMaker.errorAndAddToDb(e, "error converting override url to uri " + url, LogDb.TESTING); throw new RuntimeException(e); } @@ -181,6 +183,7 @@ public static String replacePathFromConfig(String url, TestingRunConfig testingR url = new URI(newScheme, null, newHost, newPort, newPath, typedUrl.getQuery(), typedUrl.getFragment()).toString(); } catch (URISyntaxException e) { + loggerMaker.errorAndAddToDb(e, "error building new url using override url", LogDb.TESTING); throw new RuntimeException(e); } }