From 1a614aecaea4986f8f99adece4b3825c7e91bdc0 Mon Sep 17 00:00:00 2001 From: Ankush Jain <91221068+ankush-jain-akto@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:55:50 +0530 Subject: [PATCH 01/10] Fix release notes --- .github/workflows/beamerAndDiscord.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/beamerAndDiscord.yml b/.github/workflows/beamerAndDiscord.yml index eedd7f028e..f6b499dcde 100644 --- a/.github/workflows/beamerAndDiscord.yml +++ b/.github/workflows/beamerAndDiscord.yml @@ -40,17 +40,11 @@ jobs: line = line.split('by', 1)[0].strip() release_notes += f'
  • {line[1:]}
  • ' release_notes += '' - release_notes2 = '

    More...

    ' - release_notes2 += '' - release_notes2 += '

    ' + release_notes2 = '

    ' release_notes2 += '' release_notes2 += '' release_notes2 += '

    ' - release_notes2 += '' + release_notes2 += 'Have questions? Ask on Discord or our Community page' release_notes = release_notes+release_notes2 From c0b71053ccce6427aa1f8c702e2c0b8247ac23ee Mon Sep 17 00:00:00 2001 From: Ankush Jain <91221068+ankush-jain-akto@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:58:36 +0530 Subject: [PATCH 02/10] remove extra lines --- .github/workflows/beamerAndDiscord.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/beamerAndDiscord.yml b/.github/workflows/beamerAndDiscord.yml index f6b499dcde..713120603d 100644 --- a/.github/workflows/beamerAndDiscord.yml +++ b/.github/workflows/beamerAndDiscord.yml @@ -40,11 +40,7 @@ jobs: line = line.split('by', 1)[0].strip() release_notes += f'
  • {line[1:]}
  • ' release_notes += '' - release_notes2 = '

    ' - release_notes2 += '' - release_notes2 += '' - release_notes2 += '

    ' - release_notes2 += 'Have questions? Ask on Discord or our Community page' + release_notes2 += '

    Have questions? Ask on Discord or our Community page' release_notes = release_notes+release_notes2 From d18b624ad4b1bdc6211766e3069cf99e21cf0324 Mon Sep 17 00:00:00 2001 From: Ankush Jain Date: Tue, 9 Apr 2024 02:44:27 +0530 Subject: [PATCH 03/10] add test collection config dto --- .../testing/config/TestCollectionConfig.java | 12 ++++ .../config/TestCollectionProperty.java | 70 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 libs/dao/src/main/java/com/akto/dto/testing/config/TestCollectionConfig.java create mode 100644 libs/dao/src/main/java/com/akto/dto/testing/config/TestCollectionProperty.java diff --git a/libs/dao/src/main/java/com/akto/dto/testing/config/TestCollectionConfig.java b/libs/dao/src/main/java/com/akto/dto/testing/config/TestCollectionConfig.java new file mode 100644 index 0000000000..cde9ad3a2f --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/testing/config/TestCollectionConfig.java @@ -0,0 +1,12 @@ +package com.akto.dto.testing.config; + +import java.util.List; +import java.util.Map; + +public class TestCollectionConfig { + Map tokenKeyToCustomAuthHexId; + + + + +} diff --git a/libs/dao/src/main/java/com/akto/dto/testing/config/TestCollectionProperty.java b/libs/dao/src/main/java/com/akto/dto/testing/config/TestCollectionProperty.java new file mode 100644 index 0000000000..a682a79577 --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/testing/config/TestCollectionProperty.java @@ -0,0 +1,70 @@ +package com.akto.dto.testing.config; + +import com.akto.util.enums.GlobalEnums; + +import java.util.List; + +public class TestCollectionProperty { + + public enum Status { + PENDING, DONE + } + public enum Type { + CUSTOM_AUTH, TEST_YAML_KEYWORD, ROLE + } + String name; + String lastUpdatedUser; + int lastUpdatedEpoch; + List values; + List impactingCategories; + int apiCollectionId; + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLastUpdatedUser() { + return lastUpdatedUser; + } + + public void setLastUpdatedUser(String lastUpdatedUser) { + this.lastUpdatedUser = lastUpdatedUser; + } + + public int getLastUpdatedEpoch() { + return lastUpdatedEpoch; + } + + public void setLastUpdatedEpoch(int lastUpdatedEpoch) { + this.lastUpdatedEpoch = lastUpdatedEpoch; + } + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + + public List getImpactingCategories() { + return impactingCategories; + } + + public void setImpactingCategories(List impactingCategories) { + this.impactingCategories = impactingCategories; + } + + public int getApiCollectionId() { + return apiCollectionId; + } + + public void setApiCollectionId(int apiCollectionId) { + this.apiCollectionId = apiCollectionId; + } +} From d5595625e86e32e1c8b7ccf44aeffbeb4a65ba34 Mon Sep 17 00:00:00 2001 From: Ark2307 Date: Tue, 9 Apr 2024 10:12:25 +0530 Subject: [PATCH 04/10] removing old ui build from github actions --- .github/workflows/prod.yml | 3 --- .github/workflows/releaseOnlyUI.yml | 3 --- .github/workflows/staging.yml | 3 --- 3 files changed, 9 deletions(-) diff --git a/.github/workflows/prod.yml b/.github/workflows/prod.yml index 115cd94ed8..a2fc69bbb5 100644 --- a/.github/workflows/prod.yml +++ b/.github/workflows/prod.yml @@ -38,9 +38,6 @@ jobs: wget -O fintech.json https://raw.githubusercontent.com/akto-api-security/akto/master/pii-types/fintech.json wget -O filetypes.json https://raw.githubusercontent.com/akto-api-security/akto/master/pii-types/filetypes.json - - name: Prepare Dashboard UI - working-directory: ./apps/dashboard/ - run: npm install && export RELEASE_VERSION=${{github.event.inputs.release_version}} && npm run build - name: Prepare Dashboard polaris UI working-directory: ./apps/dashboard/web/polaris_web run: npm install && export RELEASE_VERSION=${{github.event.inputs.release_version}} && npm run build diff --git a/.github/workflows/releaseOnlyUI.yml b/.github/workflows/releaseOnlyUI.yml index f7cea697cd..b3ad004e90 100644 --- a/.github/workflows/releaseOnlyUI.yml +++ b/.github/workflows/releaseOnlyUI.yml @@ -30,9 +30,6 @@ jobs: - uses: actions/setup-node@v2 with: node-version: '17' - - name: Prepare Dashboard UI - working-directory: ./apps/dashboard/ - run: npm install && export RELEASE_VERSION=${{github.event.inputs.release_version}} && npm run build - name: Prepare Dashboard polaris UI working-directory: ./apps/dashboard/web/polaris_web run: npm install && export RELEASE_VERSION=${{github.event.inputs.release_version}} && npm run build diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index b1d99dc4a2..2d0601ccab 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -34,9 +34,6 @@ jobs: wget -O general.json https://raw.githubusercontent.com/akto-api-security/pii-types/master/general.json wget -O fintech.json https://raw.githubusercontent.com/akto-api-security/akto/master/pii-types/fintech.json wget -O filetypes.json https://raw.githubusercontent.com/akto-api-security/akto/master/pii-types/filetypes.json - - name: Prepare Dashboard UI - working-directory: ./apps/dashboard/ - run: npm install && export RELEASE_VERSION=${{steps.docker_tag.outputs.IMAGE_TAG}} && npm run build - name: Prepare Dashboard polaris UI working-directory: ./apps/dashboard/web/polaris_web run: npm install && export RELEASE_VERSION=${{steps.docker_tag.outputs.IMAGE_TAG}} && npm run build From d34da58abcfb623482a48a5d794da666b2330267 Mon Sep 17 00:00:00 2001 From: Ark2307 Date: Tue, 9 Apr 2024 10:21:21 +0530 Subject: [PATCH 05/10] removing push to cdn command --- .github/workflows/prod.yml | 2 -- .github/workflows/releaseOnlyUI.yml | 2 -- .github/workflows/staging.yml | 2 -- 3 files changed, 6 deletions(-) diff --git a/.github/workflows/prod.yml b/.github/workflows/prod.yml index a2fc69bbb5..f4f0a8a666 100644 --- a/.github/workflows/prod.yml +++ b/.github/workflows/prod.yml @@ -48,8 +48,6 @@ jobs: aws-secret-access-key: ${{secrets.AWS_SECRET_ACCESS_KEY}} aws-region: ap-south-1 - - name: Deploy static site to S3 bucket - run: aws s3 sync ./apps/dashboard/web/dist s3://dashboard-on-cdn/web/${{github.event.inputs.release_version}}/dist --delete - name: Deploy polaris site to S3 bucket run: aws s3 sync ./apps/dashboard/web/polaris_web/web/dist s3://dashboard-on-cdn/polaris_web/${{github.event.inputs.release_version}}/dist --delete - run: mvn package -Dakto-image-tag=${{ github.event.inputs.release_version }} -Dakto-build-time=$(eval "date +%s") -Dakto-release-version=${{github.event.inputs.release_version}} diff --git a/.github/workflows/releaseOnlyUI.yml b/.github/workflows/releaseOnlyUI.yml index b3ad004e90..afca350c62 100644 --- a/.github/workflows/releaseOnlyUI.yml +++ b/.github/workflows/releaseOnlyUI.yml @@ -40,7 +40,5 @@ jobs: aws-secret-access-key: ${{secrets.AWS_SECRET_ACCESS_KEY}} aws-region: ap-south-1 - - name: Deploy static site to S3 bucket - run: aws s3 sync ./apps/dashboard/web/dist s3://dashboard-on-cdn/web/${{github.event.inputs.release_version}}/dist --delete - name: Deploy polaris site to S3 bucket run: aws s3 sync ./apps/dashboard/web/polaris_web/web/dist s3://dashboard-on-cdn/polaris_web/${{github.event.inputs.release_version}}/dist --delete diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index 2d0601ccab..dddc0b0e31 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -44,8 +44,6 @@ jobs: aws-secret-access-key: ${{secrets.AWS_SECRET_ACCESS_KEY}} aws-region: ap-south-1 - - name: Deploy static site to S3 bucket - run: aws s3 sync ./apps/dashboard/web/dist s3://dashboard-on-cdn/web/${{steps.docker_tag.outputs.IMAGE_TAG}}/dist --delete - name: Deploy polaris site to S3 bucket run: aws s3 sync ./apps/dashboard/web/polaris_web/web/dist s3://dashboard-on-cdn/polaris_web/${{steps.docker_tag.outputs.IMAGE_TAG}}/dist --delete From 75468b8bca0fb6631c1a4a0d1dd0ab543dcfdba8 Mon Sep 17 00:00:00 2001 From: Ark2307 Date: Tue, 9 Apr 2024 11:14:36 +0530 Subject: [PATCH 06/10] adding missing dependency --- .../web/polaris_web/package-lock.json | 102 ++++++++++++++++++ apps/dashboard/web/polaris_web/package.json | 2 + 2 files changed, 104 insertions(+) diff --git a/apps/dashboard/web/polaris_web/package-lock.json b/apps/dashboard/web/polaris_web/package-lock.json index 96da8074ad..5ee8a2ce8b 100644 --- a/apps/dashboard/web/polaris_web/package-lock.json +++ b/apps/dashboard/web/polaris_web/package-lock.json @@ -21,7 +21,9 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "assert": "^2.1.0", "axios": "^1.4.0", + "buffer": "^6.0.3", "dayjs": "^1.11.5", "deep-diff": "^1.0.2", "file-saver": "^2.0.5", @@ -7144,6 +7146,18 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, "node_modules/ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -8417,6 +8431,25 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -8592,6 +8625,29 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -12630,6 +12686,25 @@ "node": ">=4" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -13062,6 +13137,21 @@ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -23090,6 +23180,18 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/apps/dashboard/web/polaris_web/package.json b/apps/dashboard/web/polaris_web/package.json index 20aaaa67a3..dfaf195765 100644 --- a/apps/dashboard/web/polaris_web/package.json +++ b/apps/dashboard/web/polaris_web/package.json @@ -16,7 +16,9 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "assert": "^2.1.0", "axios": "^1.4.0", + "buffer": "^6.0.3", "dayjs": "^1.11.5", "deep-diff": "^1.0.2", "file-saver": "^2.0.5", From 7fa6ae4ed784494329b4c82617a90676168f20dc Mon Sep 17 00:00:00 2001 From: Ankush Jain Date: Tue, 9 Apr 2024 11:28:11 +0530 Subject: [PATCH 07/10] show secured and skipped tabs for test results --- .../akto/action/testing/StartTestAction.java | 32 +++++++++-- .../SingleTestRunPage/SingleTestRunPage.js | 38 +++++++++---- .../src/apps/dashboard/pages/testing/api.js | 4 +- .../yaml_tests/SecurityTestTemplate.java | 6 ++- .../akto/dao/testing/TestingRunResultDao.java | 6 +++ .../java/com/akto/dto/testing/TestResult.java | 54 ++++++++++++------- 6 files changed, 102 insertions(+), 38 deletions(-) diff --git a/apps/dashboard/src/main/java/com/akto/action/testing/StartTestAction.java b/apps/dashboard/src/main/java/com/akto/action/testing/StartTestAction.java index bea48a387a..dc14b97bb8 100644 --- a/apps/dashboard/src/main/java/com/akto/action/testing/StartTestAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/testing/StartTestAction.java @@ -449,6 +449,10 @@ public String fetchTestingRunResultSummary() { String testingRunResultSummaryHexId; List testingRunResults; private boolean fetchOnlyVulnerable; + public enum QueryMode { + VULNERABLE, SECURED, SKIPPED_EXEC_NEED_CONFIG, SKIPPED_EXEC_NO_ACTION, SKIPPED_EXEC, ALL; + } + private QueryMode queryMode; public String fetchTestingRunResults() { ObjectId testingRunResultSummaryId; @@ -461,12 +465,28 @@ public String fetchTestingRunResults() { List testingRunResultFilters = new ArrayList<>(); - if (fetchOnlyVulnerable) { - testingRunResultFilters.add(Filters.eq(TestingRunResult.VULNERABLE, true)); - } - testingRunResultFilters.add(Filters.eq(TestingRunResult.TEST_RUN_RESULT_SUMMARY_ID, testingRunResultSummaryId)); + if (queryMode == null) { + if (fetchOnlyVulnerable) { + testingRunResultFilters.add(Filters.eq(TestingRunResult.VULNERABLE, true)); + } + } else { + switch (queryMode) { + case VULNERABLE: + testingRunResultFilters.add(Filters.eq(TestingRunResult.VULNERABLE, true)); + break; + case SKIPPED_EXEC: + testingRunResultFilters.add(Filters.eq(TestingRunResult.VULNERABLE, false)); + testingRunResultFilters.add(Filters.in(TestingRunResultDao.ERRORS_KEY, TestResult.TestError.getErrorsToSkipTests())); + break; + case SECURED: + testingRunResultFilters.add(Filters.eq(TestingRunResult.VULNERABLE, false)); + testingRunResultFilters.add(Filters.nin(TestingRunResultDao.ERRORS_KEY, TestResult.TestError.getErrorsToSkipTests())); + break; + } + } + this.testingRunResults = TestingRunResultDao.instance .fetchLatestTestingRunResult(Filters.and(testingRunResultFilters)); @@ -1013,6 +1033,10 @@ public void setFetchOnlyVulnerable(boolean fetchOnlyVulnerable) { this.fetchOnlyVulnerable = fetchOnlyVulnerable; } + public void setQueryMode(QueryMode queryMode) { + this.queryMode = queryMode; + } + public Map> getMetadataFilters() { return metadataFilters; } diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/SingleTestRunPage/SingleTestRunPage.js b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/SingleTestRunPage/SingleTestRunPage.js index de51172bdb..73bd61b92f 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/SingleTestRunPage/SingleTestRunPage.js +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/SingleTestRunPage/SingleTestRunPage.js @@ -124,13 +124,13 @@ let filters = [ function SingleTestRunPage() { - const [testRunResults, setTestRunResults] = useState({ vulnerable: [], all: [] }) + const [testRunResults, setTestRunResults] = useState({ vulnerable: [], secured: [], skipped: [] }) const [ selectedTestRun, setSelectedTestRun ] = useState({}); const subCategoryFromSourceConfigMap = PersistStore(state => state.subCategoryFromSourceConfigMap); const subCategoryMap = PersistStore(state => state.subCategoryMap); const params= useParams() const [loading, setLoading] = useState(false); - const [tempLoading , setTempLoading] = useState({vulnerable: false, all: false, running: false}) + const [tempLoading , setTempLoading] = useState({vulnerable: false, secured: false, skipped: false, running: false}) const [selectedTab, setSelectedTab] = useState("vulnerable") const [selected, setSelected] = useState(0) const [workflowTest, setWorkflowTest ] = useState(false); @@ -168,19 +168,27 @@ function SingleTestRunPage() { setLoading(false); setTempLoading((prev) => { prev.vulnerable = true; - prev.all = true; + prev.secured = true; + prev.skipped = true; return {...prev}; }); let testRunResults = []; - await api.fetchTestingRunResults(summaryHexId, true).then(({ testingRunResults }) => { + await api.fetchTestingRunResults(summaryHexId, "VULNERABLE").then(({ testingRunResults }) => { testRunResults = transform.prepareTestRunResults(hexId, testingRunResults, subCategoryMap, subCategoryFromSourceConfigMap) }) fillData(transform.getPrettifiedTestRunResults(testRunResults), 'vulnerable') - await api.fetchTestingRunResults(summaryHexId, false).then(({ testingRunResults }) => { + + await api.fetchTestingRunResults(summaryHexId, "SKIPPED_EXEC").then(({ testingRunResults }) => { testRunResults = transform.prepareTestRunResults(hexId, testingRunResults, subCategoryMap, subCategoryFromSourceConfigMap) }) - fillData(transform.getPrettifiedTestRunResults(testRunResults), 'all') + + fillData(transform.getPrettifiedTestRunResults(testRunResults), 'skipped') + + await api.fetchTestingRunResults(summaryHexId, "SECURED").then(({ testingRunResults }) => { + testRunResults = transform.prepareTestRunResults(hexId, testingRunResults, subCategoryMap, subCategoryFromSourceConfigMap) + }) + fillData(transform.getPrettifiedTestRunResults(testRunResults), 'secured') } async function fetchData(setData) { @@ -312,12 +320,19 @@ const promotedBulkActions = (selectedDataHexIds) => { id: 'vulnerable', }, { - content: 'All', + content: 'Skipped', index: 1, - badge: testRunResults["all"]?.length?.toString(), - onAction: ()=> {setSelectedTab('all')}, - id: 'all', + badge: testRunResults["skipped"]?.length?.toString(), + onAction: ()=> {setSelectedTab('skipped')}, + id: 'skipped', }, + { + content: 'Secured', + index: 2, + badge: testRunResults["secured"]?.length?.toString(), + onAction: ()=> {setSelectedTab('secured')}, + id: 'secured', + } ] const handleSelectedTab = (selectedIndex) => { @@ -432,7 +447,8 @@ const promotedBulkActions = (selectedDataHexIds) => { ) } - const useComponents = (!workflowTest && testRunResults.all.length === 0) ? [] : components + const allResultsLength = testRunResults.skipped.length + testRunResults.secured.length + testRunResults.vulnerable.length + const useComponents = (!workflowTest && allResultsLength === 0) ? [] : components return ( testLogs boolean valid = filter(); if (!valid) { List testResults = new ArrayList<>(); - testResults.add(new TestResult(null, rawApi.getOriginalMessage(), Collections.singletonList("Request API failed to satisfy api_selection_filters block, skipping execution"), 0, false, TestResult.Confidence.HIGH, null)); + testResults.add(new TestResult(null, rawApi.getOriginalMessage(), Collections.singletonList(SKIPPING_EXECUTION_BECAUSE_FILTERS.getMessage()), 0, false, TestResult.Confidence.HIGH, null)); return new YamlTestResult(testResults, null); } valid = checkAuthBeforeExecution(debug, testLogs); if (!valid) { List testResults = new ArrayList<>(); - testResults.add(new TestResult(null, rawApi.getOriginalMessage(), Collections.singletonList("Request API failed authentication check, skipping execution"), 0, false, TestResult.Confidence.HIGH, null)); + testResults.add(new TestResult(null, rawApi.getOriginalMessage(), Collections.singletonList(SKIPPING_EXECUTION_BECAUSE_AUTH.getMessage()), 0, false, TestResult.Confidence.HIGH, null)); return new YamlTestResult(testResults, null); } YamlTestResult attempts = executor(debug, testLogs); diff --git a/libs/dao/src/main/java/com/akto/dao/testing/TestingRunResultDao.java b/libs/dao/src/main/java/com/akto/dao/testing/TestingRunResultDao.java index 707bb09d97..f85af98920 100644 --- a/libs/dao/src/main/java/com/akto/dao/testing/TestingRunResultDao.java +++ b/libs/dao/src/main/java/com/akto/dao/testing/TestingRunResultDao.java @@ -4,6 +4,7 @@ import com.akto.dao.MCollection; import com.akto.dao.context.Context; import com.akto.dto.ApiInfo; +import com.akto.dto.testing.TestResult; import com.akto.dto.testing.TestingRunResult; import com.akto.util.Constants; import com.akto.util.DbMode; @@ -22,6 +23,7 @@ public class TestingRunResultDao extends AccountsContextDao { public static final TestingRunResultDao instance = new TestingRunResultDao(); public static final int maxDocuments = 5_000_000; public static final long sizeInBytes = 50_000_000_000L; + public static final String ERRORS_KEY = TestingRunResult.TEST_RESULTS+".0."+TestResult.ERRORS+".0"; @Override public String getCollName() { @@ -94,6 +96,10 @@ public void createIndicesIfAbsent() { MCollection.createIndexIfAbsent(getDBName(), getCollName(), new String[] { TestingRunResult.TEST_RUN_RESULT_SUMMARY_ID, TestingRunResult.VULNERABLE, Constants.ID }, false); + + MCollection.createIndexIfAbsent(getDBName(), getCollName(), + new String[] { TestingRunResult.TEST_RUN_RESULT_SUMMARY_ID, TestingRunResult.VULNERABLE, ERRORS_KEY }, false); + MCollection.createIndexIfAbsent(getDBName(), getCollName(), new String[]{TestingRunResult.END_TIMESTAMP}, false); } diff --git a/libs/dao/src/main/java/com/akto/dto/testing/TestResult.java b/libs/dao/src/main/java/com/akto/dto/testing/TestResult.java index 7ba2dcf9e4..c780d721ad 100644 --- a/libs/dao/src/main/java/com/akto/dto/testing/TestResult.java +++ b/libs/dao/src/main/java/com/akto/dto/testing/TestResult.java @@ -2,13 +2,14 @@ import com.akto.dto.testing.info.TestInfo; +import java.util.ArrayList; import java.util.List; public class TestResult extends GenericTestResult { private String message; private List errors; - + public static final String ERRORS = "errors"; private String originalMessage; private double percentageMatch; private TestInfo testInfo; @@ -18,32 +19,47 @@ public enum Confidence { } public enum TestError { - NO_PATH("No sample data found for the API"), - NO_MESSAGE_WITH_AUTH_TOKEN("No sample data found for the API which contains the auth token"), - NO_AUTH_MECHANISM("No authentication mechanism saved"), - API_REQUEST_FAILED("API request failed"), - SOMETHING_WENT_WRONG("OOPS! Something went wrong"), - FAILED_TO_CONVERT_TEST_REQUEST_TO_STRING("Failed to store test"), - INSUFFICIENT_MESSAGES("Insufficient messages"), - NO_AUTH_TOKEN_FOUND("No authentication token found"), - FAILED_DOWNLOADING_NUCLEI_TEMPLATE("Failed downloading nuclei template"), - FAILED_DOWNLOADING_PAYLOAD_FILES("Failed downloading payload files"), - FAILED_BUILDING_NUCLEI_TEMPLATE("Failed building nuclei template"), - FAILED_BUILDING_URL_WITH_DOMAIN("Failed building URL with domain"), - FAILED_REPLACING_VARIABLES_IN_NUCLEI_TEMPLATE("Failed replacing variables in nuclei template"), - EXECUTION_FAILED("Test execution failed"), - INVALID_EXECUTION_BLOCK("Invalid test execution block in template"), - NO_API_REQUEST("No test requests created"); - + NO_PATH("No sample data found for the API", true), + NO_MESSAGE_WITH_AUTH_TOKEN("No sample data found for the API which contains the auth token", true), + NO_AUTH_MECHANISM("No authentication mechanism saved", false), + API_REQUEST_FAILED("API request failed", false), + SOMETHING_WENT_WRONG("OOPS! Something went wrong", false), + FAILED_TO_CONVERT_TEST_REQUEST_TO_STRING("Failed to store test", false), + INSUFFICIENT_MESSAGES("Insufficient messages", false), + NO_AUTH_TOKEN_FOUND("No authentication token found", false), + FAILED_DOWNLOADING_NUCLEI_TEMPLATE("Failed downloading nuclei template", false), + FAILED_DOWNLOADING_PAYLOAD_FILES("Failed downloading payload files", false), + FAILED_BUILDING_URL_WITH_DOMAIN("Failed building URL with domain", false), + FAILED_REPLACING_VARIABLES_IN_NUCLEI_TEMPLATE("Failed replacing variables in nuclei template", false), + EXECUTION_FAILED("Test execution failed", false), + INVALID_EXECUTION_BLOCK("Invalid test execution block in template", true), + NO_API_REQUEST("No test requests created", false), + SKIPPING_EXECUTION_BECAUSE_AUTH("Request API failed authentication check, skipping execution", true), + SKIPPING_EXECUTION_BECAUSE_FILTERS("Request API failed to satisfy api_selection_filters block, skipping execution", true); private final String message; + private final boolean skipTest; - TestError(String message) { + TestError(String message, boolean skipTest) { this.message = message; + this.skipTest = skipTest; } public String getMessage() { return message; } + public boolean getSkipTest() { + return skipTest; + } + + public static List getErrorsToSkipTests() { + List ret = new ArrayList<>(); + for(TestError te: TestError.values()) { + if (te.getSkipTest()) { + ret.add(te.getMessage()); + } + } + return ret; + } } public TestResult(String message, String originalMessage, List errors, double percentageMatch, boolean isVulnerable, From 2206d7d5c10f4bcbc90b3a658da511f034f64f0c Mon Sep 17 00:00:00 2001 From: Ankush Jain Date: Tue, 9 Apr 2024 12:02:00 +0530 Subject: [PATCH 08/10] change title of the table --- .../pages/testing/SingleTestRunPage/SingleTestRunPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/SingleTestRunPage/SingleTestRunPage.js b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/SingleTestRunPage/SingleTestRunPage.js index 73bd61b92f..726d2280db 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/SingleTestRunPage/SingleTestRunPage.js +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/SingleTestRunPage/SingleTestRunPage.js @@ -327,7 +327,7 @@ const promotedBulkActions = (selectedDataHexIds) => { id: 'skipped', }, { - content: 'Secured', + content: 'No vulnerability found', index: 2, badge: testRunResults["secured"]?.length?.toString(), onAction: ()=> {setSelectedTab('secured')}, From c4b08e7e64dc373fc963402ca31c1efcecddf045 Mon Sep 17 00:00:00 2001 From: Ark2307 Date: Tue, 9 Apr 2024 14:03:40 +0530 Subject: [PATCH 09/10] fixing null checks and adding filter operators for method header in api changes --- .../api_collections/component/ApiChangesTable.jsx | 2 +- .../pages/observe/api_collections/data/apiChanges.js | 12 +++++++++++- .../pages/testing/SingleTestRunPage/TrendChart.jsx | 11 ++++++----- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/observe/api_collections/component/ApiChangesTable.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/observe/api_collections/component/ApiChangesTable.jsx index 3809daf62f..6df5d4eb1e 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/observe/api_collections/component/ApiChangesTable.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/observe/api_collections/component/ApiChangesTable.jsx @@ -123,7 +123,7 @@ function ApiChangesTable(props) { selected={selected} onSelect={handleSelectedTab} mode={IndexFiltersMode.Default} - headings={tableDataObj.headers} + headings={tableDataObj.headings} useNewRow={true} condensedHeight={true} tableTabs={tableTabs} diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/observe/api_collections/data/apiChanges.js b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/observe/api_collections/data/apiChanges.js index ee2b726ba1..362faa0306 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/observe/api_collections/data/apiChanges.js +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/observe/api_collections/data/apiChanges.js @@ -121,6 +121,14 @@ const endpointResourceName = { plural: 'API endpoints', }; +const methodObj = [{ + text: 'Method', + value: 'method', + filterKey: 'method', + showFilter: true, + textValue: 'method', +}] + const endpointSortOptions = [ { label: 'Method', value: 'method asc', directionLabel: 'A-Z', sortKey: 'method' }, { label: 'Method', value: 'method desc', directionLabel: 'Z-A', sortKey: 'method' }, @@ -180,13 +188,15 @@ const apiChangesData = { getData(key){ if(key === 'param'){ const obj = { - headers: newParametersHeaders, + headers: [...newParametersHeaders, ...methodObj], + headings: newParametersHeaders, resourceName: parameterResourceName, sortOptions: parameterSortOptions, } return obj; }else{ const obj = { + headings: endpointHeadings, headers: endpointHeadings, resourceName: endpointResourceName, sortOptions: endpointSortOptions, diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/SingleTestRunPage/TrendChart.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/SingleTestRunPage/TrendChart.jsx index 5ed1cfd1f7..5ad746c907 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/SingleTestRunPage/TrendChart.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/SingleTestRunPage/TrendChart.jsx @@ -64,10 +64,11 @@ function TrendChart(props) { items.forEach((x) => { let ts = x["startTimestamp"] * 1000 let countIssuesMap = x["countIssues"] - - retH.push([ts, countIssuesMap["HIGH"]]) - retM.push([ts, countIssuesMap["MEDIUM"]]) - retL.push([ts, countIssuesMap["LOW"]]) + if(countIssuesMap && Object.keys(countIssuesMap).length > 0){ + retH.push([ts, countIssuesMap["HIGH"]]) + retM.push([ts, countIssuesMap["MEDIUM"]]) + retL.push([ts, countIssuesMap["LOW"]]) + } }) return [ @@ -144,7 +145,7 @@ function TrendChart(props) { let count = 0 testingRunResultSummaries.forEach((ele)=>{ - let obj = Object.keys(ele.countIssues) ? ele.countIssues : {HIGH: 0, MEDIUM: 0, LOW: 0} + let obj = Object.keys(ele.countIssues).length > 0 ? ele.countIssues : {HIGH: 0, MEDIUM: 0, LOW: 0} count += (obj.HIGH + obj.MEDIUM + obj.LOW) }) From 444aa4fd4fd381c9607c942b21b4eba2e8ac40dd Mon Sep 17 00:00:00 2001 From: Aryan Khandelwal <60040654+Ark2307@users.noreply.github.com> Date: Tue, 9 Apr 2024 15:21:26 +0530 Subject: [PATCH 10/10] Fix compile error --- .github/workflows/beamerAndDiscord.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/beamerAndDiscord.yml b/.github/workflows/beamerAndDiscord.yml index 713120603d..cd48eaa84d 100644 --- a/.github/workflows/beamerAndDiscord.yml +++ b/.github/workflows/beamerAndDiscord.yml @@ -40,7 +40,7 @@ jobs: line = line.split('by', 1)[0].strip() release_notes += f'
  • {line[1:]}
  • ' release_notes += '' - release_notes2 += '

    Have questions? Ask on Discord or our Community page' + release_notes2 = '

    Have questions? Ask on Discord or our Community page' release_notes = release_notes+release_notes2