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
11 changes: 11 additions & 0 deletions WebContent/WEB-INF/jsp/assessment/Finalize.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@
</bs:mco>
</s:if>
</bs:row>
<s:if test="assessment.finalized && acadmin">
<bs:row>
<bs:mco colsize="12">
<bs:box type="warning" title="Controls">
<div style="padding-bottom:60px">
<bs:button color="warning" size="md" colsize="3" text="Reopen Assessment" id="reopen"></bs:button>
</div>
</bs:box>
</bs:mco>
</bs:row>
</s:if>
<bs:row>
<bs:mco colsize="12">
<ul class="timeline">
Expand Down
8 changes: 5 additions & 3 deletions WebContent/WEB-INF/jsp/peerreviews/PeerReviews.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
value="created" /></td>
<td><bs:mco colsize="6">
<button class="btn btn-md btn-info" text="Download Report"
onClick="downPdf(${assessment.id})" id="dl${st.count}">
onClick="downloadReport(${assessment.id})" id="dl${st.count}">
<i class='fa fa-download'></i> Download Report
</button>
</bs:mco></td>
Expand All @@ -66,8 +66,10 @@
<script>
var selectedId = -1;

function downPdf(id){
var win = window.open('../portal/DownloadReport?aid='+id, '_blank');
// Peer review always hands back the editable Word document -- the
// reviewer marks it up, so a PDF is no use to them.
function downloadReport(id){
var win = window.open('../portal/DownloadReport?aid='+id+'&format=docx', '_blank');
}
function trackChanges(id){
document.location="TrackChanges?prqueue=true&prid="+id;
Expand Down
80 changes: 70 additions & 10 deletions WebContent/WEB-INF/jsp/retests/Verification.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,36 @@
<bs:row>
<bs:mco colsize="12">
<bs:row>
<bs:mco colsize="6">
<div class="form-group"
style="padding-left: 30px">
<input type="radio" name="r3"
class="flat-green" value="1"> Remediated <br /> <br/><input
type="radio" name="r3" class="flat-red" checked value="0">
Not Remediated
</label>
</div>
</bs:mco>
<bs:mco colsize="6">
<div class="form-group"
style="padding-left: 30px">
<input type="radio" name="r3"
class="flat-green" value="1"> Remediated <br /> <br/><input
type="radio" name="r3" class="flat-red" checked value="0">
Not Remediated
</label>
<br />
<br />
<div id="closeEnvGroup" style="display:none">
<label><u>Close finding in:</u></label><br/>
<label style="font-weight:normal"><input type="radio"
name="closeEnv" value="" checked> Close retest only</label><br/>
<label style="font-weight:normal"><input type="radio"
name="closeEnv" value="dev"> Development</label><br/>
<label style="font-weight:normal"><input type="radio"
name="closeEnv" value="staging"> Staging</label><br/>
<label style="font-weight:normal"><input type="radio"
name="closeEnv" value="prod"> Production</label>
</div>
<div id="failActionGroup" style="display:none">
<label><u>On failure:</u></label><br/>
<label style="font-weight:normal"><input type="radio"
name="failAction" value="close" checked> Close verification</label><br/>
<label style="font-weight:normal"><input type="radio"
name="failAction" value="remediate"> Send to remediation team</label>
</div>
</div>
</bs:mco>
<bs:mco colsize="6">
<bs:button color="primary" size="md" colsize="12"
text="<span class='fa fa-check' ></span> Complete " id="save"></bs:button>
Expand All @@ -112,6 +132,38 @@
</bs:box>
</bs:mco>
</bs:row>
<bs:row>
<bs:mco colsize="12">
<bs:box type="warning"
title="<i class='glyphicon glyphicon-adjust'></i> Severity Adjustment">
<div class="row">
<div class="col-md-4">
<label><u>Current Severity:</u></label><br/>
<span class="severityBox <s:property value="verification.verificationItems[0].vulnerability.overallStr"/>">
<s:property value="verification.verificationItems[0].vulnerability.overallStr"/>
</span>
</div>
<div class="col-md-4">
<label><u>New Severity:</u></label><br/>
<select id="newOverall" name="newOverall" class="form-control">
<s:iterator value="levels" status="stat">
<option value="<s:property value="riskId"/>"
<s:if test="riskId == verification.verificationItems[0].vulnerability.overall">selected="selected"</s:if>>
<s:property value="risk"/>
</option>
</s:iterator>
</select>
</div>
<div class="col-md-4">
<label><u>Annotation (required if changed):</u></label><br/>
<input type="text" id="severityNote" name="severityNote"
class="form-control"
placeholder="Explain why the severity was changed" />
</div>
</div>
</bs:box>
</bs:mco>
</bs:row>
<bs:row>
<bs:mco colsize="6">
<bs:box type="info" title="<i class='fa fa-bug'></i> Scope">
Expand Down Expand Up @@ -204,13 +256,21 @@
const reportName = "${verification.assessment.finalReport.filename}";
const vulnId = "${verification.verificationItems[0].vulnerability.id}";
const verificationId = "${verification.id}";
const originalOverall = "${verification.verificationItems[0].vulnerability.overall}";
$(function() {
$('input[type="radio"].flat-red').iCheck({
radioClass : 'iradio_flat-red'
});
$('input[type="radio"].flat-green').iCheck({
radioClass : 'iradio_flat-green'
});
function toggleCloseEnv() {
var pass = $('input:radio[name=r3]:checked').val();
$("#closeEnvGroup").toggle(pass == '1');
$("#failActionGroup").toggle(pass == '0');
}
$('input[name=r3]').on('ifChecked', toggleCloseEnv);
toggleCloseEnv();
});
let colors = ["#8E44AD", "#9B59B6", "#2C3E50", "#34495E", "#95A5A6", "#00a65a", "#39cccc", "#00c0ef", "#f39c12", "#dd4b39"];
<%int count = 9;%>
Expand Down
2 changes: 1 addition & 1 deletion WebContent/dist/js/overview.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion WebContent/dist/js/verification.js

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions WebContent/src/assessment/overview.js
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,49 @@ $(function() {
cancel: function() { }
}
});
});

