mirror of https://github.com/goharbor/harbor.git
refactor based on swagger yaml changes
Signed-off-by: xuelichao <xuel@vmware.com>
This commit is contained in:
parent
7669e3d771
commit
71d4aecc13
|
@ -6776,6 +6776,10 @@ definitions:
|
|||
type: object
|
||||
description: 'The generate SBOM overview information'
|
||||
properties:
|
||||
report_id:
|
||||
type: string
|
||||
description: 'id of the native sbom report'
|
||||
example: '5f62c830-f996-11e9-957f-0242c0a89008'
|
||||
start_time:
|
||||
type: string
|
||||
format: date-time
|
||||
|
@ -6801,10 +6805,6 @@ definitions:
|
|||
format: int64
|
||||
description: 'Time in seconds required to create the report'
|
||||
example: 300
|
||||
complete_percent:
|
||||
type: integer
|
||||
description: 'The complete percent of the scanning which value is between 0 and 100'
|
||||
example: 100
|
||||
scanner:
|
||||
$ref: '#/definitions/Scanner'
|
||||
NativeReportSummary:
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import {
|
||||
DEFAULT_SBOM_SUPPORTED_MIME_TYPES,
|
||||
DEFAULT_SUPPORTED_MIME_TYPES,
|
||||
} from '../../../../../shared/units/utils';
|
||||
import { ScanTypes } from 'src/app/shared/entities/shared.const';
|
||||
import { DEFAULT_SUPPORTED_MIME_TYPES } from '../../../../../shared/units/utils';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
|
@ -16,8 +12,7 @@ export class AdditionsService {
|
|||
getDetailByLink(
|
||||
link: string,
|
||||
shouldSetHeader: boolean,
|
||||
shouldReturnText: boolean,
|
||||
scanType = ScanTypes.VULNERABILITY
|
||||
shouldReturnText: boolean
|
||||
): Observable<any> {
|
||||
if (shouldReturnText) {
|
||||
return this.http.get(link, {
|
||||
|
@ -27,16 +22,9 @@ export class AdditionsService {
|
|||
}
|
||||
if (shouldSetHeader) {
|
||||
return this.http.get(link, {
|
||||
headers:
|
||||
scanType === ScanTypes.SBOM
|
||||
? {
|
||||
'X-Accept-SBOMs':
|
||||
DEFAULT_SBOM_SUPPORTED_MIME_TYPES,
|
||||
}
|
||||
: {
|
||||
'X-Accept-Vulnerabilities':
|
||||
DEFAULT_SUPPORTED_MIME_TYPES,
|
||||
},
|
||||
headers: {
|
||||
'X-Accept-Vulnerabilities': DEFAULT_SUPPORTED_MIME_TYPES,
|
||||
},
|
||||
});
|
||||
}
|
||||
return this.http.get(link);
|
||||
|
|
|
@ -1,76 +1,105 @@
|
|||
<ng-container *ngIf="additionLinks">
|
||||
<h4 class="margin-bottom-025">{{ 'ARTIFACT.ADDITIONS' | translate }}</h4>
|
||||
<div class="min-15">
|
||||
<clr-tabs>
|
||||
<clr-tabs #additionsTab>
|
||||
<clr-tab *ngIf="getVulnerability()">
|
||||
<button clrTabLink id="vulnerability">
|
||||
<button
|
||||
clrTabLink
|
||||
id="vulnerability"
|
||||
(click)="actionTab('vulnerability')">
|
||||
{{ 'REPOSITORY.VULNERABILITY' | translate }}
|
||||
</button>
|
||||
<clr-tab-content id="vulnerability-content" *clrIfActive>
|
||||
<hbr-artifact-vulnerabilities
|
||||
[artifact]="artifact"
|
||||
[projectName]="projectName"
|
||||
[projectId]="projectId"
|
||||
[repoName]="repoName"
|
||||
[digest]="digest"
|
||||
[vulnerabilitiesLink]="
|
||||
getVulnerability()
|
||||
"></hbr-artifact-vulnerabilities>
|
||||
</clr-tab-content>
|
||||
<ng-template
|
||||
[clrIfActive]="currentTabLinkId === 'vulnerability'">
|
||||
<clr-tab-content id="vulnerability-content">
|
||||
<hbr-artifact-vulnerabilities
|
||||
[artifact]="artifact"
|
||||
[projectName]="projectName"
|
||||
[projectId]="projectId"
|
||||
[repoName]="repoName"
|
||||
[digest]="digest"
|
||||
[vulnerabilitiesLink]="
|
||||
getVulnerability()
|
||||
"></hbr-artifact-vulnerabilities>
|
||||
</clr-tab-content>
|
||||
</ng-template>
|
||||
</clr-tab>
|
||||
<clr-tab *ngIf="getSbom()">
|
||||
<button clrTabLink id="sbom">
|
||||
<button clrTabLink id="sbom" (click)="actionTab('sbom')">
|
||||
{{ 'REPOSITORY.SBOM' | translate }}
|
||||
</button>
|
||||
<clr-tab-content id="sbom-content" *clrIfActive>
|
||||
<hbr-artifact-sbom
|
||||
[artifact]="artifact"
|
||||
[projectName]="projectName"
|
||||
[projectId]="projectId"
|
||||
[repoName]="repoName"
|
||||
[sbomDigest]="sbomDigest"
|
||||
[sbomLink]="getSbom()"></hbr-artifact-sbom>
|
||||
</clr-tab-content>
|
||||
<ng-template [clrIfActive]="currentTabLinkId === 'sbom'">
|
||||
<clr-tab-content id="sbom-content">
|
||||
<hbr-artifact-sbom
|
||||
[artifact]="artifact"
|
||||
[projectName]="projectName"
|
||||
[projectId]="projectId"
|
||||
[repoName]="repoName"
|
||||
[sbomDigest]="sbomDigest"></hbr-artifact-sbom>
|
||||
</clr-tab-content>
|
||||
</ng-template>
|
||||
</clr-tab>
|
||||
<clr-tab *ngIf="getBuildHistory()">
|
||||
<button clrTabLink id="build-history">
|
||||
<button
|
||||
clrTabLink
|
||||
id="build-history"
|
||||
(click)="actionTab('build-history')">
|
||||
{{ 'REPOSITORY.BUILD_HISTORY' | translate }}
|
||||
</button>
|
||||
<clr-tab-content *clrIfActive>
|
||||
<hbr-artifact-build-history
|
||||
[buildHistoryLink]="
|
||||
getBuildHistory()
|
||||
"></hbr-artifact-build-history>
|
||||
</clr-tab-content>
|
||||
<ng-template
|
||||
[clrIfActive]="currentTabLinkId === 'build-history'">
|
||||
<clr-tab-content>
|
||||
<hbr-artifact-build-history
|
||||
[buildHistoryLink]="
|
||||
getBuildHistory()
|
||||
"></hbr-artifact-build-history>
|
||||
</clr-tab-content>
|
||||
</ng-template>
|
||||
</clr-tab>
|
||||
<clr-tab *ngIf="getSummary()">
|
||||
<button clrTabLink id="summary-link">
|
||||
<button
|
||||
clrTabLink
|
||||
id="summary-link"
|
||||
(click)="actionTab('summary-link')">
|
||||
{{ 'ARTIFACT.SUMMARY' | translate }}
|
||||
</button>
|
||||
<clr-tab-content id="summary-content" *clrIfActive>
|
||||
<hbr-artifact-summary
|
||||
[summaryLink]="getSummary()"></hbr-artifact-summary>
|
||||
</clr-tab-content>
|
||||
<ng-template
|
||||
[clrIfActive]="currentTabLinkId === 'summary-link'">
|
||||
<clr-tab-content id="summary-content">
|
||||
<hbr-artifact-summary
|
||||
[summaryLink]="getSummary()"></hbr-artifact-summary>
|
||||
</clr-tab-content>
|
||||
</ng-template>
|
||||
</clr-tab>
|
||||
<clr-tab *ngIf="getDependencies()">
|
||||
<button clrTabLink id="depend-link">
|
||||
<button
|
||||
clrTabLink
|
||||
id="depend-link"
|
||||
(click)="actionTab('depend-link')">
|
||||
{{ 'ARTIFACT.DEPENDENCIES' | translate }}
|
||||
</button>
|
||||
<clr-tab-content id="depend-content" *clrIfActive>
|
||||
<hbr-artifact-dependencies
|
||||
[dependenciesLink]="
|
||||
getDependencies()
|
||||
"></hbr-artifact-dependencies>
|
||||
</clr-tab-content>
|
||||
<ng-template [clrIfActive]="currentTabLinkId === 'depend-link'">
|
||||
<clr-tab-content id="depend-content">
|
||||
<hbr-artifact-dependencies
|
||||
[dependenciesLink]="
|
||||
getDependencies()
|
||||
"></hbr-artifact-dependencies>
|
||||
</clr-tab-content>
|
||||
</ng-template>
|
||||
</clr-tab>
|
||||
<clr-tab *ngIf="getValues()">
|
||||
<button clrTabLink id="value-link">
|
||||
<button
|
||||
clrTabLink
|
||||
id="value-link"
|
||||
(click)="actionTab('value-link')">
|
||||
{{ 'ARTIFACT.VALUES' | translate }}
|
||||
</button>
|
||||
<clr-tab-content id="value-content" *clrIfActive>
|
||||
<hbr-artifact-values
|
||||
[valuesLink]="getValues()"></hbr-artifact-values>
|
||||
</clr-tab-content>
|
||||
<ng-template [clrIfActive]="currentTabLinkId === 'value-link'">
|
||||
<clr-tab-content id="value-content">
|
||||
<hbr-artifact-values
|
||||
[valuesLink]="getValues()"></hbr-artifact-values>
|
||||
</clr-tab-content>
|
||||
</ng-template>
|
||||
</clr-tab>
|
||||
</clr-tabs>
|
||||
</div>
|
||||
|
|
|
@ -1,15 +1,23 @@
|
|||
import { Component, Input } from '@angular/core';
|
||||
import {
|
||||
AfterViewChecked,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
Input,
|
||||
OnInit,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { ADDITIONS } from './models';
|
||||
import { AdditionLinks } from '../../../../../../../ng-swagger-gen/models/addition-links';
|
||||
import { AdditionLink } from '../../../../../../../ng-swagger-gen/models/addition-link';
|
||||
import { Artifact } from '../../../../../../../ng-swagger-gen/models/artifact';
|
||||
import { ClrTabs } from '@clr/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'artifact-additions',
|
||||
templateUrl: './artifact-additions.component.html',
|
||||
styleUrls: ['./artifact-additions.component.scss'],
|
||||
})
|
||||
export class ArtifactAdditionsComponent {
|
||||
export class ArtifactAdditionsComponent implements AfterViewChecked, OnInit {
|
||||
@Input() artifact: Artifact;
|
||||
@Input() additionLinks: AdditionLinks;
|
||||
@Input() projectName: string;
|
||||
|
@ -21,7 +29,26 @@ export class ArtifactAdditionsComponent {
|
|||
digest: string;
|
||||
@Input()
|
||||
sbomDigest: string;
|
||||
constructor() {}
|
||||
@Input()
|
||||
tab: string;
|
||||
|
||||
@Input() currentTabLinkId: string = 'vulnerability';
|
||||
activeTab: string = null;
|
||||
|
||||
@ViewChild('additionsTab') tabs: ClrTabs;
|
||||
constructor(private ref: ChangeDetectorRef) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.activeTab = this.tab;
|
||||
}
|
||||
|
||||
ngAfterViewChecked() {
|
||||
if (this.activeTab) {
|
||||
this.currentTabLinkId = this.activeTab;
|
||||
this.activeTab = null;
|
||||
}
|
||||
this.ref.detectChanges();
|
||||
}
|
||||
|
||||
getVulnerability(): AdditionLink {
|
||||
if (
|
||||
|
@ -62,4 +89,8 @@ export class ArtifactAdditionsComponent {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
actionTab(tab: string): void {
|
||||
this.currentTabLinkId = tab;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,10 +32,10 @@
|
|||
</div>
|
||||
</div>
|
||||
</clr-dg-action-bar>
|
||||
<clr-dg-column [clrDgField]="'package'">{{
|
||||
<clr-dg-column [clrDgField]="'package'" class="package-medium">{{
|
||||
'SBOM.GRID.COLUMN_PACKAGE' | translate
|
||||
}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'version'">{{
|
||||
<clr-dg-column [clrDgField]="'version'" class="version-medium">{{
|
||||
'SBOM.GRID.COLUMN_VERSION' | translate
|
||||
}}</clr-dg-column>
|
||||
<clr-dg-column>{{
|
||||
|
@ -50,17 +50,25 @@
|
|||
</ng-template>
|
||||
</clr-dg-placeholder>
|
||||
<clr-dg-row *clrDgItems="let res of artifactSbomPackages()">
|
||||
<clr-dg-cell>{{ res.name ?? '' }}</clr-dg-cell>
|
||||
<clr-dg-cell>{{ res.versionInfo ?? '' }}</clr-dg-cell>
|
||||
<clr-dg-cell class="package-medium">{{
|
||||
res.name ?? ''
|
||||
}}</clr-dg-cell>
|
||||
<clr-dg-cell class="version-medium">{{
|
||||
res.versionInfo ?? ''
|
||||
}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{ res.licenseConcluded ?? '' }}</clr-dg-cell>
|
||||
</clr-dg-row>
|
||||
|
||||
<clr-dg-footer>
|
||||
<div class="report">
|
||||
<i *ngIf="artifact?.scanner">{{
|
||||
<i *ngIf="artifact?.sbom_overview">{{
|
||||
'SBOM.REPORTED_BY'
|
||||
| translate
|
||||
: { scanner: getScannerInfo(artifact?.scanner) }
|
||||
: {
|
||||
scanner: getScannerInfo(
|
||||
artifact?.sbom_overview?.scanner
|
||||
)
|
||||
}
|
||||
}}</i>
|
||||
</div>
|
||||
<clr-dg-pagination
|
||||
|
|
|
@ -62,3 +62,13 @@
|
|||
.label {
|
||||
min-width: 3rem;
|
||||
}
|
||||
|
||||
.package-medium {
|
||||
max-width: 25rem;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.version-medium {
|
||||
min-width: 22rem;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import { SessionUser } from '../../../../../../shared/entities/session-user';
|
|||
import { AppConfigService } from 'src/app/services/app-config.service';
|
||||
import { ArtifactSbomPackageItem } from '../../artifact';
|
||||
import { ArtifactService } from 'ng-swagger-gen/services';
|
||||
import { ArtifactListPageService } from '../../artifact-list-page/artifact-list-page.service';
|
||||
|
||||
describe('ArtifactSbomComponent', () => {
|
||||
let component: ArtifactSbomComponent;
|
||||
|
@ -97,13 +98,9 @@ describe('ArtifactSbomComponent', () => {
|
|||
},
|
||||
packages: artifactSbomPackages,
|
||||
};
|
||||
const mockedLink: AdditionLink = {
|
||||
absolute: false,
|
||||
href: '/test',
|
||||
};
|
||||
const fakedArtifactService = {
|
||||
getSbomAddition() {
|
||||
return of(artifactSbomJson);
|
||||
getAddition() {
|
||||
return of(JSON.stringify(artifactSbomJson));
|
||||
},
|
||||
};
|
||||
const fakedUserPermissionService = {
|
||||
|
@ -131,6 +128,12 @@ describe('ArtifactSbomComponent', () => {
|
|||
};
|
||||
const mockedSbomDigest =
|
||||
'sha256:51a41cec9de9d62ee60e206f5a8a615a028a65653e45539990867417cb486285';
|
||||
const mockedArtifactListPageService = {
|
||||
hasScannerSupportSBOM(): boolean {
|
||||
return true;
|
||||
},
|
||||
init() {},
|
||||
};
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
|
@ -153,6 +156,10 @@ describe('ArtifactSbomComponent', () => {
|
|||
useValue: fakedUserPermissionService,
|
||||
},
|
||||
{ provide: SessionService, useValue: fakedSessionService },
|
||||
{
|
||||
provide: ArtifactListPageService,
|
||||
useValue: mockedArtifactListPageService,
|
||||
},
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
}).compileComponents();
|
||||
|
@ -162,8 +169,7 @@ describe('ArtifactSbomComponent', () => {
|
|||
fixture = TestBed.createComponent(ArtifactSbomComponent);
|
||||
component = fixture.componentInstance;
|
||||
component.hasSbomPermission = true;
|
||||
component.hasEnabledSbom = true;
|
||||
component.sbomLink = mockedLink;
|
||||
component.hasScannerSupportSBOM = true;
|
||||
component.sbomDigest = mockedSbomDigest;
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import {
|
||||
AfterViewInit,
|
||||
Component,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
} from '@angular/core';
|
||||
import { ClrDatagridStateInterface, ClrLoadingState } from '@clr/angular';
|
||||
import { finalize } from 'rxjs/operators';
|
||||
import { AdditionLink } from '../../../../../../../../ng-swagger-gen/models/addition-link';
|
||||
|
@ -32,6 +38,8 @@ import {
|
|||
getArtifactSbom,
|
||||
} from '../../artifact';
|
||||
import { ArtifactService } from 'ng-swagger-gen/services';
|
||||
import { ScanTypes } from 'src/app/shared/entities/shared.const';
|
||||
import { ArtifactListPageService } from '../../artifact-list-page/artifact-list-page.service';
|
||||
|
||||
@Component({
|
||||
selector: 'hbr-artifact-sbom',
|
||||
|
@ -39,8 +47,6 @@ import { ArtifactService } from 'ng-swagger-gen/services';
|
|||
styleUrls: ['./artifact-sbom.component.scss'],
|
||||
})
|
||||
export class ArtifactSbomComponent implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
sbomLink: AdditionLink;
|
||||
@Input()
|
||||
projectName: string;
|
||||
@Input()
|
||||
|
@ -53,7 +59,7 @@ export class ArtifactSbomComponent implements OnInit, OnDestroy {
|
|||
|
||||
artifactSbom: ArtifactSbom;
|
||||
loading: boolean = false;
|
||||
hasEnabledSbom: boolean = false;
|
||||
hasScannerSupportSBOM: boolean = false;
|
||||
downloadSbomBtnState: ClrLoadingState = ClrLoadingState.DEFAULT;
|
||||
hasSbomPermission: boolean = false;
|
||||
|
||||
|
@ -69,15 +75,16 @@ export class ArtifactSbomComponent implements OnInit, OnDestroy {
|
|||
private errorHandler: ErrorHandler,
|
||||
private appConfigService: AppConfigService,
|
||||
private artifactService: ArtifactService,
|
||||
private artifactListPageService: ArtifactListPageService,
|
||||
private userPermissionService: UserPermissionService,
|
||||
private eventService: EventService,
|
||||
private session: SessionService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.artifactListPageService.init(this.projectId);
|
||||
this.getSbom();
|
||||
this.getSbomPermission();
|
||||
this.hasEnabledSbom = this.appConfigService.getConfig().sbom_enabled;
|
||||
if (!this.sub) {
|
||||
this.sub = this.eventService.subscribe(
|
||||
HarborEvent.UPDATE_SBOM_INFO,
|
||||
|
@ -109,23 +116,19 @@ export class ArtifactSbomComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
getSbom() {
|
||||
if (
|
||||
this.sbomDigest &&
|
||||
this.sbomLink &&
|
||||
!this.sbomLink.absolute &&
|
||||
this.sbomLink.href
|
||||
) {
|
||||
if (this.sbomDigest) {
|
||||
if (!this.hasShowLoading) {
|
||||
this.loading = true;
|
||||
this.hasShowLoading = true;
|
||||
}
|
||||
const sbomAdditionParams = <ArtifactService.GetSbomAdditionParams>{
|
||||
const sbomAdditionParams = <ArtifactService.GetAdditionParams>{
|
||||
repositoryName: dbEncodeURIComponent(this.repoName),
|
||||
reference: this.sbomDigest,
|
||||
projectName: this.projectName,
|
||||
addition: ScanTypes.SBOM,
|
||||
};
|
||||
this.artifactService
|
||||
.getSbomAddition(sbomAdditionParams)
|
||||
.getAddition(sbomAdditionParams)
|
||||
.pipe(
|
||||
finalize(() => {
|
||||
this.loading = false;
|
||||
|
@ -134,7 +137,14 @@ export class ArtifactSbomComponent implements OnInit, OnDestroy {
|
|||
)
|
||||
.subscribe(
|
||||
res => {
|
||||
this.artifactSbom = getArtifactSbom(res);
|
||||
if (res) {
|
||||
this.artifactSbom = getArtifactSbom(
|
||||
JSON.parse(res)
|
||||
);
|
||||
} else {
|
||||
this.loading = false;
|
||||
this.hasShowLoading = false;
|
||||
}
|
||||
},
|
||||
error => {
|
||||
this.errorHandler.error(error);
|
||||
|
@ -190,9 +200,9 @@ export class ArtifactSbomComponent implements OnInit, OnDestroy {
|
|||
return (
|
||||
this.hasViewInitWithDelay &&
|
||||
this.artifact.sbom_overview &&
|
||||
(this.artifact.sbom_overview.sbom_status ===
|
||||
(this.artifact.sbom_overview.scan_status ===
|
||||
SBOM_SCAN_STATUS.PENDING ||
|
||||
this.artifact.sbom_overview.sbom_status ===
|
||||
this.artifact.sbom_overview.scan_status ===
|
||||
SBOM_SCAN_STATUS.RUNNING)
|
||||
);
|
||||
}
|
||||
|
@ -200,7 +210,7 @@ export class ArtifactSbomComponent implements OnInit, OnDestroy {
|
|||
downloadSbom() {
|
||||
this.downloadSbomBtnState = ClrLoadingState.LOADING;
|
||||
if (
|
||||
this.artifact?.sbom_overview?.sbom_status ===
|
||||
this.artifact?.sbom_overview?.scan_status ===
|
||||
SBOM_SCAN_STATUS.SUCCESS
|
||||
) {
|
||||
downloadJson(
|
||||
|
@ -212,9 +222,11 @@ export class ArtifactSbomComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
canDownloadSbom(): boolean {
|
||||
this.hasScannerSupportSBOM =
|
||||
this.artifactListPageService.hasScannerSupportSBOM();
|
||||
return (
|
||||
this.hasEnabledSbom &&
|
||||
this.hasSbomPermission &&
|
||||
this.hasScannerSupportSBOM &&
|
||||
//this.hasSbomPermission &&
|
||||
this.sbomDigest &&
|
||||
this.downloadSbomBtnState !== ClrLoadingState.LOADING &&
|
||||
this.artifactSbom !== undefined
|
||||
|
|
|
@ -170,6 +170,8 @@ export class ArtifactListPageService {
|
|||
this._hasDeleteImagePermission = results[2];
|
||||
this._hasScanImagePermission = results[3];
|
||||
this._hasSbomPermission = results?.[4] ?? false;
|
||||
// TODO need to remove the static code
|
||||
this._hasSbomPermission = true;
|
||||
},
|
||||
error => this.errorHandlerService.error(error)
|
||||
);
|
||||
|
|
|
@ -53,9 +53,9 @@
|
|||
!(
|
||||
canGenerateSbomNow() &&
|
||||
selectedRowHasSbom() &&
|
||||
hasEnabledSbom &&
|
||||
hasScannerSupportSBOM &&
|
||||
hasSbomPermission
|
||||
hasEnabledScanner &&
|
||||
hasSbomPermission &&
|
||||
hasScannerSupportSBOM
|
||||
)
|
||||
"
|
||||
(click)="generateSbom()">
|
||||
|
|
|
@ -46,7 +46,6 @@ import {
|
|||
ConfirmationButtons,
|
||||
ConfirmationState,
|
||||
ConfirmationTargets,
|
||||
ScanTypes,
|
||||
} from '../../../../../../../shared/entities/shared.const';
|
||||
import {
|
||||
operateChanges,
|
||||
|
@ -102,7 +101,6 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||
projectName: string;
|
||||
repoName: string;
|
||||
registryUrl: string;
|
||||
sbomEnabled: boolean;
|
||||
artifactList: ArtifactFront[] = [];
|
||||
availableTime = AVAILABLE_TIME;
|
||||
inprogress: boolean;
|
||||
|
@ -240,7 +238,6 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||
ngOnInit() {
|
||||
const appConfig = this.appConfigService.getConfig();
|
||||
this.registryUrl = appConfig.registry_url;
|
||||
this.sbomEnabled = appConfig.sbom_enabled;
|
||||
this.initRouterData();
|
||||
if (!this.updateArtifactSub) {
|
||||
this.updateArtifactSub = this.eventService.subscribe(
|
||||
|
@ -753,11 +750,15 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||
if (this.activatedRoute.snapshot.queryParams[UN_LOGGED_PARAM] === YES) {
|
||||
this.router.navigate(relativeRouterLink, {
|
||||
relativeTo: this.activatedRoute,
|
||||
queryParams: { [UN_LOGGED_PARAM]: YES },
|
||||
queryParams: {
|
||||
[UN_LOGGED_PARAM]: YES,
|
||||
sbomDigest: artifact.sbomDigest ?? '',
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.router.navigate(relativeRouterLink, {
|
||||
relativeTo: this.activatedRoute,
|
||||
queryParams: { sbomDigest: artifact.sbomDigest ?? '' },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -981,6 +982,10 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
}
|
||||
// when finished, remove it from selectedRow
|
||||
sbomFinished(artifact: Artifact) {
|
||||
this.scanFinished(artifact);
|
||||
}
|
||||
|
||||
// when finished, remove it from selectedRow
|
||||
sbomFinished(artifact: Artifact) {
|
||||
|
@ -1127,7 +1132,7 @@ export class ArtifactListTabComponent implements OnInit, OnDestroy {
|
|||
if (this.selectedRow && this.selectedRow.length) {
|
||||
let flag: boolean = true;
|
||||
this.selectedRow.forEach(item => {
|
||||
const st: string = this.scanStatus(item);
|
||||
const st: string = this.sbomStatus(item);
|
||||
if (!this.isRunningState(st)) {
|
||||
flag = false;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
[repoName]="repositoryName"
|
||||
[digest]="artifactDigest"
|
||||
[sbomDigest]="sbomDigest"
|
||||
[tab]="activeTab"
|
||||
[additionLinks]="artifact?.addition_links"></artifact-additions>
|
||||
</ng-container>
|
||||
<div *ngIf="loading" class="clr-row mt-3 center">
|
||||
|
|
|
@ -22,6 +22,7 @@ export class ArtifactSummaryComponent implements OnInit {
|
|||
tagId: string;
|
||||
artifactDigest: string;
|
||||
sbomDigest?: string;
|
||||
activeTab?: string;
|
||||
repositoryName: string;
|
||||
projectId: string | number;
|
||||
referArtifactNameArray: string[] = [];
|
||||
|
@ -96,6 +97,7 @@ export class ArtifactSummaryComponent implements OnInit {
|
|||
this.artifactDigest = this.route.snapshot.params['digest'];
|
||||
this.projectId = this.route.snapshot.parent.params['id'];
|
||||
this.sbomDigest = this.route.snapshot.queryParams['sbomDigest'];
|
||||
this.activeTab = this.route.snapshot.queryParams['tab'];
|
||||
if (this.repositoryName && this.artifactDigest) {
|
||||
const resolverData = this.route.snapshot.data;
|
||||
if (resolverData) {
|
||||
|
|
|
@ -216,10 +216,7 @@ export const ArtifactSbomFieldMapper = {
|
|||
* else return false.
|
||||
*/
|
||||
export function isSpdxSbom(sbomJson?: Object): boolean {
|
||||
return sbomJson[ArtifactSbomFieldMapper.sbomVersion] ||
|
||||
sbomJson[ArtifactSbomFieldMapper.sbomId]
|
||||
? true
|
||||
: false;
|
||||
return Object.keys(sbomJson ?? {}).includes(ArtifactSbomFieldMapper.sbomId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -343,7 +340,6 @@ export function readDataFromArtifactSbomJson(
|
|||
*/
|
||||
export function getArtifactSbom(sbomJson?: Object): ArtifactSbom {
|
||||
if (sbomJson) {
|
||||
// only support to parse spdx json
|
||||
if (isSpdxSbom(sbomJson)) {
|
||||
const artifactSbom = <ArtifactSbom>{};
|
||||
artifactSbom.sbomJsonRaw = sbomJson;
|
||||
|
|
|
@ -10,7 +10,6 @@ import { SbomTipHistogramComponent } from './sbom-tip-histogram/sbom-tip-histogr
|
|||
import { SBOMOverview } from './sbom-overview';
|
||||
import { of, timer } from 'rxjs';
|
||||
import { ArtifactService, ScanService } from 'ng-swagger-gen/services';
|
||||
import { Artifact } from 'ng-swagger-gen/models';
|
||||
|
||||
describe('ResultSbomComponent (inline template)', () => {
|
||||
let component: ResultSbomComponent;
|
||||
|
|
|
@ -219,7 +219,7 @@ export class ResultSbomComponent implements OnInit, OnDestroy {
|
|||
projectName: this.projectName,
|
||||
repositoryName: dbEncodeURIComponent(this.repoName),
|
||||
reference: this.artifactDigest,
|
||||
withScanOverview: true,
|
||||
withSbomOverview: true,
|
||||
XAcceptVulnerabilities: DEFAULT_SUPPORTED_MIME_TYPES,
|
||||
})
|
||||
.subscribe(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ScannerVo, SbomSummary } from '../../../../../../shared/services';
|
||||
|
@ -20,9 +20,8 @@ const SUCCESS_PCT: number = 100;
|
|||
templateUrl: './sbom-tip-histogram.component.html',
|
||||
styleUrls: ['./sbom-tip-histogram.component.scss'],
|
||||
})
|
||||
export class SbomTipHistogramComponent implements OnInit {
|
||||
export class SbomTipHistogramComponent {
|
||||
@Input() scanner: ScannerVo;
|
||||
_sbomPackages: number = 0;
|
||||
@Input() sbomSummary: SbomSummary = {
|
||||
scan_status: SBOM_SCAN_STATUS.NOT_GENERATED_SBOM,
|
||||
};
|
||||
|
@ -34,22 +33,6 @@ export class SbomTipHistogramComponent implements OnInit {
|
|||
private router: Router
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this._sbomPackages = this.sbomSummary?.summary?.total ?? 0;
|
||||
}
|
||||
|
||||
get sbomPackages(): number {
|
||||
return this._sbomPackages;
|
||||
}
|
||||
|
||||
get sevSummary(): { [key: string]: number } {
|
||||
if (this.sbomSummary && this.sbomSummary.summary) {
|
||||
return this.sbomSummary.summary.summary;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
duration(): string {
|
||||
if (this.sbomSummary && this.sbomSummary.duration) {
|
||||
let str = '';
|
||||
|
|
|
@ -29,7 +29,6 @@ export class AppConfig {
|
|||
registry_storage_provider_name: string;
|
||||
read_only: boolean;
|
||||
show_popular_repo: boolean;
|
||||
sbom_enabled: boolean;
|
||||
banner_message: string;
|
||||
current_time: string;
|
||||
oidc_provider_name: string;
|
||||
|
@ -44,7 +43,6 @@ export class AppConfig {
|
|||
this.project_creation_restriction = 'everyone';
|
||||
this.self_registration = true;
|
||||
this.has_ca_root = false;
|
||||
this.sbom_enabled = false;
|
||||
this.harbor_version = 'unknown';
|
||||
this.clair_vulnerability_status = {
|
||||
overall_last_update: 0,
|
||||
|
|
|
@ -213,12 +213,9 @@ export interface VulnerabilitySummary {
|
|||
}
|
||||
export interface SbomSummary {
|
||||
report_id?: string;
|
||||
mime_type?: string;
|
||||
sbom_digest?: string;
|
||||
scan_status?: string;
|
||||
severity?: string;
|
||||
duration?: number;
|
||||
summary?: SeveritySummary;
|
||||
start_time?: Date;
|
||||
end_time?: Date;
|
||||
scanner?: ScannerVo;
|
||||
|
|
Loading…
Reference in New Issue