feat: refactor project model in order to calculate progress

This commit is contained in:
mhg 2022-08-10 18:22:46 +02:00
parent 24dccb3e8f
commit 4a2024dd69
23 changed files with 177 additions and 93 deletions

View File

@ -1,16 +1,10 @@
# security-c4po # security-c4po
### Chief Innovator ## Application Architecture
> Daniel Mader ![alt architecture](./wiki/C4PO-Architecture.png)
### Project Leads ## Data Structure
* Andreas Falk ![alt datastructure](./wiki/C4PO-Datastructure.png)
* Christina Paule
### Developers
* Marcel Haag
* Norman Schmidt
* Stipe Knez
### Technical Requirements ### Technical Requirements
* Docker / Docker-compose * Docker / Docker-compose
@ -22,12 +16,6 @@
* mongoDB Compass * mongoDB Compass
* Postman * Postman
## Application Architecture
![alt architecture](./wiki/C4PO-Architecture.png)
## Data Structure
![alt datastructure](./wiki/C4PO-Datastructure.png)
### Conventions ### Conventions
* Branch: `<initial>_c4po_<issuenumber>` * Branch: `<initial>_c4po_<issuenumber>`
* Commit: `feat: <What was implemented?>` or `fix: <What got fixed?>` * Commit: `feat: <What was implemented?>` or `fix: <What got fixed?>`

View File

