Skip to content

Commit

Permalink
feat: enhance PDF report handling by supporting multiple chunks and u…
Browse files Browse the repository at this point in the history
…pdating related data structures
  • Loading branch information
TangoBeeAkto committed Jan 15, 2025
1 parent a427c39 commit 0516db5
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 13 deletions.
39 changes: 29 additions & 10 deletions apps/dashboard/src/main/java/com/akto/action/ReportAction.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.akto.action;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
Expand All @@ -13,10 +12,13 @@

import com.akto.dao.testing.sources.TestReportsDao;
import com.akto.dto.testing.sources.TestReports;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.MongoCommandException;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.bson.BsonMaximumSizeExceededException;
import org.bson.types.ObjectId;
import org.json.JSONObject;

Expand All @@ -36,7 +38,7 @@ public class ReportAction extends UserAction {
private String organizationName;
private String reportDate;
private String reportUrl;
private String pdf;
private List<String> pdf;
private String status;
private boolean firstPollRequest;

Expand Down Expand Up @@ -70,9 +72,13 @@ public String downloadReportPDF() {

if(firstPollRequest) {
TestReports testReport = TestReportsDao.instance.findOne(Filters.eq("_id", reportUrlIdObj));
if(testReport != null && (testReport.getPdfReportString() != null && !testReport.getPdfReportString().isEmpty())) {
if(testReport != null && !StringUtils.isEmpty(testReport.getPdfReportString())) {
status = "COMPLETED";
pdf = testReport.getPdfReportString();
pdf = Arrays.asList(testReport.getPdfReportString());
return SUCCESS.toUpperCase();
} else if(testReport != null && (testReport.getPdfReportStringChunks() != null && !testReport.getPdfReportStringChunks().isEmpty())) {
status = "COMPLETED";
pdf = testReport.getPdfReportStringChunks();
return SUCCESS.toUpperCase();
}
}
Expand Down Expand Up @@ -134,27 +140,40 @@ public String downloadReportPDF() {

if (status.equals("COMPLETED")) {
loggerMaker.infoAndAddToDb("Pdf download status for report id - " + reportId + " completed. Attaching pdf in response ", LogDb.DASHBOARD);
pdf = node.get("base64PDF").textValue();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode base64PDF = node.get("base64PDF");
if(base64PDF == null) {
status = "ERROR";
return ERROR.toUpperCase();
}
pdf = objectMapper.convertValue(base64PDF, List.class);

try {
TestReportsDao.instance.updateOne(Filters.eq("_id", reportUrlIdObj), Updates.set(TestReports.PDF_REPORT_STRING, pdf));
TestReportsDao.instance.updateOne(Filters.eq("_id", reportUrlIdObj), Updates.set(TestReports.PDF_REPORT_STRING_CHUNKS, pdf));
} catch(Exception e) {
loggerMaker.errorAndAddToDb("Error: " + e.getMessage() + ", while updating report binary for reportId: " + reportId, LogDb.DASHBOARD);
if (e instanceof MongoCommandException) {
MongoCommandException mongoException = (MongoCommandException) e;
if (mongoException.getCode() == 17420) {
addActionError("The report is too large to save. Please reduce its size and try again.");
status = "COMPLETED";
return SUCCESS.toUpperCase();
} else {
addActionError("A database error occurred while saving the report. Try again later.");
}
} else if(e instanceof BsonMaximumSizeExceededException) {
status = "COMPLETED";
return SUCCESS.toUpperCase();
} else {
addActionError("An error occurred while updating the report in DB. Please try again.");
}
status = "ERROR";
return ERROR.toUpperCase();
}
}
} catch (Exception e) {
loggerMaker.errorAndAddToDb(e, "Error while polling pdf download for report id - " + reportId, LogDb.DASHBOARD);
status = "ERROR";
return ERROR.toUpperCase();
}
}

Expand Down Expand Up @@ -193,11 +212,11 @@ public void setReportUrl(String reportUrl) {
this.reportUrl = reportUrl;
}

public String getPdf() {
public List<String> getPdf() {
return pdf;
}

public void setPdf(String pdf) {
public void setPdf(List<String> pdf) {
this.pdf = pdf;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ public String fetchTestingRunResultsSummary() {

public String generateTestReport () {
try {
TestReports testReport = new TestReports(reportFilterList, Context.now(), "", this.issuesIdsForReport);
TestReports testReport = new TestReports(reportFilterList, Context.now(), "", new ArrayList<>(), this.issuesIdsForReport);
InsertOneResult insertTResult = TestReportsDao.instance.insertOne(testReport);
this.generatedReportId = insertTResult.getInsertedId().toString();
return SUCCESS.toUpperCase();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,8 @@ const VulnerabilityReport = () => {
else {
// Download the PDF
try {
const byteCharacters = atob(pdf);
const stringPdf = pdf.join('')
const byteCharacters = atob(stringPdf);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
margin: auto 5vw;
height: auto;
}

.Polaris-Frame-ToastManager {
display: none !important;
}
}

.report-header-css {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,19 @@ public class TestReports {
public static final String PDF_REPORT_STRING = "pdfReportString";
private String pdfReportString;

public static final String PDF_REPORT_STRING_CHUNKS = "pdfReportStringChunks";
private List<String> pdfReportStringChunks;

public static final String ISSUE_IDS_FOR_REPORT = "issuesIdsForReport";
private List<TestingIssuesId> issuesIdsForReport;

public TestReports () {}

public TestReports (Map<String, List<String>> filtersForReport, int timestamp, String pdfReportString, List<TestingIssuesId> issuesIdsForReport){
public TestReports (Map<String, List<String>> filtersForReport, int timestamp, String pdfReportString, List<String> pdfReportStringChunks, List<TestingIssuesId> issuesIdsForReport){
this.filtersForReport = filtersForReport;
this.timestamp = timestamp;
this.pdfReportString = pdfReportString;
this.pdfReportStringChunks = pdfReportStringChunks;
this.issuesIdsForReport = issuesIdsForReport;
}

Expand Down Expand Up @@ -60,4 +64,12 @@ public List<TestingIssuesId> getIssuesIdsForReport() {
public void setIssuesIdsForReport(List<TestingIssuesId> issuesIdsForReport) {
this.issuesIdsForReport = issuesIdsForReport;
}

public List<String> getPdfReportStringChunks() {
return pdfReportStringChunks;
}

public void setPdfReportStringChunks(List<String> pdfReportStringChunks) {
this.pdfReportStringChunks = pdfReportStringChunks;
}
}

0 comments on commit 0516db5

Please sign in to comment.