feat: As an user I want to have the layout for my pentest

This commit is contained in:
Marcel Haag 2022-09-01 17:27:12 +02:00 committed by mhg
parent ecaaeea079
commit b695b17a9e
54 changed files with 718 additions and 184 deletions

View File

@ -70,12 +70,11 @@ export class PentestTableComponent implements OnInit {
.then(
() => this.store.reset({
...this.store.snapshot(),
[PROJECT_STATE_NAME]: undefined
// [PROJECT_STATE_NAME]: pentest
})
).finally();
*/
this.store.dispatch(new ChangePentest(pentest.id));
this.store.dispatch(new ChangePentest(pentest));
}
// HTML only

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PentestCommentsComponent } from './pentest-comments.component';
describe('PentestCommentsComponent', () => {
let component: PentestCommentsComponent;
let fixture: ComponentFixture<PentestCommentsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PentestCommentsComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PentestCommentsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-pentest-comments',
templateUrl: './pentest-comments.component.html',
styleUrls: ['./pentest-comments.component.scss']
})
export class PentestCommentsComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@ -0,0 +1,27 @@
<div class="pentest-content">
<div class="content">
<nb-tabset>
<nb-tab tabTitle="{{ 'global.action.info' | translate }}">
<app-pentest-info></app-pentest-info>
</nb-tab>
<nb-tab tabTitle="{{ 'pentest.findings' | translate }} ({{currentNumberOfFindings$.getValue()}})">
<app-pentest-findings></app-pentest-findings>
</nb-tab>
<nb-tab tabTitle="{{ 'pentest.comments' | translate }} ({{currentNumberOfComments$.getValue()}})">
<app-pentest-comments></app-pentest-comments>
</nb-tab>
</nb-tabset>
</div>
<div fxLayoutAlign="end end" class="content-footer">
<button nbButton
class="save-pentest-button"
status="primary"
[disabled]="!pentestChanged$.getValue()"
title="{{ 'global.action.save' | translate }}"
(click)="onClickSavePentest()">
<span class="exit-element-text"> {{ 'global.action.save' | translate }} </span>
</button>
</div>
</div>

View File

@ -0,0 +1,18 @@
.pentest-content {
width: 100%;
height: 100%;
.content {
overflow: auto !important;
height: 95%;
// check fixed height
// background-color: #8f9bb3;
}
.content-footer {
height: 5%;
.save-pentest-button {
margin: 1rem 6rem 1rem 0;
}
}
}

View File