@ -9,7 +9,7 @@
.export-button-container { .export-button-container {
display: flex; display: flex;
align-content: flex-end; align-content: flex-end;
margin-right: 1rem; margin-right: 0.5rem;
.export-element-icon { .export-element-icon {
} }

View File

@ -20,17 +20,14 @@ import {RouterModule} from '@angular/router';
import {FormsModule} from '@angular/forms'; import {FormsModule} from '@angular/forms';
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome'; import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
import {FlexLayoutModule} from '@angular/flex-layout'; import {FlexLayoutModule} from '@angular/flex-layout';
import {LoadingSpinnerComponent} from '@shared/widgets/loading-spinner/loading-spinner.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
PentestHeaderComponent, PentestHeaderComponent,
PentestCategoriesComponent, PentestCategoriesComponent,
PentestTableComponent PentestTableComponent,
], // LoadingSpinnerComponent
exports: [
PentestHeaderComponent,
PentestCategoriesComponent,
PentestTableComponent
], ],
imports: [ imports: [
CommonModule, CommonModule,
@ -52,6 +49,12 @@ import {FlexLayoutModule} from '@angular/flex-layout';
FontAwesomeModule, FontAwesomeModule,
FlexLayoutModule, FlexLayoutModule,
NbActionsModule NbActionsModule
],
exports: [
PentestHeaderComponent,
PentestCategoriesComponent,
PentestTableComponent,
// LoadingSpinnerComponent
] ]
}) })
export class PentestOverviewModule { export class PentestOverviewModule {

View File

@ -48,8 +48,11 @@
</th> </th>
<td nbTreeGridCell *nbTreeGridCellDef="let pentest"> <td nbTreeGridCell *nbTreeGridCellDef="let pentest">
<app-findig-widget [numberOfFindigs]="pentest.data['findings']"></app-findig-widget> <app-findig-widget [numberOfFindigs]="pentest.data['findings']"></app-findig-widget>
<!--{{pentest.data['findings'] || '-'}}--> <!--ToDo: Add comments {{pentest.data['comments'] || '-'}}-->
</td> </td>
</ng-container> </ng-container>
</table> </table>
</nb-card> </nb-card>
<!--ToDo: Add loading spinner after routing fix to avoid circular dependency issues
<app-loading-spinner [isLoading$]="isLoading()" *ngIf="isLoading() | async"></app-loading-spinner>-->

View File

@ -5,8 +5,8 @@ import {PentestService} from '@shared/services/pentest.service';
import {Store} from '@ngxs/store'; import {Store} from '@ngxs/store';
import {PROJECT_STATE_NAME, ProjectState} from '@shared/stores/project-state/project-state'; import {PROJECT_STATE_NAME, ProjectState} from '@shared/stores/project-state/project-state';
import {UntilDestroy, untilDestroyed} from '@ngneat/until-destroy'; import {UntilDestroy, untilDestroyed} from '@ngneat/until-destroy';
import {catchError, switchMap} from 'rxjs/operators'; import {catchError, switchMap, tap} from 'rxjs/operators';
import {of} from 'rxjs'; import {BehaviorSubject, Observable, of} from 'rxjs';
import {getTitleKeyForRefNumber} from '@shared/functions/categories/get-title-key-for-ref-number.function'; import {getTitleKeyForRefNumber} from '@shared/functions/categories/get-title-key-for-ref-number.function';
import {Route} from '@shared/models/route.enum'; import {Route} from '@shared/models/route.enum';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
@ -20,6 +20,7 @@ import {ChangePentest} from '@shared/stores/project-state/project-state.actions'
}) })
export class PentestTableComponent implements OnInit { export class PentestTableComponent implements OnInit {
loading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
columns: Array<PentestColumns> = [PentestColumns.TEST_ID, PentestColumns.TITLE, PentestColumns.STATUS, PentestColumns.FINDINGS]; columns: Array<PentestColumns> = [PentestColumns.TEST_ID, PentestColumns.TITLE, PentestColumns.STATUS, PentestColumns.FINDINGS];
dataSource: NbTreeGridDataSource<PentestEntry>; dataSource: NbTreeGridDataSource<PentestEntry>;
@ -47,14 +48,17 @@ export class PentestTableComponent implements OnInit {
loadPentestData(): void { loadPentestData(): void {
this.store.select(ProjectState.selectedCategory).pipe( this.store.select(ProjectState.selectedCategory).pipe(
switchMap(category => this.pentestService.loadPentests(category)), switchMap(category => this.pentestService.loadPentests(category)),
tap(() => this.loading$.next(true)),
catchError(_ => of(null)), catchError(_ => of(null)),
untilDestroyed(this) untilDestroyed(this)
).subscribe({ ).subscribe({
next: (pentests: Pentest[]) => { next: (pentests: Pentest[]) => {
this.data = transformPentestsToEntries(pentests); this.data = transformPentestsToEntries(pentests);
this.dataSource.setData(this.data, this.getters); this.dataSource.setData(this.data, this.getters);
this.loading$.next(false);
}, },
error: error => { error: error => {
this.loading$.next(false);
console.error(error); console.error(error);
} }
}); });
@ -78,6 +82,11 @@ export class PentestTableComponent implements OnInit {
getTitle(refNumber: string): string { getTitle(refNumber: string): string {
return getTitleKeyForRefNumber(refNumber); return getTitleKeyForRefNumber(refNumber);
} }
// HTML only
isLoading(): Observable<boolean> {
return this.loading$.asObservable();
}
} }
enum PentestColumns { enum PentestColumns {

View File

@ -34,13 +34,20 @@
</span> </span>
</nb-card-body> </nb-card-body>
<nb-card-footer> <nb-card-footer>
<!--ToDo: Display correct progress of project-->
<div fxLayout="row" fxLayoutGap="1rem" fxLayoutAlign="start end"> <div fxLayout="row" fxLayoutGap="1rem" fxLayoutAlign="start end">
<nb-progress-bar class="project-progress" <div class="project-progress">
status="warning"
[value]="40" <nb-progress-bar *ngIf="project.testingProgress > 0; else altProgressBar"
[displayValue]="true"> status="warning"
</nb-progress-bar> [value]="project.testingProgress"
[displayValue]="true">
</nb-progress-bar>
<ng-template #altProgressBar>
{{'popup.info' | translate}} {{'global.no.progress' | translate}}
</ng-template>
</div>
<button nbButton <button nbButton
status="primary" status="primary"
size="small" size="small"
@ -61,7 +68,7 @@
</div> </div>
</div> </div>
<div *ngIf="projects.getValue().length === 0 || !isLoading()" fxLayout="row" fxLayoutAlign="center center"> <div *ngIf="projects.getValue().length === 0 && loading$.getValue() === false" fxLayout="row" fxLayoutAlign="center center">
<p class="error-text"> <p class="error-text">
{{'project.overview.no.projects' | translate}} {{'project.overview.no.projects' | translate}}
</p> </p>

View File

@ -131,6 +131,7 @@ export class ProjectOverviewComponent implements OnInit {
}); });
} }
// HTML only
isLoading(): Observable<boolean> { isLoading(): Observable<boolean> {
return this.loading$.asObservable(); return this.loading$.asObservable();
} }

View File

@ -2,7 +2,7 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {ProjectOverviewComponent} from './project-overview.component'; import {ProjectOverviewComponent} from './project-overview.component';
import {ProjectOverviewRoutingModule} from './project-overview-routing.module'; import {ProjectOverviewRoutingModule} from './project-overview-routing.module';
import {NbButtonModule, NbCardModule, NbMenuModule, NbProgressBarModule, NbSidebarModule, NbSpinnerModule} from '@nebular/theme'; import {NbButtonModule, NbCardModule, NbProgressBarModule, NbSpinnerModule} from '@nebular/theme';
import {FlexLayoutModule} from '@angular/flex-layout'; import {FlexLayoutModule} from '@angular/flex-layout';
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome'; import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
import {TranslateModule} from '@ngx-translate/core'; import {TranslateModule} from '@ngx-translate/core';

View File

@ -2,7 +2,7 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {RouterModule} from '@angular/router'; import {RouterModule} from '@angular/router';
import {ProjectComponent} from './project.component'; import {ProjectComponent} from './project.component';
import {NbCardModule, NbLayoutModule, NbMenuModule, NbSidebarModule} from '@nebular/theme'; import {NbCardModule, NbLayoutModule} from '@nebular/theme';
import {FlexLayoutModule} from '@angular/flex-layout'; import {FlexLayoutModule} from '@angular/flex-layout';
import {TranslateModule} from '@ngx-translate/core'; import {TranslateModule} from '@ngx-translate/core';
import {ProjectDialogModule} from '@shared/modules/project-dialog/project-dialog.module'; import {ProjectDialogModule} from '@shared/modules/project-dialog/project-dialog.module';
@ -13,9 +13,6 @@ import {PentestOverviewModule} from '../../pentest-overview';
declarations: [ declarations: [
ProjectComponent ProjectComponent
], ],
exports: [
ProjectComponent
],
imports: [ imports: [
CommonModule, CommonModule,
NbCardModule, NbCardModule,
@ -29,6 +26,9 @@ import {PentestOverviewModule} from '../../pentest-overview';
FlexLayoutModule, FlexLayoutModule,
ProjectDialogModule, ProjectDialogModule,
PentestOverviewModule PentestOverviewModule
],
exports: [
ProjectComponent
] ]
}) })
export class ProjectModule { export class ProjectModule {

View File

@ -11,7 +11,8 @@
"action.yes": "Ja", "action.yes": "Ja",
"action.no": "Nein", "action.no": "Nein",
"username": "Nutzername", "username": "Nutzername",
"password": "Passwort" "password": "Passwort",
"no.progress": "Kein Fortschritt"
}, },
"languageKeys":{ "languageKeys":{
"de-DE": "Deutsch", "de-DE": "Deutsch",

View File

@ -11,7 +11,8 @@
"action.yes": "Yes", "action.yes": "Yes",
"action.no": "No", "action.no": "No",
"username": "Username", "username": "Username",
"password": "Password" "password": "Password",
"no.progress": "No progress"
}, },
"languageKeys":{ "languageKeys":{
"de-DE": "German", "de-DE": "German",

View File

@ -4,19 +4,22 @@ export class Project {
title: string; title: string;
createdAt: Date; createdAt: Date;
tester: string; tester: string;
testingProgress: number;
createdBy: string; createdBy: string;
constructor(id: string, constructor(id: string,
client: string, client: string,
title: string, title: string,
createdAt: Date, createdAt: Date,
tester?: string, tester: string,
testingProgress: number,
createdBy?: string) { createdBy?: string) {
this.id = id; this.id = id;
this.client = client; this.client = client;
this.title = title; this.title = title;
this.createdAt = createdAt; this.createdAt = createdAt;
this.tester = tester; this.tester = tester;
this.testingProgress = testingProgress;
this.createdBy = createdBy; this.createdBy = createdBy;
} }
} }

View File

@ -70,7 +70,7 @@
"header": [], "header": [],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"client\": \"Novatec\",\n \"title\": \"log4j pentest\",\n \"tester\" : \"Stipe\",\n \"createdBy\" : \"10e06d7a-8dd0-4ecd-8963-056b45079c4f\"\n}", "raw": "{\n \"client\": \"Novatec\",\n \"title\": \"log4j pentest\",\n \"tester\" : \"Stipe\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -142,7 +142,7 @@
"header": [], "header": [],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"client\": \"updatedProject\",\n \"title\": \"log4j pentest\",\n \"tester\" : \"Stipe\"\n}", "raw": "{\n \"client\": \"Dio Stonemask Inc.\",\n \"title\": \"log4jj bizarre adventure\",\n \"tester\" : \"Jojo\"\n}",
"options": { "options": {
"raw": { "raw": {
"language": "json" "language": "json"
@ -150,7 +150,7 @@
} }
}, },
"url": { "url": {
"raw": "http://localhost:8443/projects/f2738715-4005-4aca-8d34-27ce9b8efffe", "raw": "http://localhost:8443/projects/5a4f126c-9471-43b8-80b9-6eb02b7c35d0",
"protocol": "http", "protocol": "http",
"host": [ "host": [
"localhost" "localhost"
@ -158,7 +158,7 @@
"port": "8443", "port": "8443",
"path": [ "path": [
"projects", "projects",
"f2738715-4005-4aca-8d34-27ce9b8efffe" "5a4f126c-9471-43b8-80b9-6eb02b7c35d0"
] ]
} }
}, },
@ -261,10 +261,24 @@
{ {
"name": "getPentestsByProjectIdAndCategory", "name": "getPentestsByProjectIdAndCategory",
"request": { "request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICItdG1lbEV0ZHhGTnRSMW9aNXlRdE5jaFFpX0RVN2VNeV9YcU44aXY0S3hzIn0.eyJleHAiOjE2NjAxNDI5NjMsImlhdCI6MTY2MDE0MjY2MywianRpIjoiNzk2YzY5NzYtZjBlYS00ZTM0LTk2MTItMjI5ZmE0ODgzOTM0IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4ODg4L2F1dGgvcmVhbG1zL2M0cG9fcmVhbG1fbG9jYWwiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiMTBlMDZkN2EtOGRkMC00ZWNkLTg5NjMtMDU2YjQ1MDc5YzRmIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYzRwb19sb2NhbCIsInNlc3Npb25fc3RhdGUiOiIyYWU1MmQyYy01MjA5LTQzMjEtOWY5OS0wMTQ2YjRkMmNkY2YiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImM0cG9fdXNlciIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJjNHBvX2xvY2FsIjp7InJvbGVzIjpbInVzZXIiXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6InRlc3QgdXNlciIsInByZWZlcnJlZF91c2VybmFtZSI6InR0dCIsImdpdmVuX25hbWUiOiJ0ZXN0IiwiZmFtaWx5X25hbWUiOiJ1c2VyIn0.EO5CC1VXZzybIx-lndq3b61TZpWOnYDI4F2CUFuxj5ECxrlIfm_tlv0TbErDTX311YsA_nhzNHYSaffRzx0OkmmUKSyyH8k9aPRKXUTUmY7Y9PLv3UCKEmAFHAnJkr5kZV08g3UMYG2blpryYBg82abEVMxeMUbh-T4M-Z9dcgQyiZ4nyNMUs1bbfH_2kAtqfEXmP_9eZ42Kwa2ixFWFZDcvOp775bjkYcGvwSnHqmyBXivONzTxyPN6Ug7uFCvMTbeo10ctgOFfXJUZfoxRt-hCspTPJR8C4TzIK41fiy19uRpGjeezG5Ghwy9upXsomunwB4knTAn1otmj4afIxw",
"type": "string"
},
{
"key": "undefined",
"type": "any"
}
]
},
"method": "GET", "method": "GET",
"header": [], "header": [],
"url": { "url": {
"raw": "http://localhost:8443/pentests?projectId=8bc16303-f652-418a-b745-8a03d89356fb&category=INFORMATION_GATHERING", "raw": "http://localhost:8443/pentests?projectId=5a4f126c-9471-43b8-80b9-6eb02b7c35d0&category=INFORMATION_GATHERING",
"protocol": "http", "protocol": "http",
"host": [ "host": [
"localhost" "localhost"
@ -276,7 +290,7 @@
"query": [ "query": [
{ {
"key": "projectId", "key": "projectId",
"value": "8bc16303-f652-418a-b745-8a03d89356fb" "value": "5a4f126c-9471-43b8-80b9-6eb02b7c35d0"
}, },
{ {
"key": "category", "key": "category",

View File

@ -12,8 +12,8 @@ data class Pentest(
val title: String, val title: String,
val refNumber: String, val refNumber: String,
val status: PentestStatus, val status: PentestStatus,
val findingIds: String, val findingIds: List<String> = emptyList(),
val commentIds: String val commentIds: List<String> = emptyList()
) )
fun Pentest.toPentestResponseBody(): ResponseBody { fun Pentest.toPentestResponseBody(): ResponseBody {

View File

@ -2,7 +2,10 @@ package com.securityc4po.api.project
import com.fasterxml.jackson.annotation.JsonFormat import com.fasterxml.jackson.annotation.JsonFormat
import com.securityc4po.api.ResponseBody import com.securityc4po.api.ResponseBody
import com.securityc4po.api.pentest.PentestStatus
import org.springframework.data.mongodb.core.index.Indexed import org.springframework.data.mongodb.core.index.Indexed
import java.math.RoundingMode
import java.text.DecimalFormat
import java.time.Instant import java.time.Instant
import java.util.UUID import java.util.UUID
@ -14,6 +17,7 @@ data class Project(
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssZ") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssZ")
val createdAt: String = Instant.now().toString(), val createdAt: String = Instant.now().toString(),
val tester: String? = null, val tester: String? = null,
val projectPentests: List<ProjectPentest> = emptyList(),
val createdBy: String val createdBy: String
) )
@ -24,6 +28,7 @@ fun buildProject(body: ProjectRequestBody, projectEntity: ProjectEntity): Projec
title = body.title, title = body.title,
createdAt = projectEntity.data.createdAt, createdAt = projectEntity.data.createdAt,
tester = body.tester, tester = body.tester,
projectPentests = projectEntity.data.projectPentests,
createdBy = projectEntity.data.createdBy createdBy = projectEntity.data.createdBy
) )
} }
@ -35,6 +40,8 @@ fun Project.toProjectResponseBody(): ResponseBody {
"title" to title, "title" to title,
"createdAt" to createdAt, "createdAt" to createdAt,
"tester" to tester, "tester" to tester,
/* ToDo: Calculate percentage in BE type: float */
"testingProgress" to calculateProgress(),
"createdBy" to createdBy "createdBy" to createdBy
) )
} }
@ -45,16 +52,31 @@ 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
val TOTALPENTESTS = 95
return if (projectPentests.isEmpty())
0F
else {
var completedPentests = 0
projectPentests.forEach { projectPentest ->
if (projectPentest.status == PentestStatus.TRIAGED) {
completedPentests++
}
}
val df = DecimalFormat("#.##")
df.roundingMode = RoundingMode.DOWN
val progress = completedPentests / TOTALPENTESTS
df.format(progress).toFloat()
}
}
data class ProjectOverview( data class ProjectOverview(
val projects: List<Project> val projects: List<Project>
) )
fun ProjectOverview.toProjectOverviewResponseBody(): ResponseBody {
return mapOf(
"projects" to projects
)
}
data class ProjectRequestBody( data class ProjectRequestBody(
val client: String, val client: String,
val title: String, val title: String,

View File

@ -30,7 +30,8 @@ class ProjectController(private val projectService: ProjectService) {
it.toProjectResponseBody() it.toProjectResponseBody()
} }
}.map { }.map {
ResponseEntity.ok(it) if (it.isEmpty()) ResponseEntity.noContent().build()
else ResponseEntity.ok(it)
} }
} }

