Skip to content

Commit

Permalink
Merge pull request #481 from rushk014/vul-report
Browse files Browse the repository at this point in the history
  • Loading branch information
BinX-Suse authored Aug 17, 2023
2 parents 65c3ed6 + 7d57c2a commit f033b0b
Show file tree
Hide file tree
Showing 14 changed files with 499 additions and 76 deletions.
7 changes: 7 additions & 0 deletions admin/webapp/websrc/app/common/types/common/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ export type ScannerAutoscaleStrategy =

export type DataOps = 'add' | 'edit' | 'delete';

export type LastModifiedDateOption =
| 'all'
| 'twoweeks'
| 'onemonth'
| 'threemonths'
| 'custom';

export interface ErrorResponse {
code: number;
error: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<div class="d-flex align-items-center justify-content-between">
<h4 mat-dialog-title class="mb-2">
{{ 'scan.report.PRINT_REPORT' | translate }} ({{ data.pdf_name }})
</h4>
<button
(click)="onNoClick()"
class="mb-2"
aria-label="Close dialog"
mat-icon-button>
<i class="eos-icons">close</i>
</button>
</div>
<hr class="fancy" />
<form (ngSubmit)="submit()" [formGroup]="form">
<div class="last_modified_field">
<mat-icon
aria-hidden="false"
aria-label="Modified icon"
class="mr-3 last_modified_icon"
fontSet="fa"
fontIcon="fa-calendar-times">
</mat-icon>
<mat-form-field appearance="standard">
<mat-label>{{ 'scan.LAST_MODIFIED' | translate }}</mat-label>
<mat-select
formControlName="dateOption"
(selectionChange)="changeDateOption(selectedDateOption)">
<mat-option
*ngFor="let modifiedDateOption of dateOptions"
[value]="modifiedDateOption">
{{
'scan.report.from.' + modifiedDateOption.toUpperCase() | translate
}}
</mat-option>
</mat-select>
</mat-form-field>
<ng-container *ngIf="selectedDateOption === 'custom'">
<mat-form-field appearance="standard" class="ml-2">
<input matInput [matDatepicker]="picker" formControlName="customDate" />
<mat-hint>MM/DD/YYYY</mat-hint>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
</ng-container>
</div>
<div class="d-flex justify-content-end">
<app-loading-button
[disabled]="form.invalid || !!(saving$ | async)"
[loading]="!!(saving$ | async)"
[text]="'general.SUBMIT' | translate"
appearance="mat-raised-button"
buttonClasses="mr-1"
color="primary"
id="pdf-generation-dialog-submit"
type="submit">
</app-loading-button>
</div>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.last_modified_field {
display: flex;
justify-content: flex-start;
align-items: center;
overflow: hidden;
}

.last_modified_icon {
color: white;
background-color: #30ba78;
border-radius: 100%;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { PdfGenerationDialogComponent } from './pdf-generation-dialog.component';

describe('PdfGenerationDialogComponent', () => {
let component: PdfGenerationDialogComponent;
let fixture: ComponentFixture<PdfGenerationDialogComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PdfGenerationDialogComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(PdfGenerationDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
Inject,
OnInit,
Output,
} from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Subject } from 'rxjs';
import { VulnerabilitiesComponent } from '../vulnerabilities.component';
import { LastModifiedDateOption } from '@common/types';

const today = new Date();

@Component({
selector: 'app-pdf-generation-dialog',
templateUrl: './pdf-generation-dialog.component.html',
styleUrls: ['./pdf-generation-dialog.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PdfGenerationDialogComponent implements OnInit {
dateOptions: LastModifiedDateOption[] = [
'all',
'twoweeks',
'onemonth',
'threemonths',
'custom',
];
form = new FormGroup({
dateOption: new FormControl('none'),
customDate: new FormControl(
{
value: null,
disabled: true,
},
Validators.required
),
});
saving$ = new Subject();
get customDate(): Date {
return this.form.get('customDate')?.value;
}
get selectedDateOption(): LastModifiedDateOption {
return this.form.get('dateOption')?.value;
}

constructor(
public dialogRef: MatDialogRef<VulnerabilitiesComponent>,
@Inject(MAT_DIALOG_DATA) public data: any
) {}

ngOnInit(): void {}

onNoClick(): void {
this.dialogRef.close();
}

@Output() submitDate = new EventEmitter();
submit(): void {
this.saving$.next(true);
this.submitDate.emit(
this.getDate(this.selectedDateOption, this.customDate)
);
}

changeDateOption(selectedDateOption: LastModifiedDateOption) {
if (selectedDateOption === 'custom') {
this.form.controls['customDate'].enable();
} else {
this.form.controls['customDate'].disable();
}
}

getDate(dateOption: LastModifiedDateOption, customDate: Date): Date | null {
switch (dateOption) {
case 'all':
return null;
case 'twoweeks':
return new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() - 14
);
case 'onemonth':
return new Date(
today.getFullYear(),
today.getMonth() - 1,
today.getDate()
);
case 'threemonths':
return new Date(
today.getFullYear(),
today.getMonth() - 3,
today.getDate()
);
case 'custom':
return customDate;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import { VulnerabilitiesCsvService } from './csv-generation/vulnerabilities-csv.
import { MultiClusterService } from '@services/multi-cluster.service';
import { VulnerabilitiesFilterService } from './vulnerabilities.filter.service';
import { MapConstant } from '@common/constants/map.constant';
import { MatDialog } from '@angular/material/dialog';
import { PdfGenerationDialogComponent } from './pdf-generation-dialog/pdf-generation-dialog.component';
import { VulnerabilityAsset } from '@common/types';
import { TranslateService } from '@ngx-translate/core';

@Component({
selector: 'app-vulnerabilities',
Expand Down Expand Up @@ -32,7 +36,9 @@ export class VulnerabilitiesComponent {
private vulnerabilitiesService: VulnerabilitiesService,
private vulnerabilitiesCsvService: VulnerabilitiesCsvService,
private multiClusterService: MultiClusterService,
public vulnerabilitiesFilterService: VulnerabilitiesFilterService
public vulnerabilitiesFilterService: VulnerabilitiesFilterService,
private dialog: MatDialog,
private tr: TranslateService
) {
//refresh the page when it switched to a remote cluster
this._switchClusterSubscription =
Expand All @@ -56,7 +62,7 @@ export class VulnerabilitiesComponent {
}

printVulnerabilityPDF() {
this.vulnerabilitiesList = this.getFilteredVulnerabilities();
this.advFilter = this.vulnerabilitiesFilterService.advFilter;
this.statisticCharts = {
node: (
document.getElementById('vulnNodesBarPDF') as HTMLCanvasElement
Expand All @@ -65,46 +71,108 @@ export class VulnerabilitiesComponent {
document.getElementById('vulnImagesBarPDF') as HTMLCanvasElement
).toDataURL(),
};
this.isPrinting = true;
setInterval(() => {
if (this.printableReportView) {
window.print();
this.isPrinting = false;
}
}, 500);
if (this.advFilter.modified_dt) {
this.vulnerabilitiesList = this.getFilteredVulnerabilities();
this.isPrinting = true;
setInterval(() => {
if (this.printableReportView) {
window.print();
this.isPrinting = false;
}
}, 500);
} else {
const dialogRef = this.dialog.open(PdfGenerationDialogComponent, {
width: '550px',
data: {
pdf_name: this.tr.instant('scan.report.PDF_LINK'),
},
});
dialogRef.componentInstance.submitDate.subscribe(date => {
if (date) {
this.vulnerabilitiesList = this.getFilteredVulnerabilities(
date.getTime() / 1000
);
} else {
this.vulnerabilitiesList = this.getFilteredVulnerabilities();
}
dialogRef.componentInstance.saving$.next(false);
dialogRef.componentInstance.onNoClick();
this.isPrinting = true;
setInterval(() => {
if (this.printableReportView) {
window.print();
this.isPrinting = false;
}
}, 500);
});
}
}

printAssetsPDF() {
this.advFilter = this.vulnerabilitiesFilterService.advFilter;
this.masterData = {
workloadMap4Pdf: this.vulnerabilitiesService.workloadMap4Pdf,
hostMap4Pdf: this.vulnerabilitiesService.hostMap4Pdf,
platformMap4Pdf: this.vulnerabilitiesService.platformMap4Pdf,
imageMap4Pdf: this.vulnerabilitiesService.imageMap4Pdf,
};
this.vulnerabilitiesList = this.getFilteredVulnerabilities();
this.isFiltered = this.vulnerabilitiesFilterService.filtered;
this.advFilter = this.vulnerabilitiesFilterService.advFilter;

this.masterGrids = this.prepareDetails(
this.masterData,
this.vulnerabilitiesList,
this.isFiltered,
this.advFilter
);

this.isPrintingAssets = true;
setInterval(() => {
if (this.printableReportViewAssets) {
window.print();
this.isPrintingAssets = false;
}
}, 500);
if (this.advFilter.modified_dt) {
this.vulnerabilitiesList = this.getFilteredVulnerabilities();
this.masterGrids = this.prepareDetails(
this.masterData,
this.vulnerabilitiesList,
this.isFiltered,
this.advFilter
);
this.isPrintingAssets = true;
setInterval(() => {
if (this.printableReportViewAssets) {
window.print();
this.isPrintingAssets = false;
}
}, 500);
} else {
const dialogRef = this.dialog.open(PdfGenerationDialogComponent, {
width: '550px',
data: {
pdf_name: this.tr.instant('scan.report.PDF_LINK2'),
},
});
dialogRef.componentInstance.submitDate.subscribe(date => {
if (date) {
this.vulnerabilitiesList = this.getFilteredVulnerabilities(
date.getTime() / 1000
);
} else {
this.vulnerabilitiesList = this.getFilteredVulnerabilities();
}
this.masterGrids = this.prepareDetails(
this.masterData,
this.vulnerabilitiesList,
this.isFiltered,
this.advFilter
);
dialogRef.componentInstance.saving$.next(false);
dialogRef.componentInstance.onNoClick();
this.isPrintingAssets = true;
setInterval(() => {
if (this.printableReportViewAssets) {
window.print();
this.isPrintingAssets = false;
}
}, 500);
});
}
}

private getFilteredVulnerabilities = () => {
private getFilteredVulnerabilities = (lastTimestamp?: number) => {
let vulnerabilitiesList: any[] = [];
this.vulnerabilitiesService.gridApi.forEachNodeAfterFilter(rowNode => {
vulnerabilitiesList.push(rowNode.data);
let vul: VulnerabilityAsset = rowNode.data;
if (!lastTimestamp || vul.last_modified_timestamp > lastTimestamp) {
vulnerabilitiesList.push(vul);
}
});
this.isMeetingReportLimit =
vulnerabilitiesList.length > MapConstant.SEC_RISK_REPORT_MAX_ROW;
Expand Down
Loading

0 comments on commit f033b0b

Please sign in to comment.