Skip to content
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
45 changes: 44 additions & 1 deletion WebContent/WEB-INF/jsp/assessment/Finalize.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,34 @@
<s:if test="prEnabled">
<bs:button color="warning" size="md" colsize="3" text="Submit for Peer Review" id="prsubmit"></bs:button>
</s:if>
<bs:button color="primary" size="md" colsize="3" text="Download Report" id="dlreport"></bs:button>
<s:if test="assessment.finalReport.effectiveVariants.size() > 1">
<div class="col-md-3">
<div class="btn-group" style="width:100%">
<button type="button" class="btn btn-block btn-primary btn-md dropdown-toggle" data-toggle="dropdown">
Download Report <span class="caret"></span>
</button>
<ul class="dropdown-menu" style="width:100%; background-color:#192338; border-color:#0f1a2b;">
<li><a href="DownloadReport?aid=<s:property value="assessment.id"/>&format=docx" target="_blank" rel="noopener noreferrer" style="color:#fff;">Word (.docx)</a></li>
<li><a href="DownloadReport?aid=<s:property value="assessment.id"/>&format=pdf" target="_blank" rel="noopener noreferrer" style="color:#fff;">PDF</a></li>
<li><a href="DownloadReport?aid=<s:property value="assessment.id"/>&format=encryptedpdf" target="_blank" rel="noopener noreferrer" style="color:#fff;">Encrypted PDF</a></li>
</ul>
</div>
<s:if test="reportPassword != null && reportPassword != ''">
<div class="input-group input-group-sm" style="margin-top:8px;">
<input type="password" id="reportPasswordField" class="form-control" value="<s:property value="reportPassword"/>" readonly>
<span class="input-group-btn">
<button class="btn btn-default" type="button" id="toggleReportPassword">
<i class="fa fa-eye"></i>
</button>
</span>
</div>
<small class="text-muted">Report encryption password</small>
</s:if>
</div>
</s:if>
<s:else>
<bs:button color="primary" size="md" colsize="3" text="Download Report" id="dlreport"></bs:button>
</s:else>
<bs:button color="danger" size="md" colsize="3" text="Finalize Assessment" id="finalize"></bs:button>
</s:if>
</s:if>
Expand Down Expand Up @@ -157,6 +184,22 @@
</bs:mco>
</bs:row>

<script>
$(document).ready(function() {
$("#toggleReportPassword").click(function() {
var field = $("#reportPasswordField");
var icon = $(this).find("i");
if (field.attr("type") === "password") {
field.attr("type", "text");
icon.removeClass("fa-eye").addClass("fa-eye-slash");
} else {
field.attr("type", "password");
icon.removeClass("fa-eye-slash").addClass("fa-eye");
}
});
});
</script>

<!-- Upload Report Modal -->
<div class="modal fade" id="uploadReportModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
Expand Down
13 changes: 0 additions & 13 deletions WebContent/WEB-INF/jsp/cms/TemplateUpload.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,6 @@
</bs:select>
</bs:row>
<bs:row>
<bs:select name="Result File Type" colsize="12" id="fileType">
<s:iterator value="fileTypes" var="fileType">
<s:if test="#fileType.equals(selectedTemplate.fileType)" >
<option value="${fileType }" selected="selected">${fileType}</option>
</s:if>
<s:else>
<option value="${fileType }">${fileType}</option>