View File

@ -18,6 +18,7 @@ fun ProjectEntity.toProject() : Project {
this.data.title, this.data.title,
this.data.createdAt, this.data.createdAt,
this.data.tester, this.data.tester,
this.data.projectPentests,
this.data.createdBy this.data.createdBy
) )
} }

View File

@ -0,0 +1,8 @@
package com.securityc4po.api.project
import com.securityc4po.api.pentest.PentestStatus
data class ProjectPentest(
val pentestId: String,
val status: PentestStatus
)

View File

@ -102,8 +102,10 @@ class ProjectService(private val projectRepository: ProjectRepository) {
) )
) )
return projectRepository.findProjectById(id).switchIfEmpty{ return projectRepository.findProjectById(id).switchIfEmpty{
logger.info("Project with id $id not found. Updating not possible.") logger.warn("Project with id $id not found. Updating not possible.")
Mono.empty() val msg = "Project with id $id not found."
val ex = EntityNotFoundException(msg, Errorcode.ProjectNotFound)
throw ex
}.flatMap{projectEntity: ProjectEntity -> }.flatMap{projectEntity: ProjectEntity ->
projectEntity.lastModified = Instant.now() projectEntity.lastModified = Instant.now()
projectEntity.data = buildProject(body, projectEntity) projectEntity.data = buildProject(body, projectEntity)
@ -120,4 +122,15 @@ class ProjectService(private val projectRepository: ProjectRepository) {
} }
} }
} }
/**
* Update testing progress of [Project]
*
* @throws [TransactionInterruptedException] if the [Project] could not be updated
* @return updated list of [ProjectPentest]s
*/
fun updateProjectTestingProgress(projectId: String, projectPentests: ProjectPentest)/*: Mono<List<ProjectPentest>>*/ {
// ToDo: update Project Entity with progress
}
} }

