Skip to content

Commit

Permalink
Merge pull request #178 from softrams/177
Browse files Browse the repository at this point in the history
Assessment Deletion Feature
  • Loading branch information
skewled committed Aug 2, 2020
2 parents ef85dd0 + 116c0fc commit 822774c
Show file tree
Hide file tree
Showing 10 changed files with 392 additions and 246 deletions.
8 changes: 8 additions & 0 deletions frontend/src/app/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ export class AppService {
});
}

/**
* Delete assessment by ID
* @returns success/error message
*/
deleteAssessment(assessmentId: number) {
return this.http.delete(`${this.api}/assessment/${assessmentId}`);
}

/**
* Function is responsible for returning all vulnerabilites related to an assessment
* @param assessmentId is the ID associated with the assessment
Expand Down
10 changes: 7 additions & 3 deletions frontend/src/app/assessments/assessments.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@
style="margin-right: 10px;" data-toggle="tooltip" data-placement="bottom" title="Edit Assessment">
<fa-icon [icon]="faPencilAlt"></fa-icon>
</button>
<button class="btn btn-primary" type="button" (click)="navigateToVulnerability(assessment.id)"
data-toggle="tooltip" data-placement="bottom" title="View Vulnerabilities">
<button style="margin-right: 10px;" class="btn btn-primary" type="button"
(click)="navigateToVulnerability(assessment.id)" data-toggle="tooltip" data-placement="bottom"
title="View Vulnerabilities">
<fa-icon [icon]="faHaykal"></fa-icon>
</button>
<button (click)="deleteAssessment(assessment)" class="btn btn-dark" type="button">
<fa-icon [icon]="faTrash"></fa-icon>
</button>
</td>
</tr>
</tbody>
Expand All @@ -40,4 +44,4 @@
style="margin-right: 5px;" data-toggle="tooltip" data-placement="bottom" title="Back to Organization">
Back to Organization
</button>
</div>
</div>
49 changes: 42 additions & 7 deletions frontend/src/app/assessments/assessments.component.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
import { Component, OnInit } from '@angular/core';
import { AppService } from '../app.service';
import { AlertService } from '../alert/alert.service';
import { ActivatedRoute, Router } from '@angular/router';
import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
import { faHaykal } from '@fortawesome/free-solid-svg-icons';
import { faTrash } from '@fortawesome/free-solid-svg-icons';
import { Assessment } from '../assessment-form/Assessment';

@Component({
selector: 'app-assessments',
templateUrl: './assessments.component.html',
styleUrls: ['./assessments.component.sass']
styleUrls: ['./assessments.component.sass'],
})
export class AssessmentsComponent implements OnInit {
assessmentAry: any = [];
assetId: number;
orgId: number;
faPencilAlt = faPencilAlt;
faHaykal = faHaykal;

constructor(public activatedRoute: ActivatedRoute, public router: Router) {}
faTrash = faTrash;
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public appService: AppService,
public alertService: AlertService
) {}

ngOnInit() {
this.activatedRoute.data.subscribe(({ assessments }) => (this.assessmentAry = assessments));
this.activatedRoute.data.subscribe(
({ assessments }) => (this.assessmentAry = assessments)
);
this.activatedRoute.params.subscribe((params) => {
this.assetId = params.assetId;
this.orgId = params.orgId;
Expand All @@ -31,7 +41,9 @@ export class AssessmentsComponent implements OnInit {
* @param id of vulnerability to load
*/
navigateToVulnerability(id: number) {
this.router.navigate([`organization/${this.orgId}/asset/${this.assetId}/assessment/${id}/vulnerability`]);
this.router.navigate([
`organization/${this.orgId}/asset/${this.assetId}/assessment/${id}/vulnerability`,
]);
}

/**
Expand All @@ -46,7 +58,9 @@ export class AssessmentsComponent implements OnInit {
* Function responsible for directing the user to the main Assessment view
*/
navigateToAssessment() {
this.router.navigate([`organization/${this.orgId}/asset/${this.assetId}/assessment`]);
this.router.navigate([
`organization/${this.orgId}/asset/${this.assetId}/assessment`,
]);
}

/**
Expand All @@ -55,6 +69,27 @@ export class AssessmentsComponent implements OnInit {
* @param assessmentId is the ID associated to the assessment to load
*/
navigateToAssessmentById(assessmentId: number) {
this.router.navigate([`organization/${this.orgId}/asset/${this.assetId}/assessment/${assessmentId}`]);
this.router.navigate([
`organization/${this.orgId}/asset/${this.assetId}/assessment/${assessmentId}`,
]);
}

