Improve vilnerability list UI

Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
AllForNothing 2020-10-23 15:03:33 +08:00
parent eadb65f988
commit 64ddef2e1d
10 changed files with 113 additions and 10 deletions

View File

@ -28,7 +28,7 @@
<clr-dg-column [clrDgField]="'package'">{{'VULNERABILITY.GRID.COLUMN_PACKAGE' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'version'">{{'VULNERABILITY.GRID.COLUMN_VERSION' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'fix_version'">{{'VULNERABILITY.GRID.COLUMN_FIXED' | translate}}</clr-dg-column>
<clr-dg-column *ngIf="isSystemAdmin()">{{'VULNERABILITY.GRID.IN_ALLOW_LIST' | translate}}</clr-dg-column>
<clr-dg-placeholder>
<span *ngIf="hasScanned();else elseBlock">{{'VULNERABILITY.STATE.OTHER_STATUS' | translate}}</span>
<ng-template #elseBlock>
@ -67,6 +67,9 @@
</div>
<ng-template #elseBlock>{{res.fix_version}}</ng-template>
</clr-dg-cell>
<clr-dg-cell *ngIf="isSystemAdmin()">
{{(isInAllowList(res.id)?"TAG_RETENTION.YES":"TAG_RETENTION.NO") | translate}}
</clr-dg-cell>
<clr-dg-row-detail *clrIfExpanded>
{{'VULNERABILITY.GRID.COLUMN_DESCRIPTION' | translate}}: {{res.description}}
</clr-dg-row-detail>

View File

@ -6,11 +6,20 @@ import { AdditionsService } from "../additions.service";
import { of } from "rxjs";
import { TranslateFakeLoader, TranslateLoader, TranslateModule } from "@ngx-translate/core";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { ScanningResultService, UserPermissionService, VulnerabilityItem } from "../../../../../../lib/services";
import {
ProjectService,
ScanningResultService,
SystemInfoService,
UserPermissionService,
VulnerabilityItem
} from "../../../../../../lib/services";
import { AdditionLink } from "../../../../../../../ng-swagger-gen/models/addition-link";
import { ErrorHandler } from "../../../../../../lib/utils/error-handler";
import { ChannelService } from "../../../../../../lib/services/channel.service";
import { DEFAULT_SUPPORTED_MIME_TYPE } from "../../../../../../lib/utils/utils";
import {SessionService} from "../../../../../shared/session.service";
import {SessionUser} from "../../../../../shared/session-user";
import {delay} from "rxjs/operators";
describe('ArtifactVulnerabilitiesComponent', () => {
@ -65,6 +74,34 @@ describe('ArtifactVulnerabilitiesComponent', () => {
}
}
};
const mockedUser: SessionUser = {
user_id: 1,
username: 'admin',
email: 'harbor@vmware.com',
realname: 'admin',
has_admin_role: true,
comment: 'no comment'
};
const fakedSessionService = {
getCurrentUser() {
return mockedUser;
}
};
const fakedProjectService = {
getProject() {
return of({
name: 'test',
metadata: {
reuse_sys_cve_allowlist: "false"
},
cve_allowlist: {
items: [
{cve_id: "123"}
]
}
}).pipe(delay(0));
}
};
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
@ -80,10 +117,13 @@ describe('ArtifactVulnerabilitiesComponent', () => {
declarations: [ArtifactVulnerabilitiesComponent],
providers: [
ErrorHandler,
SystemInfoService,
{provide: AdditionsService, useValue: fakedAdditionsService},
{provide: UserPermissionService, useValue: fakedUserPermissionService},
{provide: ScanningResultService, useValue: fakedScanningResultService},
{provide: ChannelService, useValue: fakedChannelService},
{provide: SessionService, useValue: fakedSessionService},
{provide: ProjectService, useValue: fakedProjectService},
],
schemas: [
NO_ERRORS_SCHEMA
@ -111,4 +151,14 @@ describe('ArtifactVulnerabilitiesComponent', () => {
const rows = fixture.nativeElement.getElementsByTagName('clr-dg-row');
expect(rows.length).toEqual(2);
});
it("should show column 'Listed In CVE Allowlist'", async () => {
fixture.autoDetectChanges(true);
await fixture.whenStable();
const cols = fixture.nativeElement.querySelectorAll("clr-dg-column");
expect(cols).toBeTruthy();
expect(cols.length).toEqual(6);
const firstRow = fixture.nativeElement.querySelector("clr-dg-row");
const cells = firstRow.querySelectorAll("clr-dg-cell");
expect(cells[cells.length - 1].innerText).toEqual("TAG_RETENTION.YES");
});
});

View File

@ -4,8 +4,9 @@ import { ClrDatagridComparatorInterface, ClrLoadingState } from "@clr/angular";
import { finalize } from "rxjs/operators";
import { AdditionLink } from "../../../../../../../ng-swagger-gen/models/addition-link";
import {
ProjectService,
ScannerVo,
ScanningResultService,
ScanningResultService, SystemInfoService,
UserPermissionService,
USERSTATICPERMISSION,
VulnerabilityItem
@ -20,6 +21,7 @@ import { ChannelService } from "../../../../../../lib/services/channel.service";
import { ResultBarChartComponent } from "../../../vulnerability-scanning/result-bar-chart.component";
import { Subscription } from "rxjs";
import { Artifact } from "../../../../../../../ng-swagger-gen/models/artifact";
import {SessionService} from "../../../../../shared/session.service";
@Component({
selector: 'hbr-artifact-vulnerabilities',
@ -53,12 +55,16 @@ export class ArtifactVulnerabilitiesComponent implements OnInit, OnDestroy {
resultBarChartComponent: ResultBarChartComponent;
sub: Subscription;
hasViewInitWithDelay: boolean = false;
currentCVEList: Array<{ "cve_id": string; }> = [];
constructor(
private errorHandler: ErrorHandler,
private additionsService: AdditionsService,
private userPermissionService: UserPermissionService,
private scanningService: ScanningResultService,
private channel: ChannelService,
private session: SessionService,
private projectService: ProjectService,
private systemInfoService: SystemInfoService,
) {
const that = this;
this.severitySort = {
@ -80,6 +86,10 @@ export class ArtifactVulnerabilitiesComponent implements OnInit, OnDestroy {
setTimeout(() => {
this.hasViewInitWithDelay = true;
}, 0);
if (this.isSystemAdmin()) {
// get system and project CVE allow list
this.getCurrentCVEAllowList();
}
}
ngOnDestroy() {
if (this.sub) {
@ -194,4 +204,37 @@ export class ArtifactVulnerabilitiesComponent implements OnInit, OnDestroy {
}
return null;
}
isSystemAdmin(): boolean {
const account = this.session.getCurrentUser();
return account && account.has_admin_role;
}
getCurrentCVEAllowList() {
this.projectService.getProject(this.projectId).subscribe(
projectRes => {
if (projectRes && projectRes.cve_allowlist
&& projectRes.metadata && projectRes.metadata.reuse_sys_cve_allowlist !== "true"
) { // use project CVE allow list
this.currentCVEList = projectRes.cve_allowlist['items'];
} else { // use system CVE allow list
this.systemInfoService.getSystemAllowlist().subscribe(
systemRes => {
if (systemRes && systemRes.items && systemRes.items.length) {
this.currentCVEList = systemRes.items;
}
}
);
}
}
);
}
isInAllowList(CVEId: string): boolean {
if (this.currentCVEList && this.currentCVEList.length) {
for (let i = 0; i < this.currentCVEList.length; i++) {
if (CVEId === this.currentCVEList[i].cve_id) {
return true;
}
}
}
return false;
}
}

View File

@ -1016,7 +1016,8 @@
"COLUMN_FIXED": "Fixed in version",
"COLUMN_DESCRIPTION": "Description",
"FOOT_ITEMS": "Items",
"FOOT_OF": "of"
"FOOT_OF": "of",
"IN_ALLOW_LIST": "Listed In CVE Allowlist"
},
"CHART": {
"SCANNING_TIME": "Scan completed time:",

View File

@ -1016,7 +1016,8 @@
"COLUMN_FIXED": "Fixed in version",
"COLUMN_DESCRIPTION": "Description",
"FOOT_ITEMS": "Items",
"FOOT_OF": "of"
"FOOT_OF": "of",
"IN_ALLOW_LIST": "Listed In CVE Allowlist"
},
"CHART": {
"SCANNING_TIME": "Scan completed time:",

View File

@ -989,7 +989,8 @@
"COLUMN_FIXED": "Fixé dans le version",
"COLUMN_DESCRIPTION": "Description",
"FOOT_ITEMS": "Items",
"FOOT_OF": "de"
"FOOT_OF": "de",
"IN_ALLOW_LIST": "Listed In CVE Allowlist"
},
"CHART": {
"SCANNING_TIME": "Temps d'analyse complète :",

View File

@ -1012,7 +1012,8 @@
"COLUMN_FIXED": "Corrigido na versão",
"COLUMN_DESCRIPTION": "Descrição",
"FOOT_ITEMS": "Itens",
"FOOT_OF": "de"
"FOOT_OF": "de",
"IN_ALLOW_LIST": "Listed In CVE Allowlist"
},
"CHART": {
"SCANNING_TIME": "Tempo de conclusão da análise:",

View File

@ -1016,7 +1016,8 @@
"COLUMN_FIXED": "Sürümde düzeltildi",
"COLUMN_DESCRIPTION": "Açıklama",
"FOOT_ITEMS": "Öğeler",
"FOOT_OF": "of"
"FOOT_OF": "of",
"IN_ALLOW_LIST": "Listed In CVE Allowlist"
},
"CHART": {
"SCANNING_TIME": "Tarama tamamlanma zamanı:",

View File

@ -1016,7 +1016,8 @@
"COLUMN_FIXED": "修复版本",
"COLUMN_DESCRIPTION": "简介",
"FOOT_ITEMS": "项目",
"FOOT_OF": "总共"
"FOOT_OF": "总共",
"IN_ALLOW_LIST": "已入特赦名单"
},
"CHART": {
"SCANNING_TIME": "扫描完成时间:",

View File

@ -1011,7 +1011,8 @@
"COLUMN_FIXED": "修復版本",
"COLUMN_DESCRIPTION": "簡介",
"FOOT_ITEMS": "項目",
"FOOT_OF": "總共"
"FOOT_OF": "總共",
"IN_ALLOW_LIST": "Listed In CVE Allowlist"
},
"CHART":{
"SCANNING_TIME": "掃描完成時間:",