Skip to content

Commit

Permalink
feat(assessment controller): assessment deletion feature
Browse files Browse the repository at this point in the history
Implemented the ability to delete assessments.  Refactored code in app.ts, jwtMiddleware, and vuln
components.

feat #177
  • Loading branch information
alejandrosaenz117 committed Aug 1, 2020
1 parent ef85dd0 commit b96b977
Show file tree
Hide file tree
Showing 9 changed files with 308 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
};
36 changes: 23 additions & 13 deletions src/routes/assessment.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const userController = require('../routes/user.controller');
* @param {Response} res
* @returns Asset assessments
*/
const getAssessmentsByAssetId = async (req: UserRequest, res: Response) => {
export const getAssessmentsByAssetId = async (req: UserRequest, res: Response) => {
if (!req.params.id) {
return res.status(400).json('Invalid Assessment request');
}
Expand All @@ -38,7 +38,7 @@ const getAssessmentsByAssetId = async (req: UserRequest, res: Response) => {
* @param {Response} res
* @returns assessment vulnerabilities
*/
const getAssessmentVulns = async (req: UserRequest, res: Response) => {
export const getAssessmentVulns = async (req: UserRequest, res: Response) => {
if (!req.params.id) {
return res.status(400).json('Invalid Vulnerability request');
}
Expand All @@ -61,7 +61,7 @@ const getAssessmentVulns = async (req: UserRequest, res: Response) => {
* @param {Response} res c
* @returns success message
*/
const createAssessment = async (req: UserRequest, res: Response) => {
export const createAssessment = async (req: UserRequest, res: Response) => {
if (isNaN(req.body.asset)) {
return res.status(400).json('Asset ID is invalid');
}
Expand Down Expand Up @@ -99,7 +99,7 @@ const createAssessment = async (req: UserRequest, res: Response) => {
* @param {Response} res
* @returns assessment
*/
const getAssessmentById = async (req: UserRequest, res: Response) => {
export const getAssessmentById = async (req: UserRequest, res: Response) => {
if (!req.params.assessmentId) {
return res.status(400).send('Invalid assessment request');
}
Expand All @@ -126,7 +126,7 @@ const getAssessmentById = async (req: UserRequest, res: Response) => {
* @param {Response} res
* @returns success message
*/
const updateAssessmentById = async (req: UserRequest, res: Response) => {
export const updateAssessmentById = async (req: UserRequest, res: Response) => {
if (!req.params.assessmentId) {
return res.status(400).send('Invalid assessment request');
}
Expand Down Expand Up @@ -164,7 +164,7 @@ const updateAssessmentById = async (req: UserRequest, res: Response) => {
* @param {Response} res
* @returns report information
*/
const queryReportDataByAssessment = async (req: UserRequest, res: Response) => {
export const queryReportDataByAssessment = async (req: UserRequest, res: Response) => {
if (!req.params.assessmentId) {
return res.status(400).send('Invalid report request');
}
Expand Down Expand Up @@ -210,11 +210,21 @@ const queryReportDataByAssessment = async (req: UserRequest, res: Response) => {
res.status(200).json(report);
};

module.exports = {
getAssessmentsByAssetId,
getAssessmentVulns,
createAssessment,
getAssessmentById,
updateAssessmentById,
queryReportDataByAssessment
/**
* @description Delete assessment by ID
* @param {UserRequest} req vulnID is required
* @param {Response} res contains JSON object with the success/fail
* @returns success/error message
*/
export const deleteAssessmentById = async (req: UserRequest, res: Response) => {
if (!req.params.assessmentId && isNaN(+req.params.assessmentId)) {
return res.status(400).send('Invalid assessment ID');
}
const assessment = await getConnection().getRepository(Assessment).findOne(req.params.assessmentId);
if (!assessment) {
return res.status(404).send('Assessment does not exist.');
} else {
await getConnection().getRepository(Assessment).delete(assessment);
res.status(200).json(`Assessment #${assessment.id}: "${assessment.name}" successfully deleted`);
}
};
Loading

0 comments on commit b96b977

Please sign in to comment.