/**
* Delete assessment by ID
* ID
* @param assessmentId is the ID associated to the assessment to load
*/
deleteAssessment(assessment: Assessment) {
const r = confirm(`Delete the assessment "${assessment.name}"`);
if (r === true) {
this.appService
.deleteAssessment(assessment.id)
.subscribe((success: string) => {
this.alertService.success(success);
this.appService
.getAssessments(this.orgId)
.then((res) => (this.assessmentAry = res));
});
}
}
}
20 changes: 6 additions & 14 deletions frontend/src/app/vulnerability/vulnerability.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,11 @@
<a target="_blank" [href]="vuln?.jiraId">{{ vuln?.jiraId }}</a>
<td>{{ vuln?.status }}</td>
<td>
<button
(click)="navigateToVulnerabilityFormById(vuln.id)"
class="btn btn-secondary"
type="button"
style="margin-right: 10px;"
>
<button (click)="navigateToVulnerabilityFormById(vuln.id)" class="btn btn-secondary" type="button"
style="margin-right: 10px;">
<fa-icon [icon]="faPencilAlt"></fa-icon>
</button>
<button (click)="deleteVuln(vuln)" class="btn btn-primary" type="button">
<button (click)="deleteVuln(vuln)" class="btn btn-dark" type="button">
<fa-icon [icon]="faTrash"></fa-icon>
</button>
</td>
Expand All @@ -41,12 +37,8 @@
<button (click)="navigateToReport()" type="button" class="btn btn-info float-right" style="margin-right: 5px">
Preview Report
</button>
<button
(click)="navigateToAssessments()"
type="button"
class="btn btn-secondary float-right"
style="margin-right: 5px"
>
<button (click)="navigateToAssessments()" type="button" class="btn btn-secondary float-right"
style="margin-right: 5px">
Back to Assessments
</button>
</div>
</div>
30 changes: 21 additions & 9 deletions frontend/src/app/vulnerability/vulnerability.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
import { faTrash } from '@fortawesome/free-solid-svg-icons';
import { Vulnerability } from '../vuln-form/Vulnerability';
import { AppService } from '../app.service';
import { AlertService } from '../alert/alert.service';