View File

@ -97,8 +97,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
title = "Search engine discovery/reconnaissance", title = "Search engine discovery/reconnaissance",
refNumber = "OTG-INFO-001", refNumber = "OTG-INFO-001",
status = PentestStatus.NOT_STARTED, status = PentestStatus.NOT_STARTED,
findingIds = "", findingIds = emptyList(),
commentIds = "" commentIds = emptyList()
) )
private val pentestTwo = Pentest( private val pentestTwo = Pentest(
id = "43fbc63c-f624-11ec-b939-0242ac120002", id = "43fbc63c-f624-11ec-b939-0242ac120002",
@ -107,8 +107,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
title = "Fingerprint Web Server", title = "Fingerprint Web Server",
refNumber = "OTG-INFO-002", refNumber = "OTG-INFO-002",
status = PentestStatus.REPORTED, status = PentestStatus.REPORTED,
findingIds = "", findingIds = emptyList(),
commentIds = "" commentIds = emptyList()
) )
private fun getProjectsResponse() = listOf( private fun getProjectsResponse() = listOf(
@ -126,8 +126,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
title = "Search engine discovery/reconnaissance", title = "Search engine discovery/reconnaissance",
refNumber = "OTG-INFO-001", refNumber = "OTG-INFO-001",
status = PentestStatus.NOT_STARTED, status = PentestStatus.NOT_STARTED,
findingIds = "", findingIds = emptyList(),
commentIds = "" commentIds = emptyList()
) )
val pentestTwo = Pentest( val pentestTwo = Pentest(
id = "43fbc63c-f624-11ec-b939-0242ac120002", id = "43fbc63c-f624-11ec-b939-0242ac120002",
@ -136,8 +136,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
title = "Fingerprint Web Server", title = "Fingerprint Web Server",
refNumber = "OTG-INFO-002", refNumber = "OTG-INFO-002",
status = PentestStatus.REPORTED, status = PentestStatus.REPORTED,
findingIds = "", findingIds = emptyList(),
commentIds = "" commentIds = emptyList()
) )
val pentestThree = Pentest( val pentestThree = Pentest(
id = "74eae112-f62c-11ec-b939-0242ac120002", id = "74eae112-f62c-11ec-b939-0242ac120002",
@ -146,8 +146,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
title = "Testing for Credentials Transported over an Encrypted Channel", title = "Testing for Credentials Transported over an Encrypted Channel",
refNumber = "OTG-AUTHN-001", refNumber = "OTG-AUTHN-001",
status = PentestStatus.CHECKED, status = PentestStatus.CHECKED,
findingIds = "", findingIds = emptyList(),
commentIds = "" commentIds = emptyList()
) )
// persist test data in database // persist test data in database
mongoTemplate.save(PentestEntity(pentestOne)) mongoTemplate.save(PentestEntity(pentestOne))