@ -0,0 +1,82 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {PentestContentComponent} from './pentest-content.component';
import {TranslateLoader, TranslateModule} from '@ngx-translate/core';
import {HttpLoaderFactory} from '../../../common-app.module';
import {HttpClient} from '@angular/common/http';
import {RouterTestingModule} from '@angular/router/testing';
import {NgxsModule, Store} from '@ngxs/store';
import {PROJECT_STATE_NAME, ProjectState, ProjectStateModel} from '@shared/stores/project-state/project-state';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {HttpClientTestingModule} from '@angular/common/http/testing';
import {Category} from '@shared/models/category.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
selectedProject: {
id: '56c47c56-3bcd-45f1-a05b-c197dbd33111',
client: 'E Corp',
title: 'Some Mock API (v1.0) Scanning',
createdAt: new Date('2019-01-10T09:00:00'),
tester: 'Novatester',
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
},
// Manages Categories
disabledCategories: [],
selectedCategory: Category.INFORMATION_GATHERING,
// Manages Pentests of Category
disabledPentests: [],
selectedPentest: {
id: '56c47c56-3bcd-45f1-a05b-c197dbd33112',
category: Category.INFORMATION_GATHERING,
refNumber: 'OTF-001',
childEntries: [],
status: PentestStatus.NOT_STARTED,
findingsIds: [],
commentsIds: []
},
};
describe('PentestContentComponent', () => {
let component: PentestContentComponent;
let fixture: ComponentFixture<PentestContentComponent>;
let store: Store;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
PentestContentComponent
],
imports: [
BrowserAnimationsModule,
HttpClientTestingModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
}),
RouterTestingModule.withRoutes([]),
NgxsModule.forRoot([ProjectState])
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PentestContentComponent);
store = TestBed.inject(Store);
store.reset({
...store.snapshot(),
[PROJECT_STATE_NAME]: DESIRED_PROJECT_STATE_SESSION
});
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,46 @@
import { Component, OnInit } from '@angular/core';
import * as FA from '@fortawesome/free-solid-svg-icons';
import {BehaviorSubject} from 'rxjs';
import {Store} from '@ngxs/store';
import {ProjectState} from '@shared/stores/project-state/project-state';
import {UntilDestroy, untilDestroyed} from '@ngneat/until-destroy';
import {Pentest} from '@shared/models/pentest.model';
@UntilDestroy()
@Component({
selector: 'app-pentest-content',
templateUrl: './pentest-content.component.html',
styleUrls: ['./pentest-content.component.scss']
})
export class PentestContentComponent implements OnInit {
readonly fa = FA;
pentest$: BehaviorSubject<Pentest> = new BehaviorSubject<Pentest>(null);
pentestChanged$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
currentNumberOfFindings$: BehaviorSubject<number> = new BehaviorSubject<number>(0);
currentNumberOfComments$: BehaviorSubject<number> = new BehaviorSubject<number>(0);
constructor(private store: Store) { }
ngOnInit(): void {
this.store.select(ProjectState.pentest).pipe(
untilDestroyed(this)
).subscribe({
next: (selectedPentest: Pentest) => {
console.warn('Selected Pentest: ', selectedPentest);
this.pentest$.next(selectedPentest);
const findings = selectedPentest.findingsIds ? selectedPentest.findingsIds.length : 0;
this.currentNumberOfFindings$.next(findings);
const comments = selectedPentest.commentsIds ? selectedPentest.commentsIds.length : 0;
this.currentNumberOfComments$.next(comments);
},
error: err => {
console.error(err);
}
});
}
onClickSavePentest(): void {
console.info('to be implemented..');
}
}

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PentestFindingsComponent } from './pentest-findings.component';
describe('PentestFindingsComponent', () => {
let component: PentestFindingsComponent;
let fixture: ComponentFixture<PentestFindingsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PentestFindingsComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PentestFindingsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-pentest-findings',
templateUrl: './pentest-findings.component.html',
styleUrls: ['./pentest-findings.component.scss']
})
export class PentestFindingsComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PentestInfoComponent } from './pentest-info.component';
describe('PentestInfoComponent', () => {
let component: PentestInfoComponent;
let fixture: ComponentFixture<PentestInfoComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PentestInfoComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PentestInfoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-pentest-info',
templateUrl: './pentest-info.component.html',
styleUrls: ['./pentest-info.component.scss']
})
export class PentestInfoComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@ -0,0 +1,20 @@
<div class="pentest-stepper" fxLayout="row" fxLayoutGap="2rem" fxLayoutAlign="space-between center">
<div class="exit-button-container">
<button nbButton
shape="round"
title="{{ 'global.action.exit' | translate }}"
(click)="onClickRouteBack()">
<fa-icon [icon]="fa.faLongArrowAltLeft"
class="exit-element-icon fa-lg">
</fa-icon>
<span class="exit-element-text"> {{ 'global.action.exit' | translate }} </span>
</button>
</div>
<h4>{{selectedProjectTitle$.getValue()}} / {{pentest$.getValue().refNumber}}</h4>
<div class="pentest-status-container">
<app-status-tag [currentStatus]="pentest$.getValue().status"></app-status-tag>
</div>
</div>

View File

@ -0,0 +1,17 @@
.pentest-stepper {
width: calc(100vw - 14%);
.exit-button-container {
.exit-element-icon {
}
.exit-element-text {
padding-left: 0.5rem;
}
}
.pentest-status-container {
display: flex;
align-content: flex-end;
margin-right: 0.5rem;
}
}

View File

@ -0,0 +1,80 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {PentestMenuComponent} from './pentest-menu.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {HttpClientTestingModule} from '@angular/common/http/testing';
import {TranslateLoader, TranslateModule} from '@ngx-translate/core';
import {HttpLoaderFactory} from '../../../common-app.module';
import {HttpClient} from '@angular/common/http';
import {RouterTestingModule} from '@angular/router/testing';
import {NgxsModule, Store} from '@ngxs/store';
import {PROJECT_STATE_NAME, ProjectState, ProjectStateModel} from '@shared/stores/project-state/project-state';
import {Category} from '@shared/models/category.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
selectedProject: {
id: '56c47c56-3bcd-45f1-a05b-c197dbd33111',
client: 'E Corp',
title: 'Some Mock API (v1.0) Scanning',
createdAt: new Date('2019-01-10T09:00:00'),
tester: 'Novatester',
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
},
// Manages Categories
disabledCategories: [],
selectedCategory: Category.INFORMATION_GATHERING,
// Manages Pentests of Category
disabledPentests: [],
selectedPentest: {
id: '56c47c56-3bcd-45f1-a05b-c197dbd33112',
category: Category.INFORMATION_GATHERING,
refNumber: 'OTF-001',
childEntries: [],
status: PentestStatus.NOT_STARTED,
findingsIds: [],
commentsIds: []
},
};
describe('PentestMenuComponent', () => {
let component: PentestMenuComponent;
let fixture: ComponentFixture<PentestMenuComponent>;
let store: Store;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [PentestMenuComponent],
imports: [
BrowserAnimationsModule,
HttpClientTestingModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
}),
RouterTestingModule.withRoutes([]),
NgxsModule.forRoot([ProjectState])
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PentestMenuComponent);
store = TestBed.inject(Store);
store.reset({
...store.snapshot(),
[PROJECT_STATE_NAME]: DESIRED_PROJECT_STATE_SESSION
});
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,63 @@
import {Component, OnInit} from '@angular/core';
import * as FA from '@fortawesome/free-solid-svg-icons';
import {UntilDestroy, untilDestroyed} from '@ngneat/until-destroy';
import {Route} from '@shared/models/route.enum';
import {Store} from '@ngxs/store';
import {Router} from '@angular/router';
import {ChangePentest} from '@shared/stores/project-state/project-state.actions';
import {BehaviorSubject} from 'rxjs';
import {PentestStatus} from '@shared/models/pentest-status.model';
import {ProjectState} from '@shared/stores/project-state/project-state';
import {Project} from '@shared/models/project.model';
import {Pentest} from '@shared/models/pentest.model';
@UntilDestroy()
@Component({
selector: 'app-pentest-menu',
templateUrl: './pentest-menu.component.html',
styleUrls: ['./pentest-menu.component.scss']
})
export class PentestMenuComponent implements OnInit {
// HTML only
readonly fa = FA;
pentest$: BehaviorSubject<Pentest> = new BehaviorSubject<Pentest>(null);
selectedProjectTitle$: BehaviorSubject<string> = new BehaviorSubject<string>('');
constructor(private store: Store,
private readonly router: Router) {
}
ngOnInit(): void {
this.store.select(ProjectState.project).pipe(
untilDestroyed(this)
).subscribe({
next: (selectedProject: Project) => {
this.selectedProjectTitle$.next(selectedProject?.title);
},
error: err => {
console.error(err);
}
});
this.store.select(ProjectState.pentest).pipe(
untilDestroyed(this)
).subscribe({
next: (selectedPentest: Pentest) => {
this.pentest$.next(selectedPentest);
},
error: err => {
console.error(err);
}
});
}
onClickRouteBack(): void {
this.router.navigate([Route.PENTEST_OVERVIEW])
.then(
() => {
this.store.dispatch(new ChangePentest(null));
}
).finally();
}
}

