Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fixed vul and ignored testing counts #1840

Merged
merged 6 commits into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -510,26 +510,8 @@ private List<Bson> prepareTestRunResultsFilters(ObjectId testingRunResultSummary
List<Bson> filterList = new ArrayList<>();
filterList.add(Filters.eq(TestingRunResult.TEST_RUN_RESULT_SUMMARY_ID, testingRunResultSummaryId));

if(filters != null && !filters.isEmpty()) {
for(Map.Entry<String, List> filterEntry : filters.entrySet()) {
String key = filterEntry.getKey();
switch (key) {
case "severityStatus":
filterList.add(Filters.in(TestingRunResult.TEST_RESULTS+"."+GenericTestResult._CONFIDENCE, filterEntry.getValue()));
break;
case "apiCollectionId":
case "collectionIds":
filterList.add(Filters.in(TestingRunResult.API_INFO_KEY+"."+ApiInfo.ApiInfoKey.API_COLLECTION_ID, filterEntry.getValue()));
break;
case "method":
filterList.add(Filters.in(TestingRunResult.API_INFO_KEY+"."+ApiInfo.ApiInfoKey.METHOD, filterEntry.getValue()));
break;
case "categoryFilter":
filterList.add(Filters.in(TestingRunResult.TEST_SUPER_TYPE, filterEntry.getValue()));
break;
}
}
}
Bson filtersForTestingRunResults = com.akto.action.testing.Utils.createFiltersForTestingReport(reportFilterList);
if(!filtersForTestingRunResults.equals(Filters.empty())) filterList.add(filtersForTestingRunResults);

if(queryMode == null) {
if(fetchOnlyVulnerable) {
Expand Down Expand Up @@ -569,9 +551,28 @@ private List<Bson> prepareTestRunResultsFilters(ObjectId testingRunResultSummary
}
}

if(filterList.isEmpty()) {
filterList.add(Filters.empty());
}

return filterList;
}

public static Bson prepareTestingRunResultCustomSorting(String sortKey, int sortOrder) {
Bson sortStage = null;
if (TestingRunIssues.KEY_SEVERITY.equals(sortKey)) {
sortStage = (sortOrder == 1) ?
Aggregates.sort(Sorts.ascending("severityValue", TestingRunResult.END_TIMESTAMP)) :
Aggregates.sort(Sorts.descending("severityValue", TestingRunResult.END_TIMESTAMP));
} else if ("time".equals(sortKey)) {
sortStage = (sortOrder == 1) ?
Aggregates.sort(Sorts.ascending(TestingRunResult.END_TIMESTAMP)) :
Aggregates.sort(Sorts.descending(TestingRunResult.END_TIMESTAMP));
}

return sortStage;
}

String testingRunResultSummaryHexId;
List<TestingRunResult> testingRunResults;
private boolean fetchOnlyVulnerable;
Expand All @@ -595,6 +596,12 @@ public String fetchTestingRunResults() {
if (testingRunResultSummaryHexId != null) loggerMaker.infoAndAddToDb("fetchTestingRunResults called for hexId=" + testingRunResultSummaryHexId);
if (queryMode != null) loggerMaker.infoAndAddToDb("fetchTestingRunResults called for queryMode="+queryMode);

Bson ignoredIssuesFilters = Filters.and(
Filters.in(TestingRunIssues.TEST_RUN_ISSUES_STATUS, "IGNORED"),
Filters.in(TestingRunIssues.LATEST_TESTING_RUN_SUMMARY_ID, testingRunResultSummaryId)
);
List<TestingRunIssues> issueslist = TestingRunIssuesDao.instance.findAll(ignoredIssuesFilters, Projections.include("_id"));

List<Bson> testingRunResultFilters = prepareTestRunResultsFilters(testingRunResultSummaryId, queryMode);

if(queryMode == QueryMode.SKIPPED_EXEC || queryMode == QueryMode.SKIPPED_EXEC_NEED_CONFIG){
Expand All @@ -609,19 +616,13 @@ public String fetchTestingRunResults() {

try {
int pageLimit = limit <= 0 ? 150 : limit;
Bson sortStage = null;
if (TestingRunIssues.KEY_SEVERITY.equals(sortKey)) {
sortStage = (sortOrder == 1) ?
Aggregates.sort(Sorts.ascending("severityValue", TestingRunResult.END_TIMESTAMP)) :
Aggregates.sort(Sorts.descending("severityValue", TestingRunResult.END_TIMESTAMP));
} else if ("time".equals(sortKey)) {
sortStage = (sortOrder == 1) ?
Aggregates.sort(Sorts.ascending(TestingRunResult.END_TIMESTAMP)) :
Aggregates.sort(Sorts.descending(TestingRunResult.END_TIMESTAMP));
}
Bson sortStage = prepareTestingRunResultCustomSorting(sortKey, sortOrder);

Bson filters = testingRunResultFilters.isEmpty() ? Filters.empty() : Filters.and(testingRunResultFilters);
this.testingRunResults = TestingRunResultDao.instance
.fetchLatestTestingRunResultWithCustomAggregations(Filters.and(testingRunResultFilters), pageLimit, skip, sortStage);
.fetchLatestTestingRunResultWithCustomAggregations(filters, pageLimit, skip, sortStage);

removeTestingRunResultsByIssues(testingRunResults, issueslist, false);

testCountMap = new HashMap<>();
for(QueryMode qm : QueryMode.values()) {
Expand All @@ -635,20 +636,42 @@ public String fetchTestingRunResults() {
testCountMap.put(qm.toString(), count);
}

Bson ignoredIssuesFilters = Filters.and(
Filters.in(TestingRunIssues.TEST_RUN_ISSUES_STATUS, Arrays.asList("IGNORED", "FIXED")),
Filters.in(TestingRunIssues.LATEST_TESTING_RUN_SUMMARY_ID, testingRunResultSummaryId)
);
int count = (int) TestingRunIssuesDao.instance.count(ignoredIssuesFilters);
testCountMap.put(QueryMode.VULNERABLE.name(), Math.abs(testCountMap.getOrDefault(QueryMode.VULNERABLE.name(), 0)-count));
testCountMap.put("IGNORED_ISSUES", count);
testCountMap.put(QueryMode.VULNERABLE.name(), Math.abs(testCountMap.getOrDefault(QueryMode.VULNERABLE.name(), 0)- issueslist.size()));
testCountMap.put("IGNORED_ISSUES", issueslist.size());
} catch (Exception e) {
loggerMaker.errorAndAddToDb(e, "error in fetchLatestTestingRunResult: " + e);
}

return SUCCESS.toUpperCase();
}

public static void removeTestingRunResultsByIssues(List<TestingRunResult> testingRunResults,
List<TestingRunIssues> testingRunIssues,
boolean retainByIssues) {
Set<String> issuesSet = new HashSet<>();
for (TestingRunIssues issue : testingRunIssues) {
String apiInfoKeyString = issue.getId().getApiInfoKey().toString();
String key = apiInfoKeyString + "|" + issue.getId().getTestSubCategory();
issuesSet.add(key);
}

Iterator<TestingRunResult> resultIterator = testingRunResults.iterator();

while (resultIterator.hasNext()) {
TestingRunResult result = resultIterator.next();
String apiInfoKeyString = result.getApiInfoKey().toString();
String resultKey = apiInfoKeyString + "|" + result.getTestSubType();

boolean matchFound = issuesSet.contains(resultKey);

if (retainByIssues && !matchFound) {
resultIterator.remove();
} else if (!retainByIssues && matchFound) {
resultIterator.remove();
}
}
}

private Map<String, List<String>> reportFilterList;

public String fetchVulnerableTestRunResults() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static Bson createFiltersForTestingReport(Map<String, List<String>> filte
String key = entry.getKey();
List<String> value = entry.getValue();

if (value.size() == 0) continue;
if (value.isEmpty()) continue;
List<Integer> collectionIds = new ArrayList<>();
if(key.equals(SingleTypeInfo._API_COLLECTION_ID)){
for(String str: value){
Expand All @@ -32,6 +32,7 @@ public static Bson createFiltersForTestingReport(Map<String, List<String>> filte
case SingleTypeInfo._METHOD:
filterList.add(Filters.in(TestingRunResult.API_INFO_KEY + "." + ApiInfoKey.METHOD, value));
break;
case SingleTypeInfo._COLLECTION_IDS:
case SingleTypeInfo._API_COLLECTION_ID:
filterList.add(Filters.in(TestingRunResult.API_INFO_KEY + "." + ApiInfoKey.API_COLLECTION_ID, collectionIds));
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.akto.action.ExportSampleDataAction;
import com.akto.action.UserAction;
import com.akto.action.testing.Utils;
import com.akto.dao.HistoricalDataDao;
import com.akto.dao.RBACDao;
import com.akto.action.testing.StartTestAction;
Expand Down Expand Up @@ -527,12 +528,38 @@ public String bulkUpdateIssueStatus () {

String latestTestingRunSummaryId;
List<String> issueStatusQuery;
List<TestingRunResult> testingRunResultList;
private Map<String, List<String>> filters;
public String fetchIssuesByStatusAndSummaryId() {
Bson filters = Filters.and(
Bson triFilters = Filters.and(
Filters.in(TestingRunIssues.TEST_RUN_ISSUES_STATUS, issueStatusQuery),
Filters.in(TestingRunIssues.LATEST_TESTING_RUN_SUMMARY_ID, new ObjectId(latestTestingRunSummaryId))
);
issues = TestingRunIssuesDao.instance.findAll(filters);
issues = TestingRunIssuesDao.instance.findAll(triFilters, Projections.include("_id"));

List<Bson> testingRunResultsFilterList = new ArrayList<>();
for(TestingRunIssues issue: issues) {
testingRunResultsFilterList.add(Filters.and(
Filters.eq(TestingRunResult.TEST_RUN_RESULT_SUMMARY_ID, new ObjectId(latestTestingRunSummaryId)),
Filters.eq(TestingRunResult.VULNERABLE, true),
Filters.eq(TestingRunResult.API_INFO_KEY, issue.getId().getApiInfoKey()),
Filters.eq(TestingRunResult.TEST_SUB_TYPE, issue.getId().getTestSubCategory())
));
}

List<Bson> filtersList = new ArrayList<>();
if(!testingRunResultsFilterList.isEmpty()) filtersList.add(Filters.or(testingRunResultsFilterList));
Bson filtersForTestingRunResults = Utils.createFiltersForTestingReport(filters);
if(!filtersForTestingRunResults.equals(Filters.empty())) filtersList.add(filtersForTestingRunResults);
Bson sortStage = StartTestAction.prepareTestingRunResultCustomSorting(sortKey, sortOrder);

if(filtersList.isEmpty()) {
testingRunResultList = new ArrayList<>();
return SUCCESS.toUpperCase();
}

testingRunResultList = TestingRunResultDao.instance.fetchLatestTestingRunResultWithCustomAggregations(Filters.and(filtersList), limit, skip, sortStage);

return SUCCESS.toUpperCase();
}

Expand Down Expand Up @@ -824,6 +851,14 @@ public TestingRunResultSummary getTestingRunResultSummary() {
return testingRunResultSummary;
}

public List<TestingRunResult> getTestingRunResultList() {
return testingRunResultList;
}

public void setFilters(Map<String, List<String>> filters) {
this.filters = filters;
}

public void setReportFilterList(Map<String, List<String>> reportFilterList) {
this.reportFilterList = reportFilterList;
}
Expand Down
4 changes: 1 addition & 3 deletions apps/dashboard/src/main/resources/struts.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7538,9 +7538,7 @@
<param name="ignoreHierarchy">false</param>
<param name="includeProperties">^actionErrors.*</param>
</result>
<result name="SUCCESS" type="json">
<param name="root">issues</param>
</result>
<result name="SUCCESS" type="json"/>
<result name="ERROR" type="json">
<param name="statusCode">422</param>
<param name="ignoreHierarchy">false</param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ function SingleTestRunPage() {
const fetchTableData = async (sortKey, sortOrder, skip, limit, filters, filterOperators, queryValue) => {
let testRunResultsRes = []
let testRunCountMap = []
let totalIgnoredIssuesCount = 0
const { testingRun, workflowTest, testingRunType } = testingRunResultSummariesObj
if(testingRun === undefined){
return {value: [], total: 0}
Expand All @@ -261,35 +262,14 @@ function SingleTestRunPage() {

setSelectedTestRun(localSelectedTestRun);
if(localSelectedTestRun.testingRunResultSummaryHexId) {
if(selectedTab === 'ignored_issues' || selectedTab === 'vulnerable') {
let vulnerableTestingRunResults = []
await api.fetchTestingRunResults(localSelectedTestRun.testingRunResultSummaryHexId, "VULNERABLE", sortKey, sortOrder, skip, limit, filters, queryValue).then(({ testingRunResults, testCountMap }) => {
testRunCountMap = testCountMap
vulnerableTestingRunResults = testingRunResults
testRunResultsRes = transform.prepareTestRunResults(hexId, testingRunResults, subCategoryMap, subCategoryFromSourceConfigMap)
const orderedValues = tableTabsOrder.map(key => testCountMap[tableTabMap[key]] || 0)
setTestRunResultsCount(orderedValues)
})
if(selectedTab === 'ignored_issues') {
let ignoredTestRunResults = []
await api.fetchIssuesByStatusAndSummaryId(localSelectedTestRun.testingRunResultSummaryHexId, ["IGNORED", "FIXED"]).then((issues) => {
const ignoredTestingResults = vulnerableTestingRunResults.filter(result => {
return issues.some(issue =>
issue.id.apiInfoKey.apiCollectionId === result.apiInfoKey.apiCollectionId &&
issue.id.apiInfoKey.method === result.apiInfoKey.method &&
issue.id.apiInfoKey.url === result.apiInfoKey.url &&
issue.id.testSubCategory === result.testSubType
)
})

ignoredTestRunResults = transform.prepareTestRunResults(hexId, ignoredTestingResults, subCategoryMap, subCategoryFromSourceConfigMap)
})

const updatedVulnerableTestRunResults = testRunResultsRes.filter(result => {
return !ignoredTestRunResults.some(ignoredResult => {
return JSON.stringify(result) === JSON.stringify(ignoredResult)
})
await api.fetchIssuesByStatusAndSummaryId(localSelectedTestRun.testingRunResultSummaryHexId, ["IGNORED"], sortKey, sortOrder, skip, limit, filters).then((resp) => {
const ignoredIssuesTestingResult = resp?.testingRunResultList || [];
ignoredTestRunResults = transform.prepareTestRunResults(hexId, ignoredIssuesTestingResult, subCategoryMap, subCategoryFromSourceConfigMap)
})
testRunResultsRes = selectedTab === 'vulnerable' ? updatedVulnerableTestRunResults : ignoredTestRunResults
testRunResultsRes = ignoredTestRunResults
totalIgnoredIssuesCount = ignoredTestRunResults.length
} else {
await api.fetchTestingRunResults(localSelectedTestRun.testingRunResultSummaryHexId, tableTabMap[selectedTab], sortKey, sortOrder, skip, limit, filters, queryValue).then(({ testingRunResults, testCountMap, errorEnums }) => {
testRunCountMap = testCountMap
Expand All @@ -305,7 +285,7 @@ function SingleTestRunPage() {
}
}
fillTempData(testRunResultsRes, selectedTab)
return {value: transform.getPrettifiedTestRunResults(testRunResultsRes), total: testRunCountMap[tableTabMap[selectedTab]]}
return {value: transform.getPrettifiedTestRunResults(testRunResultsRes), total: selectedTab === 'ignored_issues' ? totalIgnoredIssuesCount : testRunCountMap[tableTabMap[selectedTab]]}
}

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ export default {
})
return resp
},
async fetchTestingRunResults(testingRunResultSummaryHexId, queryMode, sortKey, sortOrder, skip, limit, filters, queryValue) {
async fetchTestingRunResults(testingRunResultSummaryHexId, queryMode, sortKey, sortOrder, skip, limit, reportFilterList, queryValue) {
const resp = await request({
url: '/api/fetchTestingRunResults',
method: 'post',
data: {
testingRunResultSummaryHexId, queryMode, sortKey, sortOrder, skip, limit, filters, queryValue
testingRunResultSummaryHexId, queryMode, sortKey, sortOrder, skip, limit, reportFilterList, queryValue
}
})
return resp
Expand Down Expand Up @@ -450,11 +450,11 @@ export default {
data: {deltaTimeForScheduledSummaries}
})
},
fetchIssuesByStatusAndSummaryId(latestTestingRunSummaryId, issueStatusQuery) {
fetchIssuesByStatusAndSummaryId(latestTestingRunSummaryId, issueStatusQuery, sortKey, sortOrder, skip, limit, filters) {
return request({
url: '/api/fetchIssuesByStatusAndSummaryId',
method: 'post',
data: { latestTestingRunSummaryId, issueStatusQuery }
data: { latestTestingRunSummaryId, issueStatusQuery, sortKey, sortOrder, skip, limit, filters }
})
},
modifyTestingRunConfig(testingRunConfigId, testConfigsAdvancedSettings){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,20 @@ const VulnerabilityReport = () => {
if (window.location.pathname.includes('testing')) {
const testingRunSummaryId = currentFilters.testingRunResultSummaryId[0]
await api.fetchTestingRunResultsSummary(testingRunSummaryId).then((resp) => {
let startTimestamp = '-'
if(resp == null) {
setScanTime('-')
} else if(resp?.state === 'COMPLETED') {
const time = func.getTimeTakenByTest(resp?.startTimestamp, resp?.endTimestamp)
setScanTime(time || '-')
startTimestamp = func.getFormattedDate(resp?.startTimestamp)
} else {
setScanTime("-")
startTimestamp = func.getFormattedDate(resp?.startTimestamp)
}
setCurrentDate(startTimestamp)

if(resp?.startTimestamp) {
setCurrentDate(func.getFormattedDate(resp?.startTimestamp))
} else {
setCurrentDate('-')
}
})

while (true) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ public void createIndicesIfAbsent() {

fieldNames = new String[]{TestingRunResult.TEST_RUN_RESULT_SUMMARY_ID, TestingRunResult.TEST_SUPER_TYPE};
MCollection.createIndexIfAbsent(getDBName(), getCollName(), fieldNames, false);

fieldNames = new String[]{TestingRunResult.TEST_RUN_RESULT_SUMMARY_ID, TestingRunResult.VULNERABLE, TestingRunResult.API_INFO_KEY, TestingRunResult.TEST_SUB_TYPE};
MCollection.createIndexIfAbsent(getDBName(), getCollName(), fieldNames, false);
}

public void convertToCappedCollection() {
Expand Down
Loading