@Component({
selector: 'app-vulnerability',
templateUrl: './vulnerability.component.html',
styleUrls: ['./vulnerability.component.sass']
styleUrls: ['./vulnerability.component.sass'],
})
export class VulnerabilityComponent implements OnInit {
vulnAry: any = [];
Expand All @@ -18,10 +19,17 @@ export class VulnerabilityComponent implements OnInit {
faPencilAlt = faPencilAlt;
faTrash = faTrash;

constructor(public activatedRoute: ActivatedRoute, public router: Router, public appService: AppService) {}
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public appService: AppService,
public alertService: AlertService
) {}

ngOnInit() {
this.activatedRoute.data.subscribe(({ vulnerabilities }) => (this.vulnAry = vulnerabilities));
this.activatedRoute.data.subscribe(
({ vulnerabilities }) => (this.vulnAry = vulnerabilities)
);
this.activatedRoute.params.subscribe((params) => {
this.assetId = params.assetId;
this.assessmentId = params.assessmentId;
Expand All @@ -35,7 +43,7 @@ export class VulnerabilityComponent implements OnInit {
*/
navigateToVulnerabilityForm() {
this.router.navigate([
`organization/${this.orgId}/asset/${this.assetId}/assessment/${this.assessmentId}/vuln-form`
`organization/${this.orgId}/asset/${this.assetId}/assessment/${this.assessmentId}/vuln-form`,
]);
}

Expand All @@ -45,7 +53,7 @@ export class VulnerabilityComponent implements OnInit {
*/
navigateToVulnerabilityFormById(vulnId: number) {
this.router.navigate([
`organization/${this.orgId}/asset/${this.assetId}/assessment/${this.assessmentId}/vuln-form/${vulnId}`
`organization/${this.orgId}/asset/${this.assetId}/assessment/${this.assessmentId}/vuln-form/${vulnId}`,
]);
}

Expand All @@ -60,7 +68,9 @@ export class VulnerabilityComponent implements OnInit {
* Function responsible for navigating to report area, takes no params directly
*/
navigateToReport() {
this.router.navigate([`organization/${this.orgId}/asset/${this.assetId}/assessment/${this.assessmentId}/report`]);
this.router.navigate([
`organization/${this.orgId}/asset/${this.assetId}/assessment/${this.assessmentId}/report`,
]);
}

/**
Expand All @@ -71,9 +81,11 @@ export class VulnerabilityComponent implements OnInit {
deleteVuln(vuln: Vulnerability) {
const r = confirm(`Delete the vulnerability "${vuln.name}"`);
if (r === true) {
this.appService.deleteVuln(vuln.id).subscribe((success) => {
// TODO: Success message
this.appService.getVulnerabilities(this.assessmentId).then((res) => (this.vulnAry = res));
this.appService.deleteVuln(vuln.id).subscribe((success: string) => {
this.alertService.success(success);
this.appService
.getVulnerabilities(this.assessmentId)
.then((res) => (this.vulnAry = res));
});
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ const orgController = require('./routes/organization.controller');
const userController = require('./routes/user.controller');
const fileUploadController = require('./routes/file-upload.controller');
import * as assetController from './routes/asset.controller';
const assessmentController = require('./routes/assessment.controller');
import * as assessmentController from './routes/assessment.controller';
const vulnController = require('./routes/vulnerability.controller');
const jwtMiddleware = require('./middleware/jwt.middleware');
import * as jwtMiddleware from './middleware/jwt.middleware';
const puppeteerUtility = require('./utilities/puppeteer.utility');
const helmet = require('helmet');
const cors = require('cors');
Expand Down Expand Up @@ -73,6 +73,7 @@ createConnection().then((_) => {
app.get('/api/assessment/:id', jwtMiddleware.checkToken, assessmentController.getAssessmentsByAssetId);
app.get('/api/assessment/:id/vulnerability', jwtMiddleware.checkToken, assessmentController.getAssessmentVulns);
app.post('/api/assessment', jwtMiddleware.checkToken, assessmentController.createAssessment);
app.delete('/api/assessment/:assessmentId', jwtMiddleware.checkToken, assessmentController.deleteAssessmentById);
app.get(
'/api/asset/:assetId/assessment/:assessmentId',
jwtMiddleware.checkToken,
Expand Down
9 changes: 2 additions & 7 deletions src/middleware/jwt.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import jwt = require('jsonwebtoken');
* @param {Request} req
* @param {Response} res
*/
const checkToken = (req, res, next) => {
export const checkToken = (req, res, next) => {
const token = req.headers.authorization; // Express headers are auto converted to lowercase
if (token) {
jwt.verify(token, process.env.JWT_KEY, (err, decoded) => {
Expand All @@ -26,7 +26,7 @@ const checkToken = (req, res, next) => {
* @param {Request} req
* @param {Response} res
*/
const checkRefreshToken = (req, res, next) => {
export const checkRefreshToken = (req, res, next) => {
const token = req.body.refreshToken;
if (token) {
jwt.verify(token, process.env.JWT_REFRESH_KEY, (err, decoded) => {
Expand All @@ -41,8 +41,3 @@ const checkRefreshToken = (req, res, next) => {
return res.status(401).json('Refresh token not supplied');
}
};

module.exports = {
checkToken,
checkRefreshToken
};
81 changes: 81 additions & 0 deletions src/routes/assessment.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { getConnection } from 'typeorm';
import { Assessment } from '../entity/Assessment';
import { Asset } from '../entity/Asset';
import { Vulnerability } from '../entity/Vulnerability';
import { Organization } from '../entity/Organization';
import { createConnection } from 'typeorm';
import { File } from '../entity/File';
import { User } from '../entity/User';
import { ProblemLocation } from '../entity/ProblemLocation';
import { Resource } from '../entity/Resource';
import MockExpressResponse = require('mock-express-response');
import MockExpressRequest = require('mock-express-request');
import * as assessmentController from './assessment.controller';

describe('Assessment Controller', () => {
beforeEach(async () => {
await createConnection({
type: 'sqlite',
database: ':memory:',
dropSchema: true,
entities: [Asset, Organization, File, Vulnerability, Assessment, User, ProblemLocation, Resource],
synchronize: true,
logging: false,
name: 'default'
});
});
afterEach(() => {
const conn = getConnection('default');
return conn.close();
});
test('Assessment Delete', async () => {
const response = new MockExpressResponse();
const request = new MockExpressRequest({
params: {
assessmentId: 'abc'
}
});
await assessmentController.deleteAssessmentById(request, response);
expect(response.statusCode).toBe(400);
const response2 = new MockExpressResponse();
const request2 = new MockExpressRequest({
params: {
assessmentId: null
}
});
await assessmentController.deleteAssessmentById(request2, response2);
expect(response2.statusCode).toBe(400);
const response3 = new MockExpressResponse();
const request3 = new MockExpressRequest({
params: {
assessmentId: 3
}
});
await assessmentController.deleteAssessmentById(request3, response3);
expect(response3.statusCode).toBe(404);
const assessment: Assessment = {
id: null,
name: 'testAssessment',
executiveSummary: '',
jiraId: '',
testUrl: '',
prodUrl: '',
scope: '',
tag: '',
startDate: new Date(),
endDate: new Date(),
asset: new Asset(),
testers: null,
vulnerabilities: null
};
await getConnection().getRepository(Assessment).insert(assessment);
const response4 = new MockExpressResponse();
const request4 = new MockExpressRequest({
params: {
assessmentId: 1
}
});
await assessmentController.deleteAssessmentById(request4, response4);
expect(response4.statusCode).toBe(200);
});
});
Loading

0 comments on commit 822774c

Please sign in to comment.