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

feat: enhance PDF report handling by supporting multiple chunks and u… #1986

Closed
wants to merge 1 commit into from
Closed
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
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;
}
}
Loading