View File

@ -1,5 +1,15 @@
<nb-layout>
<nb-layout-header>
<p>pentest works!</p>
</nb-layout-header>
</nb-layout>
<div fxFlex class="pentest">
<nb-layout fxFlex>
<nb-layout-header fxFlex="0 1 max-content" class="stepper-column">
<app-pentest-menu></app-pentest-menu>
</nb-layout-header>
<nb-layout-column fxFlex="0 1 max-content" class="column-wrapper">
<nb-card class="content-column">
<nb-card-body>
<app-pentest-content></app-pentest-content>
</nb-card-body>
</nb-card>
</nb-layout-column>
</nb-layout>
</div>

View File

@ -0,0 +1,24 @@
@import '../../../assets/@theme/styles/themes';
@import '../../../assets/@theme/styles/_variables.scss';
.pentest {
width: 100vw;
height: calc(100vh - #{$header-height});
overflow: hidden;
.header-column {
width: 100vw;
height: $pentest-header-height;
}
.column-wrapper {
padding-left: 0 !important;
.content-column {
overflow: auto !important;
width: 100vw;
max-width: 100vw;
height: calc(100vh - #{$pentest-header-height} - #{$header-height});
}
}
}

View File

@ -2,11 +2,25 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {RouterModule} from '@angular/router';
import {PentestComponent} from './pentest.component';
import {NbLayoutModule} from '@nebular/theme';
import {NbButtonModule, NbCardModule, NbLayoutModule, NbTabsetModule} from '@nebular/theme';
import { PentestMenuComponent } from './pentest-menu/pentest-menu.component';
import { PentestContentComponent } from './pentest-content/pentest-content.component';
import {FlexLayoutModule} from '@angular/flex-layout';
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
import {TranslateModule} from '@ngx-translate/core';
import {StatusTagModule} from '@shared/widgets/status-tag/status-tag.module';
import { PentestInfoComponent } from './pentest-content/pentest-info/pentest-info.component';
import { PentestFindingsComponent } from './pentest-content/pentest-findings/pentest-findings.component';
import { PentestCommentsComponent } from './pentest-content/pentest-comments/pentest-comments.component';
@NgModule({
declarations: [
PentestComponent
PentestComponent,
PentestMenuComponent,
PentestContentComponent,
PentestInfoComponent,
PentestFindingsComponent,
PentestCommentsComponent
],
imports: [
CommonModule,
@ -14,7 +28,14 @@ import {NbLayoutModule} from '@nebular/theme';
path: '',
component: PentestComponent
}]),
NbLayoutModule
NbLayoutModule,
NbCardModule,
FlexLayoutModule,
FontAwesomeModule,
TranslateModule,
NbButtonModule,
StatusTagModule,
NbTabsetModule
]
})
export class PentestModule {

View File

@ -8,13 +8,14 @@
.header-column {
width: 100vw;
height: $pentest-header-height;
}
.column-wrapper {
padding-left: 0 !important;
.categories-column {
height: calc(100vh - #{$pentest-header-height});
height: calc(100vh - #{$pentest-header-height} - #{$header-height});
}
}
@ -23,7 +24,7 @@
.table-column {
overflow: auto !important;
height: calc(100vh - #{$pentest-header-height});
height: calc(100vh - #{$pentest-header-height} - #{$header-height});
}
}
}

View File

@ -2,10 +2,12 @@
"global": {
"action.login": "Einloggen",
"action.retry": "Erneut Versuchen",
"action.info": "Info",
"action.save": "Speichern",
"action.confirm": "Bestätigen",
"action.cancel": "Abbrechen",
"action.return": "Zurück",
"action.exit": "Beenden",
"action.update": "Speichern",
"action.export": "Exportieren",
"action.yes": "Ja",
@ -83,10 +85,8 @@
"not_started": "Nicht angefangen",
"disabled": "Deaktiviert",
"open": "Offen",
"checked": "Geprüft",
"reported": "Gemeldet",
"under_review": "Unter Beurteilung",
"triaged": "Triagiert"
"in_progress": "In Bearbeitung",
"completed": "Fertig"
},
"info": {
"001": "Nutze Suchmaschinenerkennung und -aufklärung für Informationslecks",

View File

@ -2,10 +2,12 @@
"global": {
"action.login": "Login",
"action.retry": "Try again",
"action.info": "Info",
"action.confirm": "Confirm",
"action.save": "Save",
"action.cancel": "Cancel",
"action.return": "Return",
"action.exit": "Exit",
"action.update": "Update",
"action.export": "Export",
"action.yes": "Yes",
@ -83,10 +85,8 @@
"not_started": "Not Started",
"disabled": "Disabled",
"open": "Open",
"checked": "Checked",
"reported": "Reported",
"under_review": "Under Review",
"triaged": "Triaged"
"in_progress": "In progress",
"completed": "Completed"
},
"info": {
"001": "Conduct Search Engine Discovery and Reconnaissance for Information Leakage",

View File

@ -1,58 +1,58 @@
import {Pentest} from '@shared/models/pentest.model';
import {Category} from '@shared/models/category.model';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
export function getAUTHN_Pentests(): Pentest[] {
return [
{
category: Category.AUTHENTICATION_TESTING,
refNumber: 'OTG-AUTHN-001',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.AUTHENTICATION_TESTING,
refNumber: 'OTG-AUTHN-002',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.AUTHENTICATION_TESTING,
refNumber: 'OTG-AUTHN-003',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.AUTHENTICATION_TESTING,
refNumber: 'OTG-AUTHN-004',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.AUTHENTICATION_TESTING,
refNumber: 'OTG-AUTHN-005',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.AUTHENTICATION_TESTING,
refNumber: 'OTG-AUTHN-006',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.AUTHENTICATION_TESTING,
refNumber: 'OTG-AUTHN-007',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.AUTHENTICATION_TESTING,
refNumber: 'OTG-AUTHN-008',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.AUTHENTICATION_TESTING,
refNumber: 'OTG-AUTHN-009',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.AUTHENTICATION_TESTING,
refNumber: 'OTG-AUTHN-010',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
}
];
}

View File

@ -1,28 +1,28 @@
import {Pentest} from '@shared/models/pentest.model';
import {Category} from '@shared/models/category.model';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
export function getAUTHZ_Pentests(): Pentest[] {
return [
{
category: Category.AUTHORIZATION_TESTING,
refNumber: 'OTG-AUTHZ-001',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.AUTHORIZATION_TESTING,
refNumber: 'OTG-AUTHZ-002',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.AUTHORIZATION_TESTING,
refNumber: 'OTG-AUTHZ-003',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.AUTHORIZATION_TESTING,
refNumber: 'OTG-AUTHZ-004',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
}
];
}

View File

@ -1,53 +1,53 @@
import {Pentest} from '@shared/models/pentest.model';
import {Category} from '@shared/models/category.model';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
export function getBUSLOGIC_Pentests(): Pentest[] {
return [
{
category: Category.BUSINESS_LOGIC_TESTING,
refNumber: 'OTG-BUSLOGIC-001',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.BUSINESS_LOGIC_TESTING,
refNumber: 'OTG-BUSLOGIC-002',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.BUSINESS_LOGIC_TESTING,
refNumber: 'OTG-BUSLOGIC-003',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.BUSINESS_LOGIC_TESTING,
refNumber: 'OTG-BUSLOGIC-004',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.BUSINESS_LOGIC_TESTING,
refNumber: 'OTG-BUSLOGIC-005',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.BUSINESS_LOGIC_TESTING,
refNumber: 'OTG-BUSLOGIC-006',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.BUSINESS_LOGIC_TESTING,
refNumber: 'OTG-BUSLOGIC-007',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.BUSINESS_LOGIC_TESTING,
refNumber: 'OTG-BUSLOGIC-008',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.BUSINESS_LOGIC_TESTING,
refNumber: 'OTG-BUSLOGIC-009',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
}
];
}

View File

@ -1,68 +1,68 @@
import {Pentest} from '@shared/models/pentest.model';
import {Category} from '@shared/models/category.model';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
export function getCLIENT_Pentests(): Pentest[] {
return [
{
category: Category.CLIENT_SIDE_TESTING,
refNumber: 'OTG-CLIENT-001',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CLIENT_SIDE_TESTING,
refNumber: 'OTG-CLIENT-002',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CLIENT_SIDE_TESTING,
refNumber: 'OTG-CLIENT-003',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CLIENT_SIDE_TESTING,
refNumber: 'OTG-CLIENT-004',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CLIENT_SIDE_TESTING,
refNumber: 'OTG-CLIENT-005',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CLIENT_SIDE_TESTING,
refNumber: 'OTG-CLIENT-006',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CLIENT_SIDE_TESTING,
refNumber: 'OTG-CLIENT-007',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CLIENT_SIDE_TESTING,
refNumber: 'OTG-CLIENT-008',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CLIENT_SIDE_TESTING,
refNumber: 'OTG-CLIENT-009',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CLIENT_SIDE_TESTING,
refNumber: 'OTG-CLIENT-010',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CLIENT_SIDE_TESTING,
refNumber: 'OTG-CLIENT-011',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CLIENT_SIDE_TESTING,
refNumber: 'OTG-CLIENT-012',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
}
];
}

View File

@ -1,48 +1,48 @@
import {Pentest} from '@shared/models/pentest.model';
import {Category} from '@shared/models/category.model';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
export function getCONFIG_Pentests(): Pentest[] {
return [
{
category: Category.CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING,
refNumber: 'OTG-CONFIG-001',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING,
refNumber: 'OTG-CONFIG-002',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING,
refNumber: 'OTG-CONFIG-003',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING,
refNumber: 'OTG-CONFIG-004',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING,
refNumber: 'OTG-CONFIG-005',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING,
refNumber: 'OTG-CONFIG-006',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING,
refNumber: 'OTG-CONFIG-007',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING,
refNumber: 'OTG-CONFIG-008',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
}
];
}

View File

@ -1,23 +1,23 @@
import {Pentest} from '@shared/models/pentest.model';
import {Category} from '@shared/models/category.model';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
export function getCRYPST_Pentests(): Pentest[] {
return [
{
category: Category.CRYPTOGRAPHY,
refNumber: 'OTG-CRYPST-001',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CRYPTOGRAPHY,
refNumber: 'OTG-CRYPST-002',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.CRYPTOGRAPHY,
refNumber: 'OTG-CRYPST-003',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
}
];
}

View File

@ -1,18 +1,18 @@
import {Pentest} from '@shared/models/pentest.model';
import {Category} from '@shared/models/category.model';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
export function getERR_Pentests(): Pentest[] {
return [
{
category: Category.ERROR_HANDLING,
refNumber: 'OTG-ERR-001',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.ERROR_HANDLING,
refNumber: 'OTG-ERR-002',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
}
];
}

View File

@ -1,43 +1,43 @@
import {Pentest} from '@shared/models/pentest.model';
import {Category} from '@shared/models/category.model';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
export function getIDENT_Pentests(): Pentest[] {
return [
{
category: Category.IDENTITY_MANAGEMENT_TESTING,
refNumber: 'OTG-IDENT-001',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.IDENTITY_MANAGEMENT_TESTING,
refNumber: 'OTG-IDENT-002',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.IDENTITY_MANAGEMENT_TESTING,
refNumber: 'OTG-IDENT-003',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.IDENTITY_MANAGEMENT_TESTING,
refNumber: 'OTG-IDENT-004',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.IDENTITY_MANAGEMENT_TESTING,
refNumber: 'OTG-IDENT-005',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.IDENTITY_MANAGEMENT_TESTING,
refNumber: 'OTG-IDENT-006',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.IDENTITY_MANAGEMENT_TESTING,
refNumber: 'OTG-IDENT-007',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
}
];
}

View File

@ -1,5 +1,5 @@
import {Pentest} from '@shared/models/pentest.model';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
import {Category} from '@shared/models/category.model';
export function getINFO_Pentests(): Pentest[] {
@ -7,52 +7,52 @@ export function getINFO_Pentests(): Pentest[] {
{
category: Category.INFORMATION_GATHERING,
refNumber: 'OTG-INFO-001',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INFORMATION_GATHERING,
refNumber: 'OTG-INFO-002',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INFORMATION_GATHERING,
refNumber: 'OTG-INFO-003',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INFORMATION_GATHERING,
refNumber: 'OTG-INFO-004',
status: Status.NOT_STARTED,
status: PentestStatus.NOT_STARTED,
},
{
category: Category.INFORMATION_GATHERING,
refNumber: 'OTG-INFO-005',
status: Status.NOT_STARTED,
status: PentestStatus.NOT_STARTED,
},
{
category: Category.INFORMATION_GATHERING,
refNumber: 'OTG-INFO-006',
status: Status.NOT_STARTED,
status: PentestStatus.NOT_STARTED,
},
{
category: Category.INFORMATION_GATHERING,
refNumber: 'OTG-INFO-007',
status: Status.NOT_STARTED,
status: PentestStatus.NOT_STARTED,
},
{
category: Category.INFORMATION_GATHERING,
refNumber: 'OTG-INFO-008',
status: Status.NOT_STARTED,
status: PentestStatus.NOT_STARTED,
},
{
category: Category.INFORMATION_GATHERING,
refNumber: 'OTG-INFO-009',
status: Status.NOT_STARTED,
status: PentestStatus.NOT_STARTED,
},
{
category: Category.INFORMATION_GATHERING,
refNumber: 'OTG-INFO-010',
status: Status.NOT_STARTED,
status: PentestStatus.NOT_STARTED,
}
];
}

View File

@ -1,149 +1,149 @@
import {Pentest} from '@shared/models/pentest.model';
import {Category} from '@shared/models/category.model';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
export function getINPVAL_Pentests(): Pentest[] {
return [
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-001',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-002',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-003',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-004',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-005',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-006',
status: Status.NOT_STARTED,
status: PentestStatus.NOT_STARTED,
childEntries: [
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-006_1',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-006_2',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-006_3',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-006_4',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-006_5',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
]
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-007',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-008',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-009',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-010',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-011',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-012',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-013',
status: Status.NOT_STARTED,
status: PentestStatus.NOT_STARTED,
childEntries: [
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-013_1',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-013_2',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
}
]
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-014',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-015',
status: Status.NOT_STARTED,
status: PentestStatus.NOT_STARTED,
childEntries: [
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-015_1',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-015_2',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-015_3',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
}
]
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-016',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.INPUT_VALIDATION_TESTING,
refNumber: 'OTG-INPVAL-017',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
];
}

View File

@ -1,48 +1,48 @@
import {Pentest} from '@shared/models/pentest.model';
import {Category} from '@shared/models/category.model';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
export function getSESS_Pentests(): Pentest[] {
return [
{
category: Category.SESSION_MANAGEMENT_TESTING,
refNumber: 'OTG-SESS-001',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.SESSION_MANAGEMENT_TESTING,
refNumber: 'OTG-SESS-002',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.SESSION_MANAGEMENT_TESTING,
refNumber: 'OTG-SESS-003',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.SESSION_MANAGEMENT_TESTING,
refNumber: 'OTG-SESS-004',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.SESSION_MANAGEMENT_TESTING,
refNumber: 'OTG-SESS-005',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.SESSION_MANAGEMENT_TESTING,
refNumber: 'OTG-SESS-006',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.SESSION_MANAGEMENT_TESTING,
refNumber: 'OTG-SESS-007',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
},
{
category: Category.SESSION_MANAGEMENT_TESTING,
refNumber: 'OTG-SESS-008',
status: Status.NOT_STARTED
status: PentestStatus.NOT_STARTED
}
];
}

View File

@ -0,0 +1,7 @@
export enum PentestStatus {
NOT_STARTED = 'NOT_STARTED',
DISABLED = 'DISABLED',
OPEN = 'OPEN',
IN_PROGRESS = 'IN_PROGRESS',
COMPLETED = 'COMPLETED',
}

View File

@ -1,5 +1,5 @@
import {v4 as UUID} from 'uuid';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
import {Category} from '@shared/models/category.model';
export class Pentest {
@ -7,13 +7,13 @@ export class Pentest {
category: Category;
refNumber: string;
childEntries?: Pentest[];
status: Status;
status: PentestStatus;
findingsIds?: Array<string>;
commentsIds?: Array<string>;
constructor(category: Category,
refNumber: string,
status: Status,
status: PentestStatus,
id?: string,
findingsIds?: Array<string>,
commentsIds?: Array<string>) {

View File

@ -1,5 +1,5 @@
export enum Route {
HOME = 'home',
PROJECT_OVERVIEW = 'projects',
PENTEST = 'pentest'
PENTEST_OVERVIEW = 'pentest'
}

View File

@ -1,9 +0,0 @@
export enum Status {
NOT_STARTED = 'NOT_STARTED',
DISABLED = 'DISABLED',
OPEN = 'OPEN',
CHECKED = 'CHECKED',
REPORTED = 'REPORTED',
UNDER_REVIEW = 'UNDER_REVIEW',
TRIAGED = 'TRIAGED'
}

View File

@ -93,6 +93,7 @@ export const mockProject: Project = {
client: 'Testclient',
tester: 'Testpentester',
createdAt: new Date(),
testingProgress: 0,
createdBy: 'UID-11-12-13'
};

View File

@ -41,6 +41,7 @@ describe('ProjectService', () => {
title: 'Some Mock API (v1.0) Scanning',
createdAt: dummyDate,
tester: 'Novatester',
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
};
@ -89,6 +90,7 @@ describe('ProjectService', () => {
title: 'Some Mock API (v1.0) Scanning',
createdAt: dummyDate,
tester: 'Novatester',
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
};

View File

@ -1,5 +1,6 @@
import {Project} from '@shared/models/project.model';
import {Category} from '@shared/models/category.model';
import {Pentest} from '@shared/models/pentest.model';
export class InitProjectState {
@ -29,6 +30,6 @@ export class ChangeCategory {
export class ChangePentest {
static readonly type = '[ProjectState] ChangePentest';
constructor(public pentestId: string) {
constructor(public pentest: Pentest) {
}
}

View File

@ -12,7 +12,7 @@ const INITIAL_PROJECT_STATE_SESSION: ProjectStateModel = {
disabledCategories: [],
selectedCategory: Category.INFORMATION_GATHERING,
disabledPentests: [],
selectedPentestId: null
selectedPentest: null
};
const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
@ -20,7 +20,7 @@ const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
disabledCategories: [],
selectedCategory: Category.INFORMATION_GATHERING,
disabledPentests: [],
selectedPentestId: null
selectedPentest: null
};
describe('SessionState', () => {

View File

@ -3,6 +3,7 @@ import {Injectable} from '@angular/core';
import {Project} from '@shared/models/project.model';
import {ChangeCategory, ChangePentest, ChangeProject, InitProjectState} from '@shared/stores/project-state/project-state.actions';
import {Category} from '@shared/models/category.model';
import {Pentest} from '@shared/models/pentest.model';
export const PROJECT_STATE_NAME = 'project';
@ -13,7 +14,7 @@ export interface ProjectStateModel {
selectedCategory: Category;
// Manages Pentests of Category
disabledPentests: Array<string>;
selectedPentestId: string;
selectedPentest: Pentest;
}
@State<ProjectStateModel>({
@ -23,7 +24,7 @@ export interface ProjectStateModel {
disabledCategories: [],
selectedCategory: Category.INFORMATION_GATHERING,
disabledPentests: [],
selectedPentestId: null
selectedPentest: null
}
})
@Injectable()
@ -39,8 +40,8 @@ export class ProjectState {
}
@Selector()
static selectedPentestId(state: ProjectStateModel): string {
return state.selectedPentestId;
static pentest(state: ProjectStateModel): Pentest {
return state.selectedPentest;
}
@Action(InitProjectState)
@ -50,7 +51,7 @@ export class ProjectState {
disabledCategories: action.disabledCategories,
selectedCategory: Category.INFORMATION_GATHERING,
disabledPentests: action.disabledPentests,
selectedPentestId: null
selectedPentest: null
});
}
@ -73,10 +74,10 @@ export class ProjectState {
}
@Action(ChangePentest)
changePentest(ctx: StateContext<ProjectStateModel>, {pentestId}: ChangePentest): void {
changePentest(ctx: StateContext<ProjectStateModel>, {pentest}: ChangePentest): void {
const state = ctx.getState();
ctx.patchState({
selectedPentestId: pentestId
selectedPentest: pentest
});
}
}

View File

@ -2,13 +2,9 @@
<nb-tag-list>
<nb-tag *ngSwitchCase="status.OPEN" status="info" appearance="filled"
text="{{getTranslationKey() | translate}}"></nb-tag>
<nb-tag *ngSwitchCase="status.CHECKED" status="primary" appearance="filled"
text="{{getTranslationKey() | translate}}"></nb-tag>
<nb-tag *ngSwitchCase="status.REPORTED" status="danger" appearance="filled"
text="{{getTranslationKey() | translate}}"></nb-tag>
<nb-tag *ngSwitchCase="status.UNDER_REVIEW" status="warning" appearance="filled"
<nb-tag *ngSwitchCase="status.IN_PROGRESS" status="warning" appearance="filled"
text=" {{getTranslationKey() | translate}}"></nb-tag>
<nb-tag *ngSwitchCase="status.TRIAGED" status="success" appearance="filled"
<nb-tag *ngSwitchCase="status.COMPLETED" status="success" appearance="filled"
text="{{getTranslationKey() | translate}}"></nb-tag>
<nb-tag *ngSwitchDefault status="basic" appearance="filled"
text="{{getTranslationKey() | translate}}"></nb-tag>

View File

@ -1,5 +1,5 @@
import {ChangeDetectionStrategy, Component, Input, OnInit} from '@angular/core';
import {Status} from '@shared/models/status.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
@Component({
selector: 'app-status-tag',
@ -8,18 +8,16 @@ import {Status} from '@shared/models/status.model';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class StatusTagComponent implements OnInit {
@Input() currentStatus: Status = Status.NOT_STARTED;
@Input() currentStatus: PentestStatus = PentestStatus.NOT_STARTED;
// HTML only
status = Status;
status = PentestStatus;
readonly statusTexts: Array<StatusText> = [
{value: Status.NOT_STARTED, translationText: 'pentest.statusText.not_started'},
{value: Status.DISABLED, translationText: 'pentest.statusText.disabled'},
{value: Status.OPEN, translationText: 'pentest.statusText.open'},
{value: Status.CHECKED, translationText: 'pentest.statusText.checked'},
{value: Status.REPORTED, translationText: 'pentest.statusText.reported'},
{value: Status.UNDER_REVIEW, translationText: 'pentest.statusText.under_review'},
{value: Status.TRIAGED, translationText: 'pentest.statusText.triaged'}
{value: PentestStatus.NOT_STARTED, translationText: 'pentest.statusText.not_started'},
{value: PentestStatus.DISABLED, translationText: 'pentest.statusText.disabled'},
{value: PentestStatus.OPEN, translationText: 'pentest.statusText.open'},
{value: PentestStatus.IN_PROGRESS, translationText: 'pentest.statusText.in_progress'},
{value: PentestStatus.COMPLETED, translationText: 'pentest.statusText.completed'}
];
constructor() { }

View File

@ -3,9 +3,6 @@ package com.securityc4po.api.pentest
enum class PentestStatus {
NOT_STARTED,
OPEN,
UNDER_REVIEW,
DISABLED,
CHECKED,
REPORTED,
TRIAGED
IN_PROGRESS,
COMPLETED
}

View File

@ -3,6 +3,7 @@ package com.securityc4po.api.project
import com.fasterxml.jackson.annotation.JsonFormat
import com.securityc4po.api.ResponseBody
import com.securityc4po.api.pentest.PentestStatus
import org.springframework.beans.factory.annotation.Value
import org.springframework.data.mongodb.core.index.Indexed
import java.math.RoundingMode
import java.text.DecimalFormat
@ -52,9 +53,13 @@ fun Project.toProjectDeleteResponseBody(): ResponseBody {
)
}
fun Project.calculateProgress(): Float {
// Total number of pentests listet in the OWASP testing guide
// https://owasp.org/www-project-web-security-testing-guide/assets/archive/OWASP_Testing_Guide_v4.pdf
// @Value("\${owasp.web.pentests}")
// lateinit var TOTALPENTESTS: Int
val TOTALPENTESTS = 95
return if (projectPentests.isEmpty())
@ -62,7 +67,7 @@ fun Project.calculateProgress(): Float {
else {
var completedPentests = 0
projectPentests.forEach { projectPentest ->
if (projectPentest.status == PentestStatus.TRIAGED) {
if (projectPentest.status == PentestStatus.COMPLETED) {
completedPentests++
}
}

View File

@ -19,4 +19,8 @@ spring.data.mongodb.auto-index-creation=true
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8888/auth/realms/c4po_realm_local
keycloakhost=localhost
keycloak.client.url=http://localhost:8888
keycloak.client.realm.path=auth/realms/c4po_realm_local/
keycloak.client.realm.path=auth/realms/c4po_realm_local/
## Total number of pentests listet in the OWASP testing guide
## https://owasp.org/www-project-web-security-testing-guide/assets/archive/OWASP_Testing_Guide_v4.pdf
owasp.web.pentests=95

View File

@ -106,7 +106,7 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
category = PentestCategory.INFORMATION_GATHERING,
title = "Fingerprint Web Server",
refNumber = "OTG-INFO-002",
status = PentestStatus.REPORTED,
status = PentestStatus.IN_PROGRESS,
findingIds = emptyList(),
commentIds = emptyList()
)
@ -135,7 +135,7 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
category = PentestCategory.INFORMATION_GATHERING,
title = "Fingerprint Web Server",
refNumber = "OTG-INFO-002",
status = PentestStatus.REPORTED,
status = PentestStatus.IN_PROGRESS,
findingIds = emptyList(),
commentIds = emptyList()
)
@ -145,7 +145,7 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
category = PentestCategory.AUTHENTICATION_TESTING,
title = "Testing for Credentials Transported over an Encrypted Channel",
refNumber = "OTG-AUTHN-001",
status = PentestStatus.CHECKED,
status = PentestStatus.COMPLETED,
findingIds = emptyList(),
commentIds = emptyList()
)

View File

@ -81,7 +81,7 @@ class PentestControllerIntTest : BaseIntTest() {
category = PentestCategory.INFORMATION_GATHERING,
title = "Fingerprint Web Server",
refNumber = "OTG-INFO-002",
status = PentestStatus.REPORTED,
status = PentestStatus.IN_PROGRESS,
findingIds = emptyList(),
commentIds = emptyList()
)
@ -110,7 +110,7 @@ class PentestControllerIntTest : BaseIntTest() {
category = PentestCategory.INFORMATION_GATHERING,
title = "Fingerprint Web Server",
refNumber = "OTG-INFO-002",
status = PentestStatus.REPORTED,
status = PentestStatus.COMPLETED,
findingIds = emptyList(),
commentIds = emptyList()
)
@ -120,7 +120,7 @@ class PentestControllerIntTest : BaseIntTest() {
category = PentestCategory.AUTHENTICATION_TESTING,
title = "Testing for Credentials Transported over an Encrypted Channel",
refNumber = "OTG-AUTHN-001",
status = PentestStatus.CHECKED,
status = PentestStatus.COMPLETED,
findingIds = emptyList(),
commentIds = emptyList()
)