$("#reopen").click(function() {
$.confirm({
title: 'Are you sure?',
content: "Reopening this assessment will unfinalize it and return it to the assessment queue. Any closed vulnerabilities will be reopened.",
type: 'orange',
buttons: {
confirm: function() {
$(".content").loading({ overlay: true, base: 0.3 });
var data = "action=reopen";
data += "&id=" + $("#appid")[0].value.replace("app", "");
data += "&_token=" + global._token;
$.post("Assessment", data).done(function(resp) {
global._token = resp.token;
if (resp.result === "success") {
$.alert({
type: "green",
title: 'Success!',
content: "Assessment has been reopened",
buttons: {
ok: function() { location.reload(); }
}
});
} else {
$(".content").loading({ destroy: true });
var error = "";
if (typeof resp.errors == 'undefined')
error = "<br>" + resp.message;
else {
error = resp.errors;
}
$.alert({
type: "red",
title: 'Alert!',
content: error,
});
}
});
},
cancel: function() { }
}
});
});
});

Expand Down
23 changes: 23 additions & 0 deletions WebContent/src/retests/verification.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@ $(function() {
let pass = $('input:radio[name=r3]:checked').val();
let msgText = pass == '1'? "<span style='color:green'>PASS</span>": "<span style='color:red' >FAIL</span>";
let type = pass == '1'? 'green': 'red';

let newOverall = $('#newOverall').val();
let severityNote = $('#severityNote').val().trim();
let severityChanged = newOverall !== originalOverall;
if (severityChanged && severityNote === '') {
$.alert({
title: 'Annotation Required',
content: 'You changed the severity. Please annotate why it was downgraded or raised.',
type: 'orange'
});
return;
}

$.confirm({
title: "Are you sure?",
content: `This will ${msgText} the vulnerability re-test.`,
Expand All @@ -100,6 +113,16 @@ $(function() {
data += `&notes=${encodeURIComponent(editors["failNotes"].getHTML())}`;
data += `&vid=${vulnId}`;
data += `&ver=${verificationId}`;
if (pass == '1') {
data += `&closeEnv=${encodeURIComponent($('input:radio[name=closeEnv]:checked').val() || "")}`;
}
if (pass == '0') {
data += `&failAction=${encodeURIComponent($('input:radio[name=failAction]:checked').val() || "close")}`;
}
if (severityChanged) {
data += `&overall=${encodeURIComponent(newOverall)}`;
data += `&severityNote=${encodeURIComponent(severityNote)}`;
}
$.post("CompleteVerification", data).done( () => {

document.location = "Verifications";
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.faction</groupId>
<artifactId>faction</artifactId>
<version>1.8.11-SNAPSHOT</version>
<version>1.8.12-SNAPSHOT</version>
<packaging>war</packaging>
<name>Faction</name>
<scm>
Expand Down
46 changes: 46 additions & 0 deletions src/com/fuse/actions/assessment/AssessmentView.java
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,12 @@ public String execute() throws NotSupportedException, SystemException {

return finalizeAssessment(em, assessment, user);

} else if (this.action != null && this.action.equals("reopen")) {
if (!this.testToken(false))
return this.ERRORJSON;

return reopenAssessment(em, assessment, user);

} else if (this.update != null && this.update.equals("true")) {
if (!this.testToken(false))
return this.ERRORJSON;
Expand Down Expand Up @@ -950,6 +956,46 @@ private String finalizeAssessment(EntityManager em, Assessment assessment, User
return this.SUCCESSJSON;
}

private String reopenAssessment(EntityManager em, Assessment assessment, User user) {

if (!this.isAcadmin()) {
JSONObject msg = new JSONObject();
msg.put("errors", "Only administrators can reopen a finalized assessment.");
msg.put("token", this.get_token());
this.jsonResponse = msg.toJSONString();
return "finerrorJson";
}

if (!assessment.isFinalized()) {
JSONObject msg = new JSONObject();
msg.put("errors", "Assessment is not finalized.");
msg.put("token", this.get_token());
this.jsonResponse = msg.toJSONString();
return "finerrorJson";
}

assessment.setReopen();
List<Vulnerability> vulns = assessment.getVulns();
for (Vulnerability v : vulns) {
if (v.getStatus() != null && v.getStatus().contains("Closed")) {
v.setStatus(Vulnerability.StatusOpen);
}
}

AssessmentQueries.saveAll(this, assessment, em, "Assessment Reopened",
assessment.getVulns(), assessment);

String email = "<b>Assessment Reopened: " + assessment.getName() + " [ " + assessment.getAppId()
+ " ] </b><br>";
email += "<p>The assessment was reopened by " + user.getFname() + " " + user.getLname() + " on " + new Date()
+ "</p>";
EmailThread emailThread = new EmailThread(assessment,
"Assessment Reopened for " + assessment.getName() + " [ " + assessment.getAppId() + " ]", email);
TaskQueueExecutor.getInstance().execute(emailThread);

return this.SUCCESSJSON;
}

// If we return null here then it means one of two things:
// - No checklists were set up for this assessment
// - The user has completed at least one checklist
Expand Down
Loading
Loading