</s:else>
</s:iterator>
</bs:select>
</bs:row>
<bs:row>
<form enctype="multipart/form-data" action="cms" id="imgForm" method="POST" style="display:none">
<input type="hidden" id="id" value="${id}" name="id"/>
<input type="hidden" id="action" value="templateSave" name="action"/>
Expand Down
14 changes: 10 additions & 4 deletions WebContent/WEB-INF/jsp/remediation/notesForm.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,19 @@
<s:else>
<tr>
</s:else>
<td><s:property value="appName"/> - <s:property value="appType"/> <s:if test="retest == true">Retest</s:if> Report.docx</td>
<td><s:property value="appName"/> - <s:property value="appType"/> <s:if test="retest == true">Retest</s:if> Report</td>
<td><s:property value="appType"/> <s:if test="retest == true">Retest</s:if></td>
<td><s:date name="gentime" format="MM-dd-yyyy hh:mm:ss"/></td>
<td>
<span class="vulnControl downloadReport" data-guid="<s:property value="filename"/>">
<i class="fa fa-download"></i>
</span>
<s:if test="#r.variantCount > 1">
<a class="vulnControl" style="display:block" href="DownloadReport?guid=<s:property value="#r.filename"/>&format=docx" target="_blank" rel="noopener noreferrer">DOCX</a>
<a class="vulnControl" style="display:block" href="DownloadReport?guid=<s:property value="#r.filename"/>&format=pdf" target="_blank" rel="noopener noreferrer">PDF</a>
</s:if>
<s:else>
<a class="vulnControl" href="DownloadReport?guid=<s:property value="#r.filename"/>" target="_blank" rel="noopener noreferrer">
<i class="fa fa-download"></i>
</a>
</s:else>
<s:if test="retest == true">
<span class="vulnControl genReport" >
<i class="fa fa-arrows-rotate"></i>
Expand Down
12 changes: 9 additions & 3 deletions WebContent/WEB-INF/jsp/retests/Verification.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,15 @@
</s:else>
<td><s:date name="gentime" format="MM-dd-yyyy hh:mm:ss"/></td>
<td>
<span class="vulnControl downloadReport" data-guid="<s:property value="filename"/>">
<i class="fa fa-download"></i>
</span>
<s:if test="#r.variantCount > 1">
<a class="vulnControl" style="display:block" href="DownloadReport?guid=<s:property value="#r.filename"/>&format=docx" target="_blank" rel="noopener noreferrer">DOCX</a>
<a class="vulnControl" style="display:block" href="DownloadReport?guid=<s:property value="#r.filename"/>&format=pdf" target="_blank" rel="noopener noreferrer">PDF</a>
</s:if>
<s:else>
<a class="vulnControl" href="DownloadReport?guid=<s:property value="#r.filename"/>" target="_blank" rel="noopener noreferrer">
<i class="fa fa-download"></i>
</a>
</s:else>
</td>
</tr>
</s:iterator>
Expand Down
1 change: 0 additions & 1 deletion WebContent/src/cms/cms.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ $(function(){
data+="&name=" + $("#name").val();
data+="&teamid="+$("#team").val();
data+="&typeid="+$("#type").val();
data+="&reportExtension="+$("#fileType").val();
data+="&retest="+$("#retest").is(':checked');
$.post("cms",data).done(function(resp){
if(resp.result == "success"){
Expand Down
4 changes: 0 additions & 4 deletions WebContent/src/remediation/remediation_schedule.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,6 @@ function getSelectedSeverity(){
}
//actions
$(function() {
$(".downloadReport").on('click', function(event){
const guid = $(this).data("guid");
window.open(`DownloadReport?guid=${guid}`, "_blank");
});
let checkStatus = {};
$(".genReport").click(function() {
$("#retestRow").html("<td colspan='4'><div class='throbber-loader'>Loading…</div></td>");
Expand Down
4 changes: 0 additions & 4 deletions WebContent/src/retests/verification.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,6 @@ function downloadFile(id) {
$(function() {
getFiles()

$(".downloadReport").on('click', function(event){
const guid = $(this).data("guid");
window.open(`DownloadReport?guid=${guid}`, "_blank");
})

$("#save").click(function() {
let pass = $('input:radio[name=r3]:checked').val();
Expand Down
9 changes: 5 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.faction</groupId>
<artifactId>faction</artifactId>
<version>1.8.7-SNAPSHOT</version>
<version>1.8.8-SNAPSHOT</version>
<packaging>war</packaging>
<name>Faction</name>
<scm>
<url>https://github.com/factionsecurity/faction.git</url>
<connection>scm:git:https://github.com/factionsecurity/faction.git</connection>
<developerConnection>
scm:git:https://github.com/factionsecurity/faction.git</developerConnection>
<tag>1.8.3</tag>
<tag>HEAD</tag>
</scm>
<properties>
<aws.java.sdk.version>2.18.16</aws.java.sdk.version>
<lombok.version>1.18.38</lombok.version>
<project.scm.id>faction-web</project.scm.id>
<github.global.server>github</github.global.server>
</properties>
Expand Down Expand Up @@ -55,7 +56,7 @@
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
<source>8</source>
Expand Down Expand Up @@ -478,7 +479,7 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
4 changes: 2 additions & 2 deletions src/com/faction/reporting/ReportFeatures.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ public class ReportFeatures {
return report;
}

public static String [] getReportOptions() {
return new String[] {"docx"};
public static byte[] encryptPdf(byte[] pdfBytes, String password) throws Exception {
return pdfBytes;
}

public static Boolean allowSections(){
Expand Down
57 changes: 45 additions & 12 deletions src/com/fuse/actions/Reports.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
package com.fuse.actions;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import com.opensymphony.xwork2.interceptor.annotations.Before;

import com.faction.reporting.ReportFeatures;
import com.fuse.dao.Assessment;
import com.fuse.dao.AuditLog;
import com.fuse.dao.FinalReport;
import com.fuse.dao.FinalReportVariant;
import com.fuse.dao.User;
import com.fuse.dao.Verification;
import com.fuse.dao.Vulnerability;
import com.fuse.dao.query.AssessmentQueries;
import com.fuse.reporting.GenerateReport;
import com.fuse.tasks.ReportGenThread;
import com.fuse.tasks.TaskQueueExecutor;
import com.fuse.utils.FSUtils;
import com.opensymphony.xwork2.interceptor.annotations.Before;

import java.util.GregorianCalendar;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import lombok.Setter;

@Namespace("/portal")
public class Reports extends FSActionSupport {
Expand All @@ -39,6 +44,8 @@ public class Reports extends FSActionSupport {
private String filename;
private String contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
private String guid;
@Setter
private String format;
private InputStream reportStream;

@Before(priority = 1)
Expand Down Expand Up @@ -180,13 +187,13 @@ public String downloadReport() {

} else {
finalreport = assessment.getFinalReport();
b64Rpt = finalreport.getBase64EncodedPdf();
b64Rpt = selectVariant(finalreport).getBase64Content();
}
} else if (guid != null) {

finalreport = (FinalReport) em.createQuery("from FinalReport where filename = :guid")
.setParameter("guid", guid).getResultList().stream().findFirst().orElse(null);
b64Rpt = finalreport.getBase64EncodedPdf();
b64Rpt = selectVariant(finalreport).getBase64Content();

} else {
return ERROR;
Expand Down Expand Up @@ -220,7 +227,18 @@ public String downloadReport() {
if(report.length > 3 && report[1] == (byte)'P' && report[2] == (byte)'D' && report[3] == (byte)'F') {
contentType = "application/pdf";
filename +="pdf";

if ("encryptedpdf".equals(format)) {
if (finalreport == null || finalreport.getEncryptedReportPassword() == null) {
System.err.println("DownloadReport: encrypted PDF requested but no report password set for report id=" + (finalreport != null ? finalreport.getId() : "null"));
return ERROR;
}
String password = FSUtils.decryptPassword(finalreport.getEncryptedReportPassword());
if (password == null || password.isEmpty()) {
System.err.println("DownloadReport: failed to decrypt report password for report id=" + finalreport.getId());
return ERROR;
}
report = ReportFeatures.encryptPdf(report, password);
}
}else {
filename +="docx";
}
Expand Down Expand Up @@ -293,5 +311,20 @@ public InputStream getReportStream() {
return this.reportStream;
}


private FinalReportVariant selectVariant(FinalReport fr) {
List<FinalReportVariant> variants = fr.getEffectiveVariants();
if (format != null && !format.isEmpty()) {
String lookupFormat = "encryptedpdf".equals(format) ? "pdf" : format;
return variants.stream()
.filter(v -> lookupFormat.equals(v.getFileType()))
.findFirst()
.orElse(variants.get(0));
}
// Default: prefer PDF if available (preserves prior enterprise behavior),
// otherwise return the first available variant.
return variants.stream()
.filter(v -> "pdf".equals(v.getFileType()))
.findFirst()
.orElse(variants.get(0));
}
}
14 changes: 0 additions & 14 deletions src/com/fuse/actions/admin/CMS.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ public class CMS extends FSActionSupport {
private String file_dataContentType;
private String file_dataFilename;
private String message;
private String reportExtension;
private List<List<String>> reportSections = new ArrayList<>();
private String reportSection;
private InputStream templateStream;
Expand Down Expand Up @@ -201,11 +200,6 @@ public String execute() throws IOException {
selectedTemplate.setTeam(team);
selectedTemplate.setType(type);
selectedTemplate.setRetest(retest);
if(Arrays.asList(ReportFeatures.getReportOptions()).stream().anyMatch(this.reportExtension::equals)) {
selectedTemplate.setFileType(this.reportExtension);
}else {
selectedTemplate.setFileType("docx");
}
}
HibHelper.getInstance().preJoin();
em.joinTransaction();
Expand Down Expand Up @@ -584,14 +578,6 @@ public String getMessage() {
return message;
}

public void setReportExtension(String reportExtension) {
this.reportExtension = reportExtension;

}
public List<String> getFileTypes(){
return Arrays.asList(ReportFeatures.getReportOptions());
}

public Boolean getSectionsEnabled() {
return ReportFeatures.allowSections();
}
Expand Down
Loading
Loading