Skip to content

Commit

Permalink
Recalculate functionality added
Browse files Browse the repository at this point in the history
  • Loading branch information
Ark2307 committed Jan 2, 2025
1 parent fed8b14 commit b942853
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.akto.log.LoggerMaker;
import com.akto.log.LoggerMaker.LogDb;
import com.akto.util.Constants;
import com.akto.util.enums.GlobalEnums;
import com.akto.util.enums.GlobalEnums.TestErrorSource;
import com.akto.utils.DeleteTestRunUtils;
import com.akto.utils.Utils;
Expand All @@ -40,6 +41,7 @@
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -507,21 +509,25 @@ public String fetchTestingRunResultSummary() {
}
}

private static Bson vulnerableFilter = Filters.and(
Filters.eq(TestingRunResult.VULNERABLE, true),
Filters.in(TestingRunResult.IS_IGNORED_RESULT, Arrays.asList(null, false))
);

private List<Bson> prepareTestRunResultsFilters(ObjectId testingRunResultSummaryId, QueryMode queryMode) {
List<Bson> filterList = new ArrayList<>();
filterList.add(Filters.eq(TestingRunResult.TEST_RUN_RESULT_SUMMARY_ID, testingRunResultSummaryId));

Bson filtersForTestingRunResults = com.akto.action.testing.Utils.createFiltersForTestingReport(reportFilterList);
if(!filtersForTestingRunResults.equals(Filters.empty())) filterList.add(filtersForTestingRunResults);

if(queryMode == null) {
if(fetchOnlyVulnerable) {
filterList.add(Filters.eq(TestingRunResult.VULNERABLE, true));
filterList.add(vulnerableFilter);
}
} else {
switch (queryMode) {
case VULNERABLE:
filterList.add(Filters.eq(TestingRunResult.VULNERABLE, true));
filterList.add(vulnerableFilter);
break;
case SKIPPED_EXEC_API_REQUEST_FAILED:
filterList.add(Filters.eq(TestingRunResult.VULNERABLE, false));
Expand Down Expand Up @@ -1043,6 +1049,80 @@ public String modifyTestingRunConfig(){
return SUCCESS.toUpperCase();
}

public String handleRefreshTableCount(){
if(this.testingRunResultSummaryHexId == null || this.testingRunResultSummaryHexId.isEmpty()){
addActionError("Invalid summary id");
return ERROR.toUpperCase();
}
int accountId = Context.accountId.get();
executorService.schedule( new Runnable() {
public void run() {
Context.accountId.set(accountId);
try {
ObjectId summaryObjectId = new ObjectId(testingRunResultSummaryHexId);
List<TestingRunResult> testingRunResults = TestingRunResultDao.instance.findAll(
Filters.and(
Filters.eq(TestingRunResult.TEST_RUN_RESULT_SUMMARY_ID, summaryObjectId),
vulnerableFilter
),
Projections.include(TestingRunResult.API_INFO_KEY, TestingRunResult.TEST_SUB_TYPE)
);

if(testingRunResults.isEmpty()){
return;
}

Set<TestingIssuesId> issuesIds = new HashSet<>();
Map<TestingIssuesId, ObjectId> mapIssueToResultId = new HashMap<>();
Set<ObjectId> ignoredResults = new HashSet<>();
for(TestingRunResult runResult: testingRunResults){
TestingIssuesId issuesId = new TestingIssuesId(runResult.getApiInfoKey(), TestErrorSource.AUTOMATED_TESTING , runResult.getTestSubType());
issuesIds.add(issuesId);
mapIssueToResultId.put(issuesId, runResult.getId());
ignoredResults.add(runResult.getId());
}

List<TestingRunIssues> issues = TestingRunIssuesDao.instance.findAll(
Filters.and(
Filters.in(Constants.ID, issuesIds),
Filters.eq(TestingRunIssues.TEST_RUN_ISSUES_STATUS, GlobalEnums.TestRunIssueStatus.OPEN)
), Projections.include(TestingRunIssues.KEY_SEVERITY)
);

Map<String, Integer> totalCountIssues = new HashMap<>();
totalCountIssues.put("HIGH", 0);
totalCountIssues.put("MEDIUM", 0);
totalCountIssues.put("LOW", 0);

for(TestingRunIssues runIssue: issues){
int initCount = totalCountIssues.getOrDefault(runIssue.getSeverity().name(), 0);
totalCountIssues.put(runIssue.getSeverity().name(), initCount + 1);
if(mapIssueToResultId.containsKey(runIssue.getId())){
ObjectId resId = mapIssueToResultId.get(runIssue.getId());
ignoredResults.remove(resId);
}
}

// update testing run result summary
TestingRunResultSummariesDao.instance.updateOne(
Filters.eq(Constants.ID, summaryObjectId),
Updates.set(TestingRunResultSummary.COUNT_ISSUES, totalCountIssues)
);

// update testing run results, by setting them isIgnored true
TestingRunResultDao.instance.updateMany(
Filters.in(Constants.ID, ignoredResults),
Updates.set(TestingRunResult.IS_IGNORED_RESULT, true)
);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 0 , TimeUnit.SECONDS);

return SUCCESS.toUpperCase();
}


public void setType(TestingEndpoints.Type type) {
this.type = type;
Expand Down
21 changes: 21 additions & 0 deletions apps/dashboard/src/main/resources/struts.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3513,6 +3513,27 @@
</result>
</action>

<action name="api/handleRefreshTableCount" class="com.akto.action.testing.StartTestAction" method="handleRefreshTableCount">
<interceptor-ref name="json"/>
<interceptor-ref name="defaultStack" />
<interceptor-ref name="roleAccessInterceptor">
<param name="featureLabel">TEST_RESULTS</param>
<param name="accessType">READ</param>
</interceptor-ref>

<result name="FORBIDDEN" type="json">
<param name="statusCode">403</param>
<param name="ignoreHierarchy">false</param>
<param name="includeProperties">^actionErrors.*</param>
</result>
<result name="SUCCESS" type="json"/>
<result name="ERROR" type="json">
<param name="statusCode">422</param>
<param name="ignoreHierarchy">false</param>
<param name="includeProperties">^actionErrors.*</param>
</result>
</action>

<action name="api/fetchTestingRunResultSummary" class="com.akto.action.testing.StartTestAction" method="fetchTestingRunResultSummary">
<interceptor-ref name="json"/>
<interceptor-ref name="defaultStack" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,13 @@ const editableConfigsComp = (
}
}

const handleRefreshTableCount = async(summaryHexId) => {
await api.handleRefreshTableCount(summaryHexId).then((res) => {
func.setToast("Re-calculating issues count")
setSecondaryPopover(false)
})
}

const EmptyData = () => {
return(
<div style={{margin: 'auto', marginTop: '20vh'}}>
Expand Down Expand Up @@ -710,6 +717,11 @@ const editableConfigsComp = (
content: 'Edit testing config settings',
icon: EditMajor,
onAction: () => { setShowEditableSettings(true); handleAddSettings(); }
},
{
content: 'Re-Calculate Issues Count',
icon: RefreshMajor,
onAction: () => {handleRefreshTableCount(currentSummary.hexId)}
}
]})
const moreActionsComp = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import "./style.css"
import ActivityTracker from '../../dashboard/components/ActivityTracker'
import observeFunc from "../../observe/transform.js"
import settingFunctions from '../../settings/module.js'
import DropdownSearch from '../../../components/shared/DropdownSearch.jsx'
import JiraTicketCreationModal from '../../../components/shared/JiraTicketCreationModal.jsx'

function TestRunResultFlyout(props) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,5 +494,12 @@ export default {
method: 'post',
data: {...filters, issueIds, endTimeStamp}
})
},
handleRefreshTableCount(testingRunResultSummaryHexId) {
return request({
url: '/api/handleRefreshTableCount',
method: 'post',
data: {testingRunResultSummaryHexId}
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.akto.dao.test_editor.YamlTemplateDao;
import com.akto.dto.test_editor.YamlTemplate;
import com.akto.dto.test_run_findings.TestingIssuesId;
import com.akto.util.Constants;
import com.akto.util.enums.GlobalEnums;
import com.akto.util.enums.MongoDBEnums;
import com.mongodb.BasicDBObject;
Expand Down Expand Up @@ -60,6 +61,9 @@ public void createIndicesIfAbsent() {
MCollection.createIndexIfAbsent(getDBName(), getCollName(), fieldNames, true);
fieldNames = new String[] {TestingRunIssues.LATEST_TESTING_RUN_SUMMARY_ID};
MCollection.createIndexIfAbsent(getDBName(), getCollName(), fieldNames, true);

fieldNames = new String[] {Constants.ID, TestingRunIssues.TEST_RUN_ISSUES_STATUS};
MCollection.createIndexIfAbsent(getDBName(), getCollName(), fieldNames, true);

}

Expand Down
10 changes: 10 additions & 0 deletions libs/dao/src/main/java/com/akto/dto/testing/TestingRunResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public class TestingRunResult implements Comparable<TestingRunResult> {
public static final String TEST_RUN_RESULT_SUMMARY_ID = "testRunResultSummaryId";
private ObjectId testRunResultSummaryId;

public static final String IS_IGNORED_RESULT = "isIgnoredResult";
private boolean isIgnoredResult ;

public static final String ERRORS_LIST = "errorsList";
private List<String> errorsList;
Expand Down Expand Up @@ -343,4 +345,12 @@ public List<String> getErrorsList() {
public void setErrorsList(List<String> errorsList) {
this.errorsList = errorsList;
}

public boolean isIgnoredResult() {
return isIgnoredResult;
}

public void setIgnoredResult(boolean isIgnoredResult) {
this.isIgnoredResult = isIgnoredResult;
}
}

0 comments on commit b942853

Please sign in to comment.