View File

@ -72,8 +72,8 @@ class PentestControllerIntTest : BaseIntTest() {
title = "Search engine discovery/reconnaissance", title = "Search engine discovery/reconnaissance",
refNumber = "OTG-INFO-001", refNumber = "OTG-INFO-001",
status = PentestStatus.NOT_STARTED, status = PentestStatus.NOT_STARTED,
findingIds = "", findingIds = emptyList(),
commentIds = "" commentIds = emptyList()
) )
private val pentestTwo = Pentest( private val pentestTwo = Pentest(
id = "43fbc63c-f624-11ec-b939-0242ac120002", id = "43fbc63c-f624-11ec-b939-0242ac120002",
@ -82,8 +82,8 @@ class PentestControllerIntTest : BaseIntTest() {
title = "Fingerprint Web Server", title = "Fingerprint Web Server",
refNumber = "OTG-INFO-002", refNumber = "OTG-INFO-002",
status = PentestStatus.REPORTED, status = PentestStatus.REPORTED,
findingIds = "", findingIds = emptyList(),
commentIds = "" commentIds = emptyList()
) )
private fun getPentests() = listOf( private fun getPentests() = listOf(
@ -101,8 +101,8 @@ class PentestControllerIntTest : BaseIntTest() {
title = "Search engine discovery/reconnaissance", title = "Search engine discovery/reconnaissance",
refNumber = "OTG-INFO-001", refNumber = "OTG-INFO-001",
status = PentestStatus.NOT_STARTED, status = PentestStatus.NOT_STARTED,
findingIds = "", findingIds = emptyList(),
commentIds = "" commentIds = emptyList()
) )
val pentestTwo = Pentest( val pentestTwo = Pentest(
id = "43fbc63c-f624-11ec-b939-0242ac120002", id = "43fbc63c-f624-11ec-b939-0242ac120002",
@ -111,8 +111,8 @@ class PentestControllerIntTest : BaseIntTest() {
title = "Fingerprint Web Server", title = "Fingerprint Web Server",
refNumber = "OTG-INFO-002", refNumber = "OTG-INFO-002",
status = PentestStatus.REPORTED, status = PentestStatus.REPORTED,
findingIds = "", findingIds = emptyList(),
commentIds = "" commentIds = emptyList()
) )
val pentestThree = Pentest( val pentestThree = Pentest(
id = "74eae112-f62c-11ec-b939-0242ac120002", id = "74eae112-f62c-11ec-b939-0242ac120002",
@ -121,8 +121,8 @@ class PentestControllerIntTest : BaseIntTest() {
title = "Testing for Credentials Transported over an Encrypted Channel", title = "Testing for Credentials Transported over an Encrypted Channel",
refNumber = "OTG-AUTHN-001", refNumber = "OTG-AUTHN-001",
status = PentestStatus.CHECKED, status = PentestStatus.CHECKED,
findingIds = "", findingIds = emptyList(),
commentIds = "" commentIds = emptyList()
) )
// persist test data in database // persist test data in database
mongoTemplate.save(PentestEntity(pentestOne)) mongoTemplate.save(PentestEntity(pentestOne))

View File

@ -86,6 +86,7 @@ class ProjectControllerDocumentationTest : BaseDocumentationIntTest() {
title = "Some Mock API (v1.0) Scanning", title = "Some Mock API (v1.0) Scanning",
createdAt = "2021-01-10T18:05:00Z", createdAt = "2021-01-10T18:05:00Z",
tester = "Novatester", tester = "Novatester",
projectPentests = emptyList<ProjectPentest>(),
createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032" createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032"
) )
val projectTwo = Project( val projectTwo = Project(
@ -94,6 +95,7 @@ class ProjectControllerDocumentationTest : BaseDocumentationIntTest() {
title = "CashMyData (iOS)", title = "CashMyData (iOS)",
createdAt = "2021-01-10T18:05:00Z", createdAt = "2021-01-10T18:05:00Z",
tester = "Elliot", tester = "Elliot",
projectPentests = emptyList<ProjectPentest>(),
createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032" createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032"
) )
@ -218,6 +220,7 @@ class ProjectControllerDocumentationTest : BaseDocumentationIntTest() {
title = "Some Mock API (v1.0) Scanning", title = "Some Mock API (v1.0) Scanning",
createdAt = "2021-01-10T18:05:00Z", createdAt = "2021-01-10T18:05:00Z",
tester = "Novatester", tester = "Novatester",
projectPentests = emptyList<ProjectPentest>(),
createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032" createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032"
) )
} }
@ -268,6 +271,7 @@ class ProjectControllerDocumentationTest : BaseDocumentationIntTest() {
title = "log4j Pentest_updated", title = "log4j Pentest_updated",
createdAt = "2021-01-10T18:05:00Z", createdAt = "2021-01-10T18:05:00Z",
tester = "Stipe_updated", tester = "Stipe_updated",
projectPentests = emptyList<ProjectPentest>(),
createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032" createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032"
) )
} }
@ -280,6 +284,7 @@ class ProjectControllerDocumentationTest : BaseDocumentationIntTest() {
title = "Some Mock API (v1.0) Scanning", title = "Some Mock API (v1.0) Scanning",
createdAt = "2021-01-10T18:05:00Z", createdAt = "2021-01-10T18:05:00Z",
tester = "Novatester", tester = "Novatester",
projectPentests = emptyList<ProjectPentest>(),
createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032" createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032"
) )
val projectTwo = Project( val projectTwo = Project(
@ -288,6 +293,7 @@ class ProjectControllerDocumentationTest : BaseDocumentationIntTest() {
title = "CashMyData (iOS)", title = "CashMyData (iOS)",
createdAt = "2021-01-10T18:05:00Z", createdAt = "2021-01-10T18:05:00Z",
tester = "Elliot", tester = "Elliot",
projectPentests = emptyList<ProjectPentest>(),
createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032" createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032"
) )
// persist test data in database // persist test data in database

View File

@ -1,55 +1,58 @@
[{ [{
"_id": { "_id": {
"$oid": "62c4018f18f1f463ed1e11be" "$oid": "62f3c50c7acde34f740ba737"
}, },
"lastModified": { "lastModified": {
"$date": { "$date": {
"$numberLong": "1657012623629" "$numberLong": "1660142860140"
} }
}, },
"data": { "data": {
"_id": "41051d0a-63ef-4290-b984-e6fbd736f218", "_id": "5a4f126c-9471-43b8-80b9-6eb02b7c35d0",
"client": "E Corp", "client": "E Corp",
"title": "Some Mock API (v1.0) Scanning", "title": "Some Mock API (v1.0) Scanning",
"createdAt": "2022-07-05T09:17:03.629331Z", "createdAt": "2022-08-10T14:47:40.140406Z",
"tester": "Novatester", "tester": "Novatester",
"createdBy": "ca447a34-cac3-495e-9295-0a5bf5de502a" "projectPentests": [],
"createdBy": "3c4ae87f-0d56-4634-a824-b4883c403c8a"
}, },
"_class": "com.securityc4po.api.project.ProjectEntity" "_class": "com.securityc4po.api.project.ProjectEntity"
},{ },{
"_id": { "_id": {
"$oid": "62c401b718f1f463ed1e11bf" "$oid": "62f3c5317acde34f740ba738"
}, },
"lastModified": { "lastModified": {
"$date": { "$date": {
"$numberLong": "1657012663386" "$numberLong": "1660142897912"
} }
}, },
"data": { "data": {
"_id": "0fa17ddb-7094-4f9c-b295-3433244c32c2", "_id": "42b8c0df-b70e-4526-8ed0-7c022195fe85",
"client": "Allsafe", "client": "Allsafe",
"title": "CashMyData (iOS)", "title": "CashMyData (iOS)",
"createdAt": "2022-07-05T09:17:43.386782Z", "createdAt": "2022-08-10T14:48:17.912592Z",
"tester": "Elliot", "tester": "Elliot",
"createdBy": "1ac9753a-5a62-4bf7-8412-6fde779ea33a" "projectPentests": [],
"createdBy": "6740ad72-8f42-486a-bcf3-e057e6afb0de"
}, },
"_class": "com.securityc4po.api.project.ProjectEntity" "_class": "com.securityc4po.api.project.ProjectEntity"
},{ },{
"_id": { "_id": {
"$oid": "62c401e318f1f463ed1e11c0" "$oid": "62f3c5427acde34f740ba739"
}, },
"lastModified": { "lastModified": {
"$date": { "$date": {
"$numberLong": "1657012707557" "$numberLong": "1660142914204"
} }
}, },
"data": { "data": {
"_id": "85aa8d79-5899-4b68-894c-d07f3b168cd4", "_id": "1120bfa1-0d2b-4e42-a209-0289a1256266",
"client": "Novatec", "client": "Novatec",
"title": "Openspace log4J", "title": "Openspace log4J",
"createdAt": "2022-07-05T09:18:27.557740Z", "createdAt": "2022-08-10T14:48:34.204234Z",
"tester": "mhg", "tester": "mhg",
"createdBy": "3201f6f8-10a4-4826-9b49-b6bdef28b152" "projectPentests": [],
"createdBy": "5a4a8032-0726-4851-a105-9f079c3989b9"
}, },
"_class": "com.securityc4po.api.project.ProjectEntity" "_class": "com.securityc4po.api.project.ProjectEntity"
}] }]