diff --git a/security-c4po-angular/package-lock.json b/security-c4po-angular/package-lock.json
index 122e791..f38a711 100644
--- a/security-c4po-angular/package-lock.json
+++ b/security-c4po-angular/package-lock.json
@@ -2997,6 +2997,21 @@
"tslib": "^2.0.0"
}
},
+ "@ngxs/storage-plugin": {
+ "version": "3.7.6",
+ "resolved": "https://registry.npmjs.org/@ngxs/storage-plugin/-/storage-plugin-3.7.6.tgz",
+ "integrity": "sha512-jeeoUgsMdb4M8kIHdnO0X6I73okmRJhMW9znaqhYF/aZ+PiQrogdJ5xvSXmoQ7Gg57YfQEhVErM+zf/HD7fnMA==",
+ "requires": {
+ "tslib": "^1.9.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
+ }
+ },
"@ngxs/store": {
"version": "3.7.4",
"resolved": "https://registry.npmjs.org/@ngxs/store/-/store-3.7.4.tgz",
@@ -11338,9 +11353,9 @@
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
},
"moment-timezone": {
- "version": "0.5.38",
- "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.38.tgz",
- "integrity": "sha512-nMIrzGah4+oYZPflDvLZUgoVUO4fvAqHstvG3xAUnMolWncuAiLDWNnJZj6EwJGMGfb1ZcuTFE6GI3hNOVWI/Q==",
+ "version": "0.5.40",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.40.tgz",
+ "integrity": "sha512-tWfmNkRYmBkPJz5mr9GVDn9vRlVZOTe6yqY92rFxiOdWXbjaR0+9LwQnZGGuNR63X456NqmEkbskte8tWL5ePg==",
"requires": {
"moment": ">= 2.9.0"
}
diff --git a/security-c4po-angular/package.json b/security-c4po-angular/package.json
index 6deb8d9..df1565c 100644
--- a/security-c4po-angular/package.json
+++ b/security-c4po-angular/package.json
@@ -32,6 +32,7 @@
"@ngneat/until-destroy": "~8.0.4",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
+ "@ngxs/storage-plugin": "^3.7.3",
"@ngxs/store": "^3.7.3",
"eva-icons": "^1.1.3",
"i18n-iso-countries": "^6.8.0",
diff --git a/security-c4po-angular/src/app/pentest/pentest-content/pentest-comments/pentest-comments.component.html b/security-c4po-angular/src/app/pentest/pentest-content/pentest-comments/pentest-comments.component.html
index e1053b0..a53374e 100644
--- a/security-c4po-angular/src/app/pentest/pentest-content/pentest-comments/pentest-comments.component.html
+++ b/security-c4po-angular/src/app/pentest/pentest-content/pentest-comments/pentest-comments.component.html
@@ -38,7 +38,12 @@
{{ 'comment.relatedFindings' | translate }}
- {{ comment.data['relatedFindings'].length ? comment.data['relatedFindings'] : 'comment.no.relatedFindings' | translate }}
+ 0; else NoRelatedFindings">
+
+
+
+ {{ 'comment.no.relatedFindings' | translate }}
+
|
diff --git a/security-c4po-angular/src/app/pentest/pentest-content/pentest-comments/pentest-comments.component.scss b/security-c4po-angular/src/app/pentest/pentest-content/pentest-comments/pentest-comments.component.scss
index da388fe..1e7c7c9 100644
--- a/security-c4po-angular/src/app/pentest/pentest-content/pentest-comments/pentest-comments.component.scss
+++ b/security-c4po-angular/src/app/pentest/pentest-content/pentest-comments/pentest-comments.component.scss
@@ -7,7 +7,8 @@
.comment-cell {
// Add style here
height: 4.5rem !important;
- max-height: 4.5rem !important;
+ // max-height: 4.5rem !important;
+ overflow: hidden;
}
.comment-cell:hover {
@@ -15,10 +16,17 @@
background-color: nb-theme(color-basic-transparent-focus);
}
+ .cell {
+ height: 4.5rem !important;
+ max-height: 4.5rem !important;
+ }
+
.related-finding-cell {
+ height: 4.5rem !important;
+ max-height: 4.5rem !important;
// cursor: pointer;
font-family: Courier, serif;
- color: nb-theme(color-info-default);
+ color: nb-theme(color-danger-default);
}
.cell-actions {
diff --git a/security-c4po-angular/src/app/pentest/pentest-content/pentest-findings/pentest-findings.component.html b/security-c4po-angular/src/app/pentest/pentest-content/pentest-findings/pentest-findings.component.html
index fcd12bb..de72409 100644
--- a/security-c4po-angular/src/app/pentest/pentest-content/pentest-findings/pentest-findings.component.html
+++ b/security-c4po-angular/src/app/pentest/pentest-content/pentest-findings/pentest-findings.component.html
@@ -20,7 +20,9 @@
{{ 'finding.severity' | translate }}
-
+
+
+
|
diff --git a/security-c4po-angular/src/app/pentest/pentest-content/pentest-findings/pentest-findings.component.ts b/security-c4po-angular/src/app/pentest/pentest-content/pentest-findings/pentest-findings.component.ts
index 9ee360e..08f47fe 100644
--- a/security-c4po-angular/src/app/pentest/pentest-content/pentest-findings/pentest-findings.component.ts
+++ b/security-c4po-angular/src/app/pentest/pentest-content/pentest-findings/pentest-findings.component.ts
@@ -22,6 +22,7 @@ import {Store} from '@ngxs/store';
import {UpdatePentestFindings} from '@shared/stores/project-state/project-state.actions';
import {ProjectState} from '@shared/stores/project-state/project-state';
import {DialogService} from '@shared/services/dialog-service/dialog.service';
+import {FindingService} from '@shared/services/finding.service';
@UntilDestroy()
@Component({
@@ -31,7 +32,7 @@ import {DialogService} from '@shared/services/dialog-service/dialog.service';
})
export class PentestFindingsComponent implements OnInit {
- constructor(private readonly pentestService: PentestService,
+ constructor(private readonly findingService: FindingService,
private dataSourceBuilder: NbTreeGridDataSourceBuilder,
private notificationService: NotificationService,
private dialogService: DialogService,
@@ -75,7 +76,7 @@ export class PentestFindingsComponent implements OnInit {
}
loadFindingsData(): void {
- this.pentestService.getFindingsByPentestId(this.pentestInfo$.getValue() ? this.pentestInfo$.getValue().id : '')
+ this.findingService.getFindingsByPentestId(this.pentestInfo$.getValue() ? this.pentestInfo$.getValue().id : '')
.pipe(
untilDestroyed(this),
/*filter(isNotNullOrUndefined),*/
@@ -115,7 +116,7 @@ export class PentestFindingsComponent implements OnInit {
filter(value => !!value),
/*tap((value) => console.warn('FindingDialogBody: ', value)),*/
mergeMap((value: FindingDialogBody) =>
- this.pentestService.saveFinding(
+ this.findingService.saveFinding(
this.pentestInfo$.getValue() ? this.pentestInfo$.getValue().id : '',
transformFindingToRequestBody(value)
)
@@ -135,7 +136,7 @@ export class PentestFindingsComponent implements OnInit {
}
onClickEditFinding(findingEntry): void {
- this.pentestService.getFindingById(findingEntry.data.findingId).pipe(
+ this.findingService.getFindingById(findingEntry.data.findingId).pipe(
filter(isNotNullOrUndefined),
untilDestroyed(this)
).subscribe({
@@ -154,7 +155,7 @@ export class PentestFindingsComponent implements OnInit {
filter(value => !!value),
/*tap((value) => console.warn('FindingDialogBody: ', value)),*/
mergeMap((value: FindingDialogBody) =>
- this.pentestService.updateFinding(
+ this.findingService.updateFinding(
findingEntry.data.findingId,
transformFindingToRequestBody(value)
)
@@ -191,7 +192,7 @@ export class PentestFindingsComponent implements OnInit {
message
).onClose.pipe(
filter((confirm) => !!confirm),
- switchMap(() => this.pentestService.deleteFindingByPentestAndFindingId(
+ switchMap(() => this.findingService.deleteFindingByPentestAndFindingId(
this.pentestInfo$.getValue() ? this.pentestInfo$.getValue().id : '',
findingEntry.data.findingId)
),
@@ -201,7 +202,8 @@ export class PentestFindingsComponent implements OnInit {
}),
untilDestroyed(this)
).subscribe({
- next: () => {
+ next: (deletedFinding: any) => {
+ this.store.dispatch(new UpdatePentestFindings(deletedFinding.id));
this.loadFindingsData();
this.notificationService.showPopup('finding.popup.delete.success', PopupType.SUCCESS);
}, error: error => {
diff --git a/security-c4po-angular/src/app/pentest/pentest.module.ts b/security-c4po-angular/src/app/pentest/pentest.module.ts
index 0f244b3..1395da2 100644
--- a/security-c4po-angular/src/app/pentest/pentest.module.ts
+++ b/security-c4po-angular/src/app/pentest/pentest.module.ts
@@ -16,6 +16,7 @@ import {CommonAppModule} from '../common-app.module';
import {SeverityTagModule} from '@shared/widgets/severity-tag/severity-tag.module';
import {FindingDialogModule} from '@shared/modules/finding-dialog/finding-dialog.module';
import {CommentDialogModule} from '@shared/modules/comment-dialog/comment-dialog.module';
+import {FindigWidgetModule} from '@shared/widgets/findig-widget/findig-widget.module';
@NgModule({
declarations: [
@@ -26,28 +27,29 @@ import {CommentDialogModule} from '@shared/modules/comment-dialog/comment-dialog
PentestFindingsComponent,
PentestCommentsComponent
],
- imports: [
- CommonModule,
- CommonAppModule,
- RouterModule.forChild([{
- path: '',
- component: PentestComponent
- }]),
- NbLayoutModule,
- NbCardModule,
- FlexLayoutModule,
- FontAwesomeModule,
- TranslateModule,
- NbButtonModule,
- StatusTagModule,
- NbTabsetModule,
- NbTreeGridModule,
- SeverityTagModule,
- NbSelectModule,
- // Dialog Modules
- FindingDialogModule,
- CommentDialogModule,
- ]
+ imports: [
+ CommonModule,
+ CommonAppModule,
+ RouterModule.forChild([{
+ path: '',
+ component: PentestComponent
+ }]),
+ NbLayoutModule,
+ NbCardModule,
+ FlexLayoutModule,
+ FontAwesomeModule,
+ TranslateModule,
+ NbButtonModule,
+ StatusTagModule,
+ NbTabsetModule,
+ NbTreeGridModule,
+ SeverityTagModule,
+ NbSelectModule,
+ // Dialog Modules
+ FindingDialogModule,
+ CommentDialogModule,
+ FindigWidgetModule,
+ ]
})
export class PentestModule {
}
diff --git a/security-c4po-angular/src/assets/i18n/de-DE.json b/security-c4po-angular/src/assets/i18n/de-DE.json
index eb25746..1044e31 100644
--- a/security-c4po-angular/src/assets/i18n/de-DE.json
+++ b/security-c4po-angular/src/assets/i18n/de-DE.json
@@ -153,7 +153,7 @@
"add": "Kommentar hinzufügen",
"add.finding": "Fund hinzufügen",
"no.comments": "Keine Kommentare verfügbar",
- "no.relatedFindings": "Nicht verbunden mit Fund",
+ "no.relatedFindings": "Nicht verbunden mit einem Fund",
"relatedFindingsPlaceholder": "Fund auswählen",
"noFindingsInObjectivePlaceholder": "Objective hat keine Befunde, auf die es sich beziehen könnte.",
"create": {
diff --git a/security-c4po-angular/src/assets/i18n/en-US.json b/security-c4po-angular/src/assets/i18n/en-US.json
index 405e4ae..f08f30f 100644
--- a/security-c4po-angular/src/assets/i18n/en-US.json
+++ b/security-c4po-angular/src/assets/i18n/en-US.json
@@ -153,7 +153,7 @@
"add": "Add Comment",
"add.finding": "Add related finding",
"no.comments": "No comments available",
- "no.relatedFindings": "Not related to finding",
+ "no.relatedFindings": "Not related to any finding",
"relatedFindingsPlaceholder": "Select a related finding",
"noFindingsInObjectivePlaceholder": "Objective doesn't have any findings to relate to.",
"create": {
diff --git a/security-c4po-angular/src/shared/modules/comment-dialog/comment-dialog.component.ts b/security-c4po-angular/src/shared/modules/comment-dialog/comment-dialog.component.ts
index 4ba9e7e..c0c4cbd 100644
--- a/security-c4po-angular/src/shared/modules/comment-dialog/comment-dialog.component.ts
+++ b/security-c4po-angular/src/shared/modules/comment-dialog/comment-dialog.component.ts
@@ -12,6 +12,7 @@ import {Store} from '@ngxs/store';
import {Finding} from '@shared/models/finding.model';
import {RelatedFindingOption} from '@shared/models/comment.model';
import {BehaviorSubject} from 'rxjs';
+import {FindingService} from '@shared/services/finding.service';
@Component({
selector: 'app-comment-dialog',
@@ -39,7 +40,7 @@ export class CommentDialogComponent implements OnInit {
@Inject(NB_DIALOG_CONFIG) private data: GenericDialogData,
private fb: FormBuilder,
protected dialogRef: NbDialogRef,
- private readonly pentestService: PentestService,
+ private readonly findingService: FindingService,
private store: Store
) {
}
@@ -95,7 +96,7 @@ export class CommentDialogComponent implements OnInit {
}
requestRelatedFindingsData(pentestId: string, relatedFindings: any): void {
- this.pentestService.getFindingsByPentestId(pentestId).pipe(
+ this.findingService.getFindingsByPentestId(pentestId).pipe(
untilDestroyed(this)
).subscribe({
next: (findings: Finding[]) => {
diff --git a/security-c4po-angular/src/shared/services/finding.service.spec.ts b/security-c4po-angular/src/shared/services/finding.service.spec.ts
new file mode 100644
index 0000000..bd27e83
--- /dev/null
+++ b/security-c4po-angular/src/shared/services/finding.service.spec.ts
@@ -0,0 +1,26 @@
+import { TestBed } from '@angular/core/testing';
+
+import { FindingService } from './finding.service';
+import {HttpClientTestingModule} from '@angular/common/http/testing';
+import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
+import {NgxsModule} from '@ngxs/store';
+import {ProjectState} from '@shared/stores/project-state/project-state';
+
+describe('FindingService', () => {
+ let service: FindingService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ HttpClientTestingModule,
+ BrowserAnimationsModule,
+ NgxsModule.forRoot([ProjectState])
+ ]
+ });
+ service = TestBed.inject(FindingService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/security-c4po-angular/src/shared/services/finding.service.ts b/security-c4po-angular/src/shared/services/finding.service.ts
new file mode 100644
index 0000000..16cd9e5
--- /dev/null
+++ b/security-c4po-angular/src/shared/services/finding.service.ts
@@ -0,0 +1,62 @@
+import { Injectable } from '@angular/core';
+import {environment} from '../../environments/environment';
+import {HttpClient} from '@angular/common/http';
+import {Store} from '@ngxs/store';
+import {Observable} from 'rxjs';
+import {Finding} from '@shared/models/finding.model';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class FindingService {
+
+ private apiBaseURL = `${environment.apiEndpoint}/pentests`;
+
+ constructor(
+ private http: HttpClient,
+ private readonly store: Store) {
+ }
+
+ /**
+ * Get Findings for Pentest Id
+ * @param pentestId the id of the project
+ */
+ public getFindingsByPentestId(pentestId: string): Observable {
+ return this.http.get(`${this.apiBaseURL}/${pentestId}/findings`);
+ }
+
+ /**
+ * Get Finding by Id
+ * @param findingId the id of the finding
+ */
+ public getFindingById(findingId: string): Observable {
+ return this.http.get(`${this.apiBaseURL}/${findingId}/finding`);
+ }
+
+ /**
+ * Save Finding
+ * @param pentestId the id of the pentest
+ * @param finding the information of the finding
+ */
+ public saveFinding(pentestId: string, finding: Finding): Observable {
+ return this.http.post(`${this.apiBaseURL}/${pentestId}/finding`, finding);
+ }
+
+ /**
+ * Update Finding
+ * @param findingId the id of the finding
+ * @param finding the information of the finding
+ */
+ public updateFinding(findingId: string, finding: Finding): Observable {
+ return this.http.patch(`${this.apiBaseURL}/${findingId}/finding`, finding);
+ }
+
+ /**
+ * Delete Finding
+ * @param pentestId the id of the pentest
+ * @param findingId the id of the finding
+ */
+ public deleteFindingByPentestAndFindingId(pentestId: string, findingId: string): Observable {
+ return this.http.delete(`${this.apiBaseURL}/${pentestId}/finding/${findingId}`);
+ }
+}
diff --git a/security-c4po-angular/src/shared/services/pentest.service.ts b/security-c4po-angular/src/shared/services/pentest.service.ts
index dbe17d6..4e23836 100644
--- a/security-c4po-angular/src/shared/services/pentest.service.ts
+++ b/security-c4po-angular/src/shared/services/pentest.service.ts
@@ -9,8 +9,6 @@ import {ProjectState} from '@shared/stores/project-state/project-state';
import {catchError, map, switchMap} from 'rxjs/operators';
import {getTempPentestsForCategory} from '@shared/functions/categories/get-temp-pentests-for-category.function';
import {Finding} from '@shared/models/finding.model';
-import {Comment} from '@shared/models/comment.model';
-import {v4 as UUID} from 'uuid';
@Injectable({
providedIn: 'root'
@@ -78,47 +76,4 @@ export class PentestService {
public updatePentest(pentest: Pentest): Observable {
return this.http.patch(`${this.apiBaseURL}/${pentest.id}`, pentest);
}
-
- /**
- * Get Findings for Pentest Id
- * @param pentestId the id of the project
- */
- public getFindingsByPentestId(pentestId: string): Observable {
- return this.http.get(`${this.apiBaseURL}/${pentestId}/findings`);
- }
-
- /**
- * Get Finding by Id
- * @param findingId the id of the finding
- */
- public getFindingById(findingId: string): Observable {
- return this.http.get(`${this.apiBaseURL}/${findingId}/finding`);
- }
-
- /**
- * Save Finding
- * @param pentestId the id of the pentest
- * @param finding the information of the finding
- */
- public saveFinding(pentestId: string, finding: Finding): Observable {
- return this.http.post(`${this.apiBaseURL}/${pentestId}/finding`, finding);
- }
-
- /**
- * Update Finding
- * @param findingId the id of the finding
- * @param finding the information of the finding
- */
- public updateFinding(findingId: string, finding: Finding): Observable {
- return this.http.patch(`${this.apiBaseURL}/${findingId}/finding`, finding);
- }
-
- /**
- * Delete Finding
- * @param pentestId the id of the pentest
- * @param findingId the id of the finding
- */
- public deleteFindingByPentestAndFindingId(pentestId: string, findingId: string): Observable {
- return this.http.delete(`${this.apiBaseURL}/${pentestId}/finding/${findingId}`);
- }
}
diff --git a/security-c4po-angular/src/shared/stores/project-state/project-state.ts b/security-c4po-angular/src/shared/stores/project-state/project-state.ts
index 709a9ee..c13e323 100644
--- a/security-c4po-angular/src/shared/stores/project-state/project-state.ts
+++ b/security-c4po-angular/src/shared/stores/project-state/project-state.ts
@@ -23,6 +23,10 @@ export interface ProjectStateModel {
selectedPentest: Pentest;
}
+export interface FindingMap {
+ [key: string]: string;
+}
+
@State({
name: PROJECT_STATE_NAME,
defaults: {
@@ -91,12 +95,14 @@ export class ProjectState {
updatePentestFindings(ctx: StateContext, {findingId}: UpdatePentestFindings): void {
const state = ctx.getState();
let stateSelectedPentest: Pentest = state.selectedPentest;
+ // State objects
const stateFindingIds: Array = stateSelectedPentest.findingIds || [];
let updatedFindingIds: Array = [];
if (!stateFindingIds.includes(findingId)) {
updatedFindingIds = [...stateFindingIds, findingId];
} else {
- // ToDo: Add logic to remove findingId from array
+ const findingIndex = stateFindingIds.indexOf(findingId);
+ updatedFindingIds = [...stateFindingIds.slice(0, findingIndex)];
}
// overwrites only findingIds
stateSelectedPentest = {
@@ -113,12 +119,14 @@ export class ProjectState {
updatePentestComments(ctx: StateContext, {commentId}: UpdatePentestComments): void {
const state = ctx.getState();
let stateSelectedPentest: Pentest = state.selectedPentest;
+ // State objects
const stateCommentIds: Array = stateSelectedPentest.commentIds || [];
let updatedCommentIds: Array = [];
if (!stateCommentIds.includes(commentId)) {
updatedCommentIds = [...stateCommentIds, commentId];
} else {
- // ToDo: Add logic to remove commentId from array
+ const commentIndex = stateCommentIds.indexOf(commentId);
+ updatedCommentIds = [...stateCommentIds.slice(0, commentIndex)];
}
// overwrites only findingIds
stateSelectedPentest = {
diff --git a/security-c4po-angular/tsconfig.json b/security-c4po-angular/tsconfig.json
index 4768eae..8a6b944 100644
--- a/security-c4po-angular/tsconfig.json
+++ b/security-c4po-angular/tsconfig.json
@@ -13,11 +13,8 @@
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
- "module": "es2020",
- "lib": [
- "es2018",
- "dom"
- ],
+ "module": "esNext",
+ "lib": ["es2019", "es2018", "dom"],
"paths": {
"@shared/*": ["./src/shared/*"],
"@assets/*": ["./src/assets/*"]
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/PentestController.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/PentestController.kt
index 9c9cb05..317ac13 100644
--- a/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/PentestController.kt
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/PentestController.kt
@@ -4,15 +4,10 @@ import com.securityc4po.api.configuration.BC_BAD_CAST_TO_ABSTRACT_COLLECTION
import com.securityc4po.api.extensions.getLoggerFor
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
import com.securityc4po.api.ResponseBody
-import com.securityc4po.api.finding.FindingRequestBody
-import com.securityc4po.api.finding.FindingService
-import com.securityc4po.api.finding.toFindingDeleteResponseBody
-import com.securityc4po.api.finding.toFindingResponseBody
import org.springframework.http.ResponseEntity
import org.springframework.http.ResponseEntity.noContent
import org.springframework.web.bind.annotation.*
import reactor.core.publisher.Mono
-import reactor.kotlin.core.publisher.switchIfEmpty
@RestController
@RequestMapping("/pentests")
@@ -23,7 +18,7 @@ import reactor.kotlin.core.publisher.switchIfEmpty
methods = [RequestMethod.GET, RequestMethod.DELETE, RequestMethod.POST, RequestMethod.PATCH]
)
@SuppressFBWarnings(BC_BAD_CAST_TO_ABSTRACT_COLLECTION)
-class PentestController(private val pentestService: PentestService, private val findingService: FindingService) {
+class PentestController(private val pentestService: PentestService) {
var logger = getLoggerFor()
@@ -71,55 +66,4 @@ class PentestController(private val pentestService: PentestService, private val
ResponseEntity.accepted().body(it.toPentestResponseBody())
}
}
-
- @GetMapping("/{pentestId}/findings")
- fun getFindings(@PathVariable(value = "pentestId") pentestId: String): Mono>> {
- return this.pentestService.getFindingIdsByPentestId(pentestId).flatMap { findingIds: List ->
- this.findingService.getFindingsByIds(findingIds).map { findingList ->
- findingList.map { it.toFindingResponseBody() }
- }
- }.map {
- if (it.isEmpty()) noContent().build()
- else ResponseEntity.ok(it)
- }
- }
-
- @GetMapping("/{findingId}/finding")
- fun getFinding(@PathVariable(value = "findingId") findingId: String):Mono> {
- return this.findingService.getFindingById(findingId).map {
- ResponseEntity.ok().body(it.toFindingResponseBody())
- }
- }
-
- @PostMapping("/{pentestId}/finding")
- fun saveFinding(
- @PathVariable(value = "pentestId") pentestId: String,
- @RequestBody body: FindingRequestBody
- ): Mono> {
- return this.findingService.saveFinding(pentestId, body).map {
- ResponseEntity.accepted().body(it.toFindingResponseBody())
- }
- }
-
- @PatchMapping("/{findingId}/finding")
- fun updateFinding(
- @PathVariable(value = "findingId") findingId: String,
- @RequestBody body: FindingRequestBody
- ): Mono> {
- return this.findingService.updateFinding(findingId, body).map {
- ResponseEntity.accepted().body(it.toFindingResponseBody())
- }
- }
-
- @DeleteMapping("/{pentestId}/finding/{findingId}")
- fun deleteFinding(
- @PathVariable(value = "pentestId") pentestId: String,
- @PathVariable(value = "findingId") findingId: String
- ): Mono> {
- return this.findingService.deleteFindingByPentestAndFindingId(pentestId, findingId).map {
- ResponseEntity.ok().body(it.toFindingDeleteResponseBody())
- }.switchIfEmpty {
- Mono.just(noContent().build())
- }
- }
}
\ No newline at end of file
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/PentestService.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/PentestService.kt
index 044c0e1..3c41ea6 100644
--- a/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/PentestService.kt
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/PentestService.kt
@@ -53,16 +53,16 @@ class PentestService(private val pentestRepository: PentestRepository, private v
val pentest = body.toPentest()
val pentestEntity = PentestEntity(pentest)
return pentestRepository.insert(pentestEntity).flatMap { newPentestEntity: PentestEntity ->
- val pentest = newPentestEntity.toPentest()
+ val newPentest = newPentestEntity.toPentest()
// After successfully saving pentest add id and status to project
- val projectPentest = ProjectPentest(pentestId = pentest.id, status = pentest.status)
+ val projectPentest = ProjectPentest(pentestId = newPentest.id, status = newPentest.status)
projectService.updateProjectTestingProgress(projectId, projectPentest).onErrorMap {
TransactionInterruptedException(
"Project Pentests could not be updated in Database.",
Errorcode.ProjectPentestInsertionFailed
)
}.map {
- pentest
+ newPentest
}
}.doOnError {
throw wrappedException(
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/Comment.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/Comment.kt
similarity index 93%
rename from security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/Comment.kt
rename to security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/Comment.kt
index 39fedf4..3b7cebd 100644
--- a/security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/Comment.kt
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/Comment.kt
@@ -1,7 +1,7 @@
-package com.securityc4po.api.comment
+package com.securityc4po.api.pentest.comment
import com.securityc4po.api.ResponseBody
-import com.securityc4po.api.finding.FindingRequestBody
+import com.securityc4po.api.pentest.finding.FindingRequestBody
import org.springframework.data.mongodb.core.index.Indexed
import java.util.*
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/CommentController.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/CommentController.kt
similarity index 94%
rename from security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/CommentController.kt
rename to security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/CommentController.kt
index e1d5066..218ec22 100644
--- a/security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/CommentController.kt
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/CommentController.kt
@@ -1,4 +1,4 @@
-package com.securityc4po.api.comment
+package com.securityc4po.api.pentest.comment
import com.securityc4po.api.configuration.BC_BAD_CAST_TO_ABSTRACT_COLLECTION
import com.securityc4po.api.extensions.getLoggerFor
@@ -6,7 +6,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
import com.securityc4po.api.ResponseBody
import com.securityc4po.api.configuration.error.handler.EntityNotFoundException
import com.securityc4po.api.configuration.error.handler.Errorcode
-import com.securityc4po.api.finding.toFindingResponseBody
+import com.securityc4po.api.pentest.finding.toFindingResponseBody
import com.securityc4po.api.pentest.PentestService
import org.springframework.http.ResponseEntity
import org.springframework.http.ResponseEntity.noContent
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/CommentEntity.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/CommentEntity.kt
similarity index 89%
rename from security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/CommentEntity.kt
rename to security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/CommentEntity.kt
index cc7352c..79af7b8 100644
--- a/security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/CommentEntity.kt
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/CommentEntity.kt
@@ -1,4 +1,4 @@
-package com.securityc4po.api.comment
+package com.securityc4po.api.pentest.comment
import com.securityc4po.api.BaseEntity
import org.springframework.data.mongodb.core.mapping.Document
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/CommentRepository.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/CommentRepository.kt
similarity index 93%
rename from security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/CommentRepository.kt
rename to security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/CommentRepository.kt
index a19ba17..02dd8eb 100644
--- a/security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/CommentRepository.kt
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/CommentRepository.kt
@@ -1,4 +1,4 @@
-package com.securityc4po.api.comment
+package com.securityc4po.api.pentest.comment
import org.springframework.data.mongodb.repository.DeleteQuery
import org.springframework.data.mongodb.repository.Query
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/CommentService.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/CommentService.kt
similarity index 97%
rename from security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/CommentService.kt
rename to security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/CommentService.kt
index f76ef5c..f023426 100644
--- a/security-c4po-api/src/main/kotlin/com/securityc4po/api/comment/CommentService.kt
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/comment/CommentService.kt
@@ -1,4 +1,4 @@
-package com.securityc4po.api.comment
+package com.securityc4po.api.pentest.comment
import com.securityc4po.api.configuration.BC_BAD_CAST_TO_ABSTRACT_COLLECTION
import com.securityc4po.api.configuration.MESSAGE_BAD_CAST_TO_ABSTRACT_COLLECTION
@@ -7,7 +7,6 @@ import com.securityc4po.api.configuration.error.handler.EntityNotFoundException
import com.securityc4po.api.configuration.error.handler.InvalidModelException
import com.securityc4po.api.configuration.error.handler.TransactionInterruptedException
import com.securityc4po.api.extensions.getLoggerFor
-import com.securityc4po.api.finding.*
import com.securityc4po.api.pentest.PentestService
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
import org.springframework.stereotype.Service
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/Finding.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/Finding.kt
similarity index 98%
rename from security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/Finding.kt
rename to security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/Finding.kt
index 268f5f6..694251c 100644
--- a/security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/Finding.kt
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/Finding.kt
@@ -1,4 +1,4 @@
-package com.securityc4po.api.finding
+package com.securityc4po.api.pentest.finding
import com.securityc4po.api.ResponseBody
import org.springframework.data.mongodb.core.index.Indexed
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/FindingController.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/FindingController.kt
new file mode 100644
index 0000000..f081ace
--- /dev/null
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/FindingController.kt
@@ -0,0 +1,85 @@
+package com.securityc4po.api.pentest.finding
+
+import com.securityc4po.api.pentest.PentestCategory
+import com.securityc4po.api.pentest.PentestRequestBody
+import com.securityc4po.api.pentest.PentestService
+import com.securityc4po.api.pentest.toPentestResponseBody
+import com.securityc4po.api.configuration.BC_BAD_CAST_TO_ABSTRACT_COLLECTION
+import com.securityc4po.api.extensions.getLoggerFor
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
+import com.securityc4po.api.ResponseBody
+import com.securityc4po.api.pentest.finding.FindingRequestBody
+import com.securityc4po.api.pentest.finding.FindingService
+import com.securityc4po.api.pentest.finding.toFindingDeleteResponseBody
+import com.securityc4po.api.pentest.finding.toFindingResponseBody
+import org.springframework.http.ResponseEntity
+import org.springframework.http.ResponseEntity.noContent
+import org.springframework.web.bind.annotation.*
+import reactor.core.publisher.Mono
+import reactor.kotlin.core.publisher.switchIfEmpty
+
+@RestController
+@RequestMapping("/pentests")
+@CrossOrigin(
+ origins = [],
+ allowCredentials = "false",
+ allowedHeaders = ["*"],
+ methods = [RequestMethod.GET, RequestMethod.DELETE, RequestMethod.POST, RequestMethod.PATCH]
+)
+@SuppressFBWarnings(BC_BAD_CAST_TO_ABSTRACT_COLLECTION)
+class FindingController(private val pentestService: PentestService, private val findingService: FindingService) {
+
+ var logger = getLoggerFor()
+
+ @GetMapping("/{pentestId}/findings")
+ fun getFindings(@PathVariable(value = "pentestId") pentestId: String): Mono>> {
+ return this.pentestService.getFindingIdsByPentestId(pentestId).flatMap { findingIds: List ->
+ this.findingService.getFindingsByIds(findingIds).map { findingList ->
+ findingList.map { it.toFindingResponseBody() }
+ }
+ }.map {
+ if (it.isEmpty()) noContent().build()
+ else ResponseEntity.ok(it)
+ }
+ }
+
+ @GetMapping("/{findingId}/finding")
+ fun getFinding(@PathVariable(value = "findingId") findingId: String):Mono> {
+ return this.findingService.getFindingById(findingId).map {
+ ResponseEntity.ok().body(it.toFindingResponseBody())
+ }
+ }
+
+ @PostMapping("/{pentestId}/finding")
+ fun saveFinding(
+ @PathVariable(value = "pentestId") pentestId: String,
+ @RequestBody body: FindingRequestBody
+ ): Mono> {
+ return this.findingService.saveFinding(pentestId, body).map {
+ ResponseEntity.accepted().body(it.toFindingResponseBody())
+ }
+ }
+
+ @PatchMapping("/{findingId}/finding")
+ fun updateFinding(
+ @PathVariable(value = "findingId") findingId: String,
+ @RequestBody body: FindingRequestBody
+ ): Mono> {
+ return this.findingService.updateFinding(findingId, body).map {
+ ResponseEntity.accepted().body(it.toFindingResponseBody())
+ }
+ }
+
+ @DeleteMapping("/{pentestId}/finding/{findingId}")
+ fun deleteFinding(
+ @PathVariable(value = "pentestId") pentestId: String,
+ @PathVariable(value = "findingId") findingId: String
+ ): Mono> {
+ // ToDo: Add remove finding from comment as well
+ return this.findingService.deleteFindingByPentestAndFindingId(pentestId, findingId).map {
+ ResponseEntity.ok().body(it.toFindingDeleteResponseBody())
+ }.switchIfEmpty {
+ Mono.just(noContent().build())
+ }
+ }
+}
\ No newline at end of file
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/FindingEntity.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/FindingEntity.kt
similarity index 91%
rename from security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/FindingEntity.kt
rename to security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/FindingEntity.kt
index 93f2d79..4928dab 100644
--- a/security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/FindingEntity.kt
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/FindingEntity.kt
@@ -1,4 +1,4 @@
-package com.securityc4po.api.finding
+package com.securityc4po.api.pentest.finding
import com.securityc4po.api.BaseEntity
import org.springframework.data.mongodb.core.mapping.Document
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/FindingRepository.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/FindingRepository.kt
similarity index 93%
rename from security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/FindingRepository.kt
rename to security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/FindingRepository.kt
index c4d5777..7580352 100644
--- a/security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/FindingRepository.kt
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/FindingRepository.kt
@@ -1,4 +1,4 @@
-package com.securityc4po.api.finding
+package com.securityc4po.api.pentest.finding
import org.springframework.data.mongodb.repository.DeleteQuery
import org.springframework.data.mongodb.repository.Query
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/FindingService.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/FindingService.kt
similarity index 96%
rename from security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/FindingService.kt
rename to security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/FindingService.kt
index b0fb231..ee9a761 100644
--- a/security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/FindingService.kt
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/FindingService.kt
@@ -1,4 +1,4 @@
-package com.securityc4po.api.finding
+package com.securityc4po.api.pentest.finding
import com.securityc4po.api.configuration.BC_BAD_CAST_TO_ABSTRACT_COLLECTION
import com.securityc4po.api.configuration.MESSAGE_BAD_CAST_TO_ABSTRACT_COLLECTION
@@ -37,15 +37,15 @@ class FindingService(private val findingRepository: FindingRepository, private v
val finding = body.toFinding()
val findingEntity = FindingEntity(finding)
return findingRepository.insert(findingEntity).flatMap { newFindingEntity: FindingEntity ->
- val finding = newFindingEntity.toFinding()
+ val newFinding = newFindingEntity.toFinding()
// After successfully saving finding add id to pentest
- pentestService.updatePentestFinding(pentestId, finding.id).onErrorMap {
+ pentestService.updatePentestFinding(pentestId, newFinding.id).onErrorMap {
TransactionInterruptedException(
"Pentest could not be updated in Database.",
Errorcode.PentestInsertionFailed
)
}.map {
- finding
+ newFinding
}
}.doOnError {
throw wrappedException(
diff --git a/security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/Severity.kt b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/Severity.kt
similarity index 60%
rename from security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/Severity.kt
rename to security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/Severity.kt
index bd93d30..9412362 100644
--- a/security-c4po-api/src/main/kotlin/com/securityc4po/api/finding/Severity.kt
+++ b/security-c4po-api/src/main/kotlin/com/securityc4po/api/pentest/finding/Severity.kt
@@ -1,4 +1,4 @@
-package com.securityc4po.api.finding
+package com.securityc4po.api.pentest.finding
enum class Severity {
LOW,
diff --git a/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/PentestControllerDocumentationTest.kt b/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/PentestControllerDocumentationTest.kt
index d79db95..d4044a9 100644
--- a/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/PentestControllerDocumentationTest.kt
+++ b/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/PentestControllerDocumentationTest.kt
@@ -6,7 +6,6 @@ import com.securityc4po.api.BaseDocumentationIntTest
import com.securityc4po.api.configuration.NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR
import com.securityc4po.api.configuration.RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE
import com.securityc4po.api.configuration.SIC_INNER_SHOULD_BE_STATIC
-import com.securityc4po.api.finding.*
import com.securityc4po.api.project.Project
import com.securityc4po.api.project.ProjectEntity
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
@@ -109,7 +108,7 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
category = PentestCategory.INFORMATION_GATHERING,
refNumber = "OTG-INFO-002",
status = PentestStatus.IN_PROGRESS,
- findingIds = listOf("ab62d365-1b1d-4da1-89bc-5496616e220f"),
+ findingIds = emptyList(),
commentIds = emptyList()
)
@@ -233,287 +232,6 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
)
}
- @Nested
- inner class GetFindings {
- @Test
- fun getFindingsByPentestId() {
- val pentestTwoId = "43fbc63c-f624-11ec-b939-0242ac120002"
- webTestClient.get()
- .uri("/pentests/{pentestId}/findings", pentestTwoId)
- .header("Authorization", "Bearer $tokenAdmin")
- .exchange()
- .expectStatus().isOk
- .expectHeader().doesNotExist("")
- .expectBody().json(Json.write(getFindingsResponse()))
- .consumeWith(
- WebTestClientRestDocumentation.document(
- "{methodName}",
- Preprocessors.preprocessRequest(
- Preprocessors.prettyPrint(),
- Preprocessors.modifyUris().removePort(),
- Preprocessors.removeHeaders("Host", "Content-Length")
- ),
- Preprocessors.preprocessResponse(
- Preprocessors.prettyPrint()
- ),
- RequestDocumentation.relaxedPathParameters(
- RequestDocumentation.parameterWithName("pentestId").description("The id of the pentest you want to get the findings for")
- ),
- PayloadDocumentation.relaxedResponseFields(
- PayloadDocumentation.fieldWithPath("[].id").type(JsonFieldType.STRING)
- .description("The id of the requested findings"),
- PayloadDocumentation.fieldWithPath("[].severity").type(JsonFieldType.STRING)
- .description("The severity of the finding"),
- PayloadDocumentation.fieldWithPath("[].title").type(JsonFieldType.STRING)
- .description("The title of the requested finding"),
- PayloadDocumentation.fieldWithPath("[].description").type(JsonFieldType.STRING)
- .description("The description number of the finding"),
- PayloadDocumentation.fieldWithPath("[].impact").type(JsonFieldType.STRING)
- .description("The impact of the finding"),
- PayloadDocumentation.fieldWithPath("[].affectedUrls").type(JsonFieldType.ARRAY)
- .description("List of affected Urls of the finding"),
- PayloadDocumentation.fieldWithPath("[].reproduction").type(JsonFieldType.STRING)
- .description("The reproduction steps of the finding"),
- PayloadDocumentation.fieldWithPath("[].mitigation").type(JsonFieldType.STRING)
- .description("The example mitigation for the finding")
- )
- )
- )
- }
-
- private val findingOne = Finding(
- id = "ab62d365-1b1d-4da1-89bc-5496616e220f",
- severity = Severity.LOW,
- title = "Found Bug",
- description = "OTG-INFO-002 Bug",
- impact = "Service",
- affectedUrls = emptyList(),
- reproduction = "Step 1: Hack",
- mitigation = "None"
- )
-
- private fun getFindingsResponse() = listOf(
- findingOne.toFindingResponseBody()
- )
- }
-
- @Nested
- inner class GetFinding {
- @Test
- fun getFindingById() {
- val findingId = "ab62d365-1b1d-4da1-89bc-5496616e220f"
- webTestClient.get()
- .uri("/pentests/{findingId}/finding", findingId)
- .header("Authorization", "Bearer $tokenAdmin")
- .exchange()
- .expectStatus().isOk
- .expectHeader().doesNotExist("")
- .expectBody().json(Json.write(findingOne.toFindingResponseBody()))
- .consumeWith(
- WebTestClientRestDocumentation.document(
- "{methodName}",
- Preprocessors.preprocessRequest(
- Preprocessors.prettyPrint(),
- Preprocessors.modifyUris().removePort(),
- Preprocessors.removeHeaders("Host", "Content-Length")
- ),
- Preprocessors.preprocessResponse(
- Preprocessors.prettyPrint()
- ),
- RequestDocumentation.relaxedPathParameters(
- RequestDocumentation.parameterWithName("findingId").description("The id of the feinidng you want to get")
- ),
- PayloadDocumentation.relaxedResponseFields(
- PayloadDocumentation.fieldWithPath("id").type(JsonFieldType.STRING)
- .description("The id of the requested finding"),
- PayloadDocumentation.fieldWithPath("severity").type(JsonFieldType.STRING)
- .description("The severity of the finding"),
- PayloadDocumentation.fieldWithPath("title").type(JsonFieldType.STRING)
- .description("The title of the requested finding"),
- PayloadDocumentation.fieldWithPath("description").type(JsonFieldType.STRING)
- .description("The description number of the finding"),
- PayloadDocumentation.fieldWithPath("impact").type(JsonFieldType.STRING)
- .description("The impact of the finding"),
- PayloadDocumentation.fieldWithPath("affectedUrls").type(JsonFieldType.ARRAY)
- .description("List of affected Urls of the finding"),
- PayloadDocumentation.fieldWithPath("reproduction").type(JsonFieldType.STRING)
- .description("The reproduction steps of the finding"),
- PayloadDocumentation.fieldWithPath("mitigation").type(JsonFieldType.STRING)
- .description("The example mitigation for the finding")
- )
- )
- )
- }
-
- private val findingOne = Finding(
- id = "ab62d365-1b1d-4da1-89bc-5496616e220f",
- severity = Severity.LOW,
- title = "Found Bug",
- description = "OTG-INFO-002 Bug",
- impact = "Service",
- affectedUrls = emptyList(),
- reproduction = "Step 1: Hack",
- mitigation = "None"
- )
- }
-
- @Nested
- inner class SaveFinding {
- @Test
- fun saveFindingByPentestId() {
- val pentestTwoId = "43fbc63c-f624-11ec-b939-0242ac120002"
- webTestClient.post()
- .uri("/pentests/{pentestId}/finding", pentestTwoId)
- .header("Authorization", "Bearer $tokenAdmin")
- .body(Mono.just(findingBody), FindingRequestBody::class.java)
- .exchange()
- .expectStatus().isAccepted
- .expectHeader().doesNotExist("")
- .expectBody().json(Json.write(findingBody))
- .consumeWith(
- WebTestClientRestDocumentation.document(
- "{methodName}",
- Preprocessors.preprocessRequest(
- Preprocessors.prettyPrint(),
- Preprocessors.modifyUris().removePort(),
- Preprocessors.removeHeaders("Host", "Content-Length")
- ),
- Preprocessors.preprocessResponse(
- Preprocessors.prettyPrint()
- ),
- RequestDocumentation.relaxedPathParameters(
- RequestDocumentation.parameterWithName("pentestId").description("The id of the pentest you want to save the finding for")
- ),
- PayloadDocumentation.relaxedResponseFields(
- PayloadDocumentation.fieldWithPath("id").type(JsonFieldType.STRING)
- .description("The id of the saved finding"),
- PayloadDocumentation.fieldWithPath("severity").type(JsonFieldType.STRING)
- .description("The severity of the finding"),
- PayloadDocumentation.fieldWithPath("title").type(JsonFieldType.STRING)
- .description("The title of the finding"),
- PayloadDocumentation.fieldWithPath("description").type(JsonFieldType.STRING)
- .description("The description number of the finding"),
- PayloadDocumentation.fieldWithPath("impact").type(JsonFieldType.STRING)
- .description("The impact of the finding"),
- PayloadDocumentation.fieldWithPath("affectedUrls").type(JsonFieldType.ARRAY)
- .description("List of affected Urls of the finding"),
- PayloadDocumentation.fieldWithPath("reproduction").type(JsonFieldType.STRING)
- .description("The reproduction steps of the finding"),
- PayloadDocumentation.fieldWithPath("mitigation").type(JsonFieldType.STRING)
- .description("The example mitigation for the finding")
- )
- )
- )
- }
-
- private val findingBody = FindingRequestBody(
- severity = "MEDIUM",
- title = "Found another Bug",
- description = "Another OTG-INFO-002 Bug",
- impact = "Service",
- affectedUrls = emptyList(),
- reproduction = "Step 1: Hack more",
- mitigation = "Another None"
- )
- }
-
- @Nested
- inner class UpdateFinding {
- @Test
- fun updateFindingById() {
- val findingId = "ab62d365-1b1d-4da1-89bc-5496616e220f"
- webTestClient.patch()
- .uri("/pentests/{findingId}/finding", findingId)
- .header("Authorization", "Bearer $tokenAdmin")
- .body(Mono.just(findingBody), FindingRequestBody::class.java)
- .exchange()
- .expectStatus().isAccepted
- .expectHeader().doesNotExist("")
- .expectBody().json(Json.write(findingBody))
- .consumeWith(
- WebTestClientRestDocumentation.document(
- "{methodName}",
- Preprocessors.preprocessRequest(
- Preprocessors.prettyPrint(),
- Preprocessors.modifyUris().removePort(),
- Preprocessors.removeHeaders("Host", "Content-Length")
- ),
- Preprocessors.preprocessResponse(
- Preprocessors.prettyPrint()
- ),
- RequestDocumentation.relaxedPathParameters(
- RequestDocumentation.parameterWithName("findingId").description("The id of the finding you want to update")
- ),
- PayloadDocumentation.relaxedResponseFields(
- PayloadDocumentation.fieldWithPath("id").type(JsonFieldType.STRING)
- .description("The id of the updated finding"),
- PayloadDocumentation.fieldWithPath("severity").type(JsonFieldType.STRING)
- .description("The severity of the finding"),
- PayloadDocumentation.fieldWithPath("title").type(JsonFieldType.STRING)
- .description("The title of the requested finding"),
- PayloadDocumentation.fieldWithPath("description").type(JsonFieldType.STRING)
- .description("The description number of the finding"),
- PayloadDocumentation.fieldWithPath("impact").type(JsonFieldType.STRING)
- .description("The impact of the finding"),
- PayloadDocumentation.fieldWithPath("affectedUrls").type(JsonFieldType.ARRAY)
- .description("List of affected Urls of the finding"),
- PayloadDocumentation.fieldWithPath("reproduction").type(JsonFieldType.STRING)
- .description("The reproduction steps of the finding"),
- PayloadDocumentation.fieldWithPath("mitigation").type(JsonFieldType.STRING)
- .description("The example mitigation for the finding")
- )
- )
- )
- }
-
- private val findingBody = FindingRequestBody(
- severity = "HIGH",
- title = "Updated Bug",
- description = "Updated OTG-INFO-002 Bug",
- impact = "Service",
- affectedUrls = emptyList(),
- reproduction = "Step 1: Hack",
- mitigation = "Still None"
- )
- }
-
- @Nested
- inner class DeleteFinding {
- @Test
- fun deleteFindingByPentestAndFindingId() {
- val pentestId = "43fbc63c-f624-11ec-b939-0242ac120002"
- val findingId = "ab62d365-1b1d-4da1-89bc-5496616e220f"
- webTestClient.delete()
- .uri("/pentests/{pentestId}/finding/{findingId}", pentestId, findingId)
- .header("Authorization", "Bearer $tokenAdmin")
- .exchange()
- .expectStatus().isOk
- .expectHeader().doesNotExist("")
- .expectBody()
- .consumeWith(
- WebTestClientRestDocumentation.document(
- "{methodName}",
- Preprocessors.preprocessRequest(
- Preprocessors.prettyPrint(),
- Preprocessors.modifyUris().removePort(),
- Preprocessors.removeHeaders("Host", "Content-Length")
- ),
- Preprocessors.preprocessResponse(
- Preprocessors.prettyPrint()
- ),
- RequestDocumentation.relaxedPathParameters(
- RequestDocumentation.parameterWithName("pentestId").description("The id of the pentest you want to remove the finidng from"),
- RequestDocumentation.parameterWithName("findingId").description("The id of the finding you want to delete")
- ),
- PayloadDocumentation.relaxedResponseFields(
- PayloadDocumentation.fieldWithPath("id").type(JsonFieldType.STRING)
- .description("The id of the finding you deleted")
- )
- )
- )
- }
- }
-
private fun persistBasicTestScenario() {
// setup test data
// Project
@@ -542,7 +260,7 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
category = PentestCategory.INFORMATION_GATHERING,
refNumber = "OTG-INFO-002",
status = PentestStatus.IN_PROGRESS,
- findingIds = listOf("ab62d365-1b1d-4da1-89bc-5496616e220f"),
+ findingIds = emptyList(),
commentIds = emptyList()
)
val pentestThree = Pentest(
@@ -554,23 +272,11 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
findingIds = emptyList(),
commentIds = emptyList()
)
- // Finding
- val findingOne = Finding(
- id = "ab62d365-1b1d-4da1-89bc-5496616e220f",
- severity = Severity.LOW,
- title = "Found Bug",
- description = "OTG-INFO-002 Bug",
- impact = "Service",
- affectedUrls = emptyList(),
- reproduction = "Step 1: Hack",
- mitigation = "None"
- )
// persist test data in database
mongoTemplate.save(ProjectEntity(projectOne))
mongoTemplate.save(PentestEntity(pentestOne))
mongoTemplate.save(PentestEntity(pentestTwo))
mongoTemplate.save(PentestEntity(pentestThree))
- mongoTemplate.save(FindingEntity(findingOne))
}
private fun configureAdminToken() {
@@ -580,7 +286,6 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
private fun cleanUp() {
mongoTemplate.findAllAndRemove(Query(), ProjectEntity::class.java)
mongoTemplate.findAllAndRemove(Query(), PentestEntity::class.java)
- mongoTemplate.findAllAndRemove(Query(), FindingEntity::class.java)
tokenAdmin = "n/a"
}
diff --git a/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/PentestControllerIntTest.kt b/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/PentestControllerIntTest.kt
index 87ac6d3..daa876c 100644
--- a/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/PentestControllerIntTest.kt
+++ b/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/PentestControllerIntTest.kt
@@ -5,7 +5,6 @@ import com.securityc4po.api.BaseIntTest
import com.securityc4po.api.configuration.NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR
import com.securityc4po.api.configuration.RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE
import com.securityc4po.api.configuration.SIC_INNER_SHOULD_BE_STATIC
-import com.securityc4po.api.finding.*
import com.securityc4po.api.project.Project
import com.securityc4po.api.project.ProjectEntity
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
@@ -86,7 +85,7 @@ class PentestControllerIntTest : BaseIntTest() {
category = PentestCategory.INFORMATION_GATHERING,
refNumber = "OTG-INFO-002",
status = PentestStatus.IN_PROGRESS,
- findingIds = listOf("ab62d365-1b1d-4da1-89bc-5496616e220f"),
+ findingIds = emptyList(),
commentIds = emptyList()
)
@@ -159,145 +158,6 @@ class PentestControllerIntTest : BaseIntTest() {
)
}
- @Nested
- inner class GetFindings {
- @Test
- fun `requesting findings by pentestId successfully`() {
- val pentestTwoId = "43fbc63c-f624-11ec-b939-0242ac120002"
- webTestClient.get()
- .uri("/pentests/{pentestId}/findings", pentestTwoId)
- .header("Authorization", "Bearer $tokenAdmin")
- .exchange()
- .expectStatus().isOk
- .expectHeader().valueEquals("Application-Name", "SecurityC4PO")
- .expectBody().json(Json.write(getFindings()))
- }
-
- private val findingOne = Finding(
- id = "ab62d365-1b1d-4da1-89bc-5496616e220f",
- severity = Severity.LOW,
- title = "Found Bug",
- description = "OTG-INFO-002 Bug",
- impact = "Service",
- affectedUrls = emptyList(),
- reproduction = "Step 1: Hack",
- mitigation = "None"
- )
-
- private fun getFindings() = listOf(
- findingOne.toFindingResponseBody()
- )
- }
-
- @Nested
- inner class GetFinding {
- @Test
- fun `requesting finding by findingId successfully`() {
- val findingId = "ab62d365-1b1d-4da1-89bc-5496616e220f"
- webTestClient.get()
- .uri("/pentests/{findingId}/finding", findingId)
- .header("Authorization", "Bearer $tokenAdmin")
- .exchange()
- .expectStatus().isOk
- .expectHeader().valueEquals("Application-Name", "SecurityC4PO")
- .expectBody().json(Json.write(findingOne.toFindingResponseBody()))
- }
-
- private val findingOne = Finding(
- id = "ab62d365-1b1d-4da1-89bc-5496616e220f",
- severity = Severity.LOW,
- title = "Found Bug",
- description = "OTG-INFO-002 Bug",
- impact = "Service",
- affectedUrls = emptyList(),
- reproduction = "Step 1: Hack",
- mitigation = "None"
- )
- }
-
- @Nested
- inner class SaveFinding {
- @Test
- fun `save finding successfully`() {
- val pentestTwoId = "43fbc63c-f624-11ec-b939-0242ac120002"
- webTestClient.post()
- .uri("/pentests/{pentestId}/finding", pentestTwoId)
- .header("Authorization", "Bearer $tokenAdmin")
- .body(Mono.just(findingBody), FindingRequestBody::class.java)
- .exchange()
- .expectStatus().isAccepted
- .expectHeader().valueEquals("Application-Name", "SecurityC4PO")
- .expectBody()
- .jsonPath("$.severity").isEqualTo("MEDIUM")
- .jsonPath("$.title").isEqualTo("Found another Bug")
- .jsonPath("$.description").isEqualTo("Another OTG-INFO-002 Bug")
- .jsonPath("$.impact").isEqualTo("Service")
- .jsonPath("$.affectedUrls").isEmpty
- .jsonPath("$.reproduction").isEqualTo("Step 1: Hack more")
- .jsonPath("$.mitigation").isEqualTo("Another None")
- }
-
- private val findingBody = FindingRequestBody(
- severity = "MEDIUM",
- title = "Found another Bug",
- description = "Another OTG-INFO-002 Bug",
- impact = "Service",
- affectedUrls = emptyList(),
- reproduction = "Step 1: Hack more",
- mitigation = "Another None"
- )
- }
-
- @Nested
- inner class UpdateFinding {
- @Test
- fun `update finding successfully`() {
- val findingId = "43fbc63c-f624-11ec-b939-0242ac120002"
- webTestClient.post()
- .uri("/pentests/{findingId}/finding", findingId)
- .header("Authorization", "Bearer $tokenAdmin")
- .body(Mono.just(findingBody), FindingRequestBody::class.java)
- .exchange()
- .expectStatus().isAccepted
- .expectHeader().valueEquals("Application-Name", "SecurityC4PO")
- .expectBody()
- .jsonPath("$.severity").isEqualTo("HIGH")
- .jsonPath("$.title").isEqualTo("Updated Bug")
- .jsonPath("$.description").isEqualTo("Updated OTG-INFO-002 Bug")
- .jsonPath("$.impact").isEqualTo("Service")
- .jsonPath("$.affectedUrls").isEmpty
- .jsonPath("$.reproduction").isEqualTo("Step 1: Hack")
- .jsonPath("$.mitigation").isEqualTo("Still None")
- }
-
- private val findingBody = FindingRequestBody(
- severity = "HIGH",
- title = "Updated Bug",
- description = "Updated OTG-INFO-002 Bug",
- impact = "Service",
- affectedUrls = emptyList(),
- reproduction = "Step 1: Hack",
- mitigation = "Still None"
- )
- }
-
- @Nested
- inner class DeleteFinding {
- @Test
- fun `delete finding successfully`() {
- val pentestId = "43fbc63c-f624-11ec-b939-0242ac120002"
- val findingId = "ab62d365-1b1d-4da1-89bc-5496616e220f"
- webTestClient.delete()
- .uri("/pentests/{pentestId}/finding/{findingId}", pentestId, findingId)
- .header("Authorization", "Bearer $tokenAdmin")
- .exchange()
- .expectStatus().isOk
- .expectHeader().valueEquals("Application-Name", "SecurityC4PO")
- .expectBody()
- .jsonPath("$.id").isEqualTo("ab62d365-1b1d-4da1-89bc-5496616e220f")
- }
- }
-
private fun persistBasicTestScenario() {
// setup test data
// project
@@ -325,7 +185,7 @@ class PentestControllerIntTest : BaseIntTest() {
category = PentestCategory.INFORMATION_GATHERING,
refNumber = "OTG-INFO-002",
status = PentestStatus.IN_PROGRESS,
- findingIds = listOf("ab62d365-1b1d-4da1-89bc-5496616e220f"),
+ findingIds = emptyList(),
commentIds = emptyList()
)
val pentestThree = Pentest(
@@ -337,23 +197,11 @@ class PentestControllerIntTest : BaseIntTest() {
findingIds = emptyList(),
commentIds = emptyList()
)
- // Finding
- val findingOne = Finding(
- id = "ab62d365-1b1d-4da1-89bc-5496616e220f",
- severity = Severity.LOW,
- title = "Found Bug",
- description = "OTG-INFO-002 Bug",
- impact = "Service",
- affectedUrls = emptyList(),
- reproduction = "Step 1: Hack",
- mitigation = "None"
- )
// persist test data in database
mongoTemplate.save(ProjectEntity(projectOne))
mongoTemplate.save(PentestEntity(pentestOne))
mongoTemplate.save(PentestEntity(pentestTwo))
mongoTemplate.save(PentestEntity(pentestThree))
- mongoTemplate.save(FindingEntity(findingOne))
}
private fun configureAdminToken() {
@@ -363,7 +211,6 @@ class PentestControllerIntTest : BaseIntTest() {
private fun cleanUp() {
mongoTemplate.findAllAndRemove(Query(), ProjectEntity::class.java)
mongoTemplate.findAllAndRemove(Query(), PentestEntity::class.java)
- mongoTemplate.findAllAndRemove(Query(), FindingEntity::class.java)
tokenAdmin = "n/a"
}
diff --git a/security-c4po-api/src/test/kotlin/com/securityc4po/api/comment/CommentControllerDocumentationTest.kt b/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/comment/CommentControllerDocumentationTest.kt
similarity index 97%
rename from security-c4po-api/src/test/kotlin/com/securityc4po/api/comment/CommentControllerDocumentationTest.kt
rename to security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/comment/CommentControllerDocumentationTest.kt
index 4853cd7..0778128 100644
--- a/security-c4po-api/src/test/kotlin/com/securityc4po/api/comment/CommentControllerDocumentationTest.kt
+++ b/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/comment/CommentControllerDocumentationTest.kt
@@ -1,4 +1,4 @@
-package com.securityc4po.api.comment
+package com.securityc4po.api.pentest.comment
import com.fasterxml.jackson.databind.ObjectMapper
import com.github.tomakehurst.wiremock.common.Json
@@ -10,6 +10,10 @@ import com.securityc4po.api.pentest.Pentest
import com.securityc4po.api.pentest.PentestCategory
import com.securityc4po.api.pentest.PentestEntity
import com.securityc4po.api.pentest.PentestStatus
+import com.securityc4po.api.pentest.comment.Comment
+import com.securityc4po.api.pentest.comment.CommentEntity
+import com.securityc4po.api.pentest.comment.CommentRequestBody
+import com.securityc4po.api.pentest.comment.toCommentResponseBody
import com.securityc4po.api.project.Project
import com.securityc4po.api.project.ProjectEntity
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
diff --git a/security-c4po-api/src/test/kotlin/com/securityc4po/api/comment/CommentControllerIntegrationTest.kt b/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/comment/CommentControllerIntegrationTest.kt
similarity index 95%
rename from security-c4po-api/src/test/kotlin/com/securityc4po/api/comment/CommentControllerIntegrationTest.kt
rename to security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/comment/CommentControllerIntegrationTest.kt
index d148436..36603ec 100644
--- a/security-c4po-api/src/test/kotlin/com/securityc4po/api/comment/CommentControllerIntegrationTest.kt
+++ b/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/comment/CommentControllerIntegrationTest.kt
@@ -1,4 +1,4 @@
-package com.securityc4po.api.comment
+package com.securityc4po.api.pentest.comment
import com.github.tomakehurst.wiremock.common.Json
import com.securityc4po.api.BaseIntTest
@@ -9,6 +9,10 @@ import com.securityc4po.api.pentest.Pentest
import com.securityc4po.api.pentest.PentestCategory
import com.securityc4po.api.pentest.PentestEntity
import com.securityc4po.api.pentest.PentestStatus
+import com.securityc4po.api.pentest.comment.Comment
+import com.securityc4po.api.pentest.comment.CommentEntity
+import com.securityc4po.api.pentest.comment.CommentRequestBody
+import com.securityc4po.api.pentest.comment.toCommentResponseBody
import com.securityc4po.api.project.Project
import com.securityc4po.api.project.ProjectEntity
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
diff --git a/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/finding/FindingControllerDocumentationTest.kt b/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/finding/FindingControllerDocumentationTest.kt
new file mode 100644
index 0000000..5caaa32
--- /dev/null
+++ b/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/finding/FindingControllerDocumentationTest.kt
@@ -0,0 +1,403 @@
+package com.securityc4po.api.pentest.finding
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.github.tomakehurst.wiremock.common.Json
+import com.securityc4po.api.BaseDocumentationIntTest
+import com.securityc4po.api.configuration.NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR
+import com.securityc4po.api.configuration.RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE
+import com.securityc4po.api.configuration.SIC_INNER_SHOULD_BE_STATIC
+import com.securityc4po.api.pentest.Pentest
+import com.securityc4po.api.pentest.PentestCategory
+import com.securityc4po.api.pentest.PentestEntity
+import com.securityc4po.api.pentest.PentestStatus
+import com.securityc4po.api.project.Project
+import com.securityc4po.api.project.ProjectEntity
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.data.mongodb.core.MongoTemplate
+import org.springframework.data.mongodb.core.query.Query
+import org.springframework.restdocs.operation.preprocess.Preprocessors
+import org.springframework.restdocs.payload.JsonFieldType
+import org.springframework.restdocs.payload.PayloadDocumentation
+import org.springframework.restdocs.request.RequestDocumentation
+import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation
+import reactor.core.publisher.Mono
+
+@SuppressFBWarnings(
+ SIC_INNER_SHOULD_BE_STATIC,
+ NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR,
+ RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE
+)
+class FindingControllerDocumentationTest: BaseDocumentationIntTest() {
+
+ @Autowired
+ lateinit var mongoTemplate: MongoTemplate
+ var mapper = ObjectMapper()
+
+ @BeforeEach
+ fun init() {
+ configureAdminToken()
+ persistBasicTestScenario()
+ }
+
+ @AfterEach
+ fun destroy() {
+ cleanUp()
+ }
+
+ @Nested
+ inner class GetFindings {
+ @Test
+ fun getFindingsByPentestId() {
+ val pentestTwoId = "43fbc63c-f624-11ec-b939-0242ac120002"
+ webTestClient.get()
+ .uri("/pentests/{pentestId}/findings", pentestTwoId)
+ .header("Authorization", "Bearer $tokenAdmin")
+ .exchange()
+ .expectStatus().isOk
+ .expectHeader().doesNotExist("")
+ .expectBody().json(Json.write(getFindingsResponse()))
+ .consumeWith(
+ WebTestClientRestDocumentation.document(
+ "{methodName}",
+ Preprocessors.preprocessRequest(
+ Preprocessors.prettyPrint(),
+ Preprocessors.modifyUris().removePort(),
+ Preprocessors.removeHeaders("Host", "Content-Length")
+ ),
+ Preprocessors.preprocessResponse(
+ Preprocessors.prettyPrint()
+ ),
+ RequestDocumentation.relaxedPathParameters(
+ RequestDocumentation.parameterWithName("pentestId").description("The id of the pentest you want to get the findings for")
+ ),
+ PayloadDocumentation.relaxedResponseFields(
+ PayloadDocumentation.fieldWithPath("[].id").type(JsonFieldType.STRING)
+ .description("The id of the requested findings"),
+ PayloadDocumentation.fieldWithPath("[].severity").type(JsonFieldType.STRING)
+ .description("The severity of the finding"),
+ PayloadDocumentation.fieldWithPath("[].title").type(JsonFieldType.STRING)
+ .description("The title of the requested finding"),
+ PayloadDocumentation.fieldWithPath("[].description").type(JsonFieldType.STRING)
+ .description("The description number of the finding"),
+ PayloadDocumentation.fieldWithPath("[].impact").type(JsonFieldType.STRING)
+ .description("The impact of the finding"),
+ PayloadDocumentation.fieldWithPath("[].affectedUrls").type(JsonFieldType.ARRAY)
+ .description("List of affected Urls of the finding"),
+ PayloadDocumentation.fieldWithPath("[].reproduction").type(JsonFieldType.STRING)
+ .description("The reproduction steps of the finding"),
+ PayloadDocumentation.fieldWithPath("[].mitigation").type(JsonFieldType.STRING)
+ .description("The example mitigation for the finding")
+ )
+ )
+ )
+ }
+
+ private val findingOne = Finding(
+ id = "ab62d365-1b1d-4da1-89bc-5496616e220f",
+ severity = Severity.LOW,
+ title = "Found Bug",
+ description = "OTG-INFO-002 Bug",
+ impact = "Service",
+ affectedUrls = emptyList(),
+ reproduction = "Step 1: Hack",
+ mitigation = "None"
+ )
+
+ private fun getFindingsResponse() = listOf(
+ findingOne.toFindingResponseBody()
+ )
+ }
+
+ @Nested
+ inner class GetFinding {
+ @Test
+ fun getFindingById() {
+ val findingId = "ab62d365-1b1d-4da1-89bc-5496616e220f"
+ webTestClient.get()
+ .uri("/pentests/{findingId}/finding", findingId)
+ .header("Authorization", "Bearer $tokenAdmin")
+ .exchange()
+ .expectStatus().isOk
+ .expectHeader().doesNotExist("")
+ .expectBody().json(Json.write(findingOne.toFindingResponseBody()))
+ .consumeWith(
+ WebTestClientRestDocumentation.document(
+ "{methodName}",
+ Preprocessors.preprocessRequest(
+ Preprocessors.prettyPrint(),
+ Preprocessors.modifyUris().removePort(),
+ Preprocessors.removeHeaders("Host", "Content-Length")
+ ),
+ Preprocessors.preprocessResponse(
+ Preprocessors.prettyPrint()
+ ),
+ RequestDocumentation.relaxedPathParameters(
+ RequestDocumentation.parameterWithName("findingId").description("The id of the feinidng you want to get")
+ ),
+ PayloadDocumentation.relaxedResponseFields(
+ PayloadDocumentation.fieldWithPath("id").type(JsonFieldType.STRING)
+ .description("The id of the requested finding"),
+ PayloadDocumentation.fieldWithPath("severity").type(JsonFieldType.STRING)
+ .description("The severity of the finding"),
+ PayloadDocumentation.fieldWithPath("title").type(JsonFieldType.STRING)
+ .description("The title of the requested finding"),
+ PayloadDocumentation.fieldWithPath("description").type(JsonFieldType.STRING)
+ .description("The description number of the finding"),
+ PayloadDocumentation.fieldWithPath("impact").type(JsonFieldType.STRING)
+ .description("The impact of the finding"),
+ PayloadDocumentation.fieldWithPath("affectedUrls").type(JsonFieldType.ARRAY)
+ .description("List of affected Urls of the finding"),
+ PayloadDocumentation.fieldWithPath("reproduction").type(JsonFieldType.STRING)
+ .description("The reproduction steps of the finding"),
+ PayloadDocumentation.fieldWithPath("mitigation").type(JsonFieldType.STRING)
+ .description("The example mitigation for the finding")
+ )
+ )
+ )
+ }
+
+ private val findingOne = Finding(
+ id = "ab62d365-1b1d-4da1-89bc-5496616e220f",
+ severity = Severity.LOW,
+ title = "Found Bug",
+ description = "OTG-INFO-002 Bug",
+ impact = "Service",
+ affectedUrls = emptyList(),
+ reproduction = "Step 1: Hack",
+ mitigation = "None"
+ )
+ }
+
+ @Nested
+ inner class SaveFinding {
+ @Test
+ fun saveFindingByPentestId() {
+ val pentestTwoId = "43fbc63c-f624-11ec-b939-0242ac120002"
+ webTestClient.post()
+ .uri("/pentests/{pentestId}/finding", pentestTwoId)
+ .header("Authorization", "Bearer $tokenAdmin")
+ .body(Mono.just(findingBody), FindingRequestBody::class.java)
+ .exchange()
+ .expectStatus().isAccepted
+ .expectHeader().doesNotExist("")
+ .expectBody().json(Json.write(findingBody))
+ .consumeWith(
+ WebTestClientRestDocumentation.document(
+ "{methodName}",
+ Preprocessors.preprocessRequest(
+ Preprocessors.prettyPrint(),
+ Preprocessors.modifyUris().removePort(),
+ Preprocessors.removeHeaders("Host", "Content-Length")
+ ),
+ Preprocessors.preprocessResponse(
+ Preprocessors.prettyPrint()
+ ),
+ RequestDocumentation.relaxedPathParameters(
+ RequestDocumentation.parameterWithName("pentestId").description("The id of the pentest you want to save the finding for")
+ ),
+ PayloadDocumentation.relaxedResponseFields(
+ PayloadDocumentation.fieldWithPath("id").type(JsonFieldType.STRING)
+ .description("The id of the saved finding"),
+ PayloadDocumentation.fieldWithPath("severity").type(JsonFieldType.STRING)
+ .description("The severity of the finding"),
+ PayloadDocumentation.fieldWithPath("title").type(JsonFieldType.STRING)
+ .description("The title of the finding"),
+ PayloadDocumentation.fieldWithPath("description").type(JsonFieldType.STRING)
+ .description("The description number of the finding"),
+ PayloadDocumentation.fieldWithPath("impact").type(JsonFieldType.STRING)
+ .description("The impact of the finding"),
+ PayloadDocumentation.fieldWithPath("affectedUrls").type(JsonFieldType.ARRAY)
+ .description("List of affected Urls of the finding"),
+ PayloadDocumentation.fieldWithPath("reproduction").type(JsonFieldType.STRING)
+ .description("The reproduction steps of the finding"),
+ PayloadDocumentation.fieldWithPath("mitigation").type(JsonFieldType.STRING)
+ .description("The example mitigation for the finding")
+ )
+ )
+ )
+ }
+
+ private val findingBody = FindingRequestBody(
+ severity = "MEDIUM",
+ title = "Found another Bug",
+ description = "Another OTG-INFO-002 Bug",
+ impact = "Service",
+ affectedUrls = emptyList(),
+ reproduction = "Step 1: Hack more",
+ mitigation = "Another None"
+ )
+ }
+
+ @Nested
+ inner class UpdateFinding {
+ @Test
+ fun updateFindingById() {
+ val findingId = "ab62d365-1b1d-4da1-89bc-5496616e220f"
+ webTestClient.patch()
+ .uri("/pentests/{findingId}/finding", findingId)
+ .header("Authorization", "Bearer $tokenAdmin")
+ .body(Mono.just(findingBody), FindingRequestBody::class.java)
+ .exchange()
+ .expectStatus().isAccepted
+ .expectHeader().doesNotExist("")
+ .expectBody().json(Json.write(findingBody))
+ .consumeWith(
+ WebTestClientRestDocumentation.document(
+ "{methodName}",
+ Preprocessors.preprocessRequest(
+ Preprocessors.prettyPrint(),
+ Preprocessors.modifyUris().removePort(),
+ Preprocessors.removeHeaders("Host", "Content-Length")
+ ),
+ Preprocessors.preprocessResponse(
+ Preprocessors.prettyPrint()
+ ),
+ RequestDocumentation.relaxedPathParameters(
+ RequestDocumentation.parameterWithName("findingId").description("The id of the finding you want to update")
+ ),
+ PayloadDocumentation.relaxedResponseFields(
+ PayloadDocumentation.fieldWithPath("id").type(JsonFieldType.STRING)
+ .description("The id of the updated finding"),
+ PayloadDocumentation.fieldWithPath("severity").type(JsonFieldType.STRING)
+ .description("The severity of the finding"),
+ PayloadDocumentation.fieldWithPath("title").type(JsonFieldType.STRING)
+ .description("The title of the requested finding"),
+ PayloadDocumentation.fieldWithPath("description").type(JsonFieldType.STRING)
+ .description("The description number of the finding"),
+ PayloadDocumentation.fieldWithPath("impact").type(JsonFieldType.STRING)
+ .description("The impact of the finding"),
+ PayloadDocumentation.fieldWithPath("affectedUrls").type(JsonFieldType.ARRAY)
+ .description("List of affected Urls of the finding"),
+ PayloadDocumentation.fieldWithPath("reproduction").type(JsonFieldType.STRING)
+ .description("The reproduction steps of the finding"),
+ PayloadDocumentation.fieldWithPath("mitigation").type(JsonFieldType.STRING)
+ .description("The example mitigation for the finding")
+ )
+ )
+ )
+ }
+
+ private val findingBody = FindingRequestBody(
+ severity = "HIGH",
+ title = "Updated Bug",
+ description = "Updated OTG-INFO-002 Bug",
+ impact = "Service",
+ affectedUrls = emptyList(),
+ reproduction = "Step 1: Hack",
+ mitigation = "Still None"
+ )
+ }
+
+ @Nested
+ inner class DeleteFinding {
+ @Test
+ fun deleteFindingByPentestAndFindingId() {
+ val pentestId = "43fbc63c-f624-11ec-b939-0242ac120002"
+ val findingId = "ab62d365-1b1d-4da1-89bc-5496616e220f"
+ webTestClient.delete()
+ .uri("/pentests/{pentestId}/finding/{findingId}", pentestId, findingId)
+ .header("Authorization", "Bearer $tokenAdmin")
+ .exchange()
+ .expectStatus().isOk
+ .expectHeader().doesNotExist("")
+ .expectBody()
+ .consumeWith(
+ WebTestClientRestDocumentation.document(
+ "{methodName}",
+ Preprocessors.preprocessRequest(
+ Preprocessors.prettyPrint(),
+ Preprocessors.modifyUris().removePort(),
+ Preprocessors.removeHeaders("Host", "Content-Length")
+ ),
+ Preprocessors.preprocessResponse(
+ Preprocessors.prettyPrint()
+ ),
+ RequestDocumentation.relaxedPathParameters(
+ RequestDocumentation.parameterWithName("pentestId").description("The id of the pentest you want to remove the finidng from"),
+ RequestDocumentation.parameterWithName("findingId").description("The id of the finding you want to delete")
+ ),
+ PayloadDocumentation.relaxedResponseFields(
+ PayloadDocumentation.fieldWithPath("id").type(JsonFieldType.STRING)
+ .description("The id of the finding you deleted")
+ )
+ )
+ )
+ }
+ }
+
+ private fun persistBasicTestScenario() {
+ // setup test data
+ // Project
+ val projectOne = Project(
+ id = "d2e126ba-f608-11ec-b939-0242ac120025",
+ client = "E Corp",
+ title = "Some Mock API (v1.0) Scanning",
+ createdAt = "2021-01-10T18:05:00Z",
+ tester = "Novatester",
+ projectPentests = emptyList(),
+ createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032"
+ )
+ // Pentests
+ val pentestOne = Pentest(
+ id = "9c8af320-f608-11ec-b939-0242ac120002",
+ projectId = "d2e126ba-f608-11ec-b939-0242ac120025",
+ category = PentestCategory.INFORMATION_GATHERING,
+ refNumber = "OTG-INFO-001",
+ status = PentestStatus.NOT_STARTED,
+ findingIds = emptyList(),
+ commentIds = emptyList()
+ )
+ val pentestTwo = Pentest(
+ id = "43fbc63c-f624-11ec-b939-0242ac120002",
+ projectId = "d2e126ba-f608-11ec-b939-0242ac120025",
+ category = PentestCategory.INFORMATION_GATHERING,
+ refNumber = "OTG-INFO-002",
+ status = PentestStatus.IN_PROGRESS,
+ findingIds = listOf("ab62d365-1b1d-4da1-89bc-5496616e220f"),
+ commentIds = emptyList()
+ )
+ val pentestThree = Pentest(
+ id = "74eae112-f62c-11ec-b939-0242ac120002",
+ projectId = "d2e126ba-f608-11ec-b939-0242ac120025",
+ category = PentestCategory.AUTHENTICATION_TESTING,
+ refNumber = "OTG-AUTHN-001",
+ status = PentestStatus.COMPLETED,
+ findingIds = emptyList(),
+ commentIds = emptyList()
+ )
+ // Finding
+ val findingOne = Finding(
+ id = "ab62d365-1b1d-4da1-89bc-5496616e220f",
+ severity = Severity.LOW,
+ title = "Found Bug",
+ description = "OTG-INFO-002 Bug",
+ impact = "Service",
+ affectedUrls = emptyList(),
+ reproduction = "Step 1: Hack",
+ mitigation = "None"
+ )
+ // persist test data in database
+ mongoTemplate.save(ProjectEntity(projectOne))
+ mongoTemplate.save(PentestEntity(pentestOne))
+ mongoTemplate.save(PentestEntity(pentestTwo))
+ mongoTemplate.save(PentestEntity(pentestThree))
+ mongoTemplate.save(FindingEntity(findingOne))
+ }
+
+ private fun configureAdminToken() {
+ tokenAdmin = getAccessToken("test_admin", "test", "c4po_local", "c4po_realm_local")
+ }
+
+ private fun cleanUp() {
+ mongoTemplate.findAllAndRemove(Query(), ProjectEntity::class.java)
+ mongoTemplate.findAllAndRemove(Query(), PentestEntity::class.java)
+ mongoTemplate.findAllAndRemove(Query(), FindingEntity::class.java)
+
+ tokenAdmin = "n/a"
+ }
+}
\ No newline at end of file
diff --git a/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/finding/FindingControllerIntTest.kt b/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/finding/FindingControllerIntTest.kt
new file mode 100644
index 0000000..c4b6907
--- /dev/null
+++ b/security-c4po-api/src/test/kotlin/com/securityc4po/api/pentest/finding/FindingControllerIntTest.kt
@@ -0,0 +1,270 @@
+package com.securityc4po.api.pentest.finding
+
+import com.github.tomakehurst.wiremock.common.Json
+import com.securityc4po.api.BaseIntTest
+import com.securityc4po.api.configuration.NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR
+import com.securityc4po.api.configuration.RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE
+import com.securityc4po.api.configuration.SIC_INNER_SHOULD_BE_STATIC
+import com.securityc4po.api.pentest.Pentest
+import com.securityc4po.api.pentest.PentestCategory
+import com.securityc4po.api.pentest.PentestEntity
+import com.securityc4po.api.pentest.PentestStatus
+import com.securityc4po.api.project.Project
+import com.securityc4po.api.project.ProjectEntity
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.web.server.LocalServerPort
+import org.springframework.data.mongodb.core.MongoTemplate
+import org.springframework.data.mongodb.core.query.Query
+import org.springframework.test.web.reactive.server.WebTestClient
+import reactor.core.publisher.Mono
+import java.time.Duration
+
+@SuppressFBWarnings(
+ SIC_INNER_SHOULD_BE_STATIC,
+ NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR,
+ RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE
+)
+class FindingControllerIntTest: BaseIntTest() {
+
+ @LocalServerPort
+ private var port = 0
+
+ @Autowired
+ lateinit var mongoTemplate: MongoTemplate
+
+ @Autowired
+ private lateinit var webTestClient: WebTestClient
+
+ @BeforeEach
+ fun setupWebClient() {
+ webTestClient = WebTestClient.bindToServer()
+ .baseUrl("http://localhost:$port")
+ .responseTimeout(Duration.ofMillis(10000))
+ .build()
+ }
+
+ @BeforeEach
+ fun init() {
+ configureAdminToken()
+ persistBasicTestScenario()
+ }
+
+ @AfterEach
+ fun destroy() {
+ cleanUp()
+ }
+
+ @Nested
+ inner class GetFindings {
+ @Test
+ fun `requesting findings by pentestId successfully`() {
+ val pentestTwoId = "43fbc63c-f624-11ec-b939-0242ac120002"
+ webTestClient.get()
+ .uri("/pentests/{pentestId}/findings", pentestTwoId)
+ .header("Authorization", "Bearer $tokenAdmin")
+ .exchange()
+ .expectStatus().isOk
+ .expectHeader().valueEquals("Application-Name", "SecurityC4PO")
+ .expectBody().json(Json.write(getFindings()))
+ }
+
+ private val findingOne = Finding(
+ id = "ab62d365-1b1d-4da1-89bc-5496616e220f",
+ severity = Severity.LOW,
+ title = "Found Bug",
+ description = "OTG-INFO-002 Bug",
+ impact = "Service",
+ affectedUrls = emptyList(),
+ reproduction = "Step 1: Hack",
+ mitigation = "None"
+ )
+
+ private fun getFindings() = listOf(
+ findingOne.toFindingResponseBody()
+ )
+ }
+
+ @Nested
+ inner class GetFinding {
+ @Test
+ fun `requesting finding by findingId successfully`() {
+ val findingId = "ab62d365-1b1d-4da1-89bc-5496616e220f"
+ webTestClient.get()
+ .uri("/pentests/{findingId}/finding", findingId)
+ .header("Authorization", "Bearer $tokenAdmin")
+ .exchange()
+ .expectStatus().isOk
+ .expectHeader().valueEquals("Application-Name", "SecurityC4PO")
+ .expectBody().json(Json.write(findingOne.toFindingResponseBody()))
+ }
+
+ private val findingOne = Finding(
+ id = "ab62d365-1b1d-4da1-89bc-5496616e220f",
+ severity = Severity.LOW,
+ title = "Found Bug",
+ description = "OTG-INFO-002 Bug",
+ impact = "Service",
+ affectedUrls = emptyList(),
+ reproduction = "Step 1: Hack",
+ mitigation = "None"
+ )
+ }
+
+ @Nested
+ inner class SaveFinding {
+ @Test
+ fun `save finding successfully`() {
+ val pentestTwoId = "43fbc63c-f624-11ec-b939-0242ac120002"
+ webTestClient.post()
+ .uri("/pentests/{pentestId}/finding", pentestTwoId)
+ .header("Authorization", "Bearer $tokenAdmin")
+ .body(Mono.just(findingBody), FindingRequestBody::class.java)
+ .exchange()
+ .expectStatus().isAccepted
+ .expectHeader().valueEquals("Application-Name", "SecurityC4PO")
+ .expectBody()
+ .jsonPath("$.severity").isEqualTo("MEDIUM")
+ .jsonPath("$.title").isEqualTo("Found another Bug")
+ .jsonPath("$.description").isEqualTo("Another OTG-INFO-002 Bug")
+ .jsonPath("$.impact").isEqualTo("Service")
+ .jsonPath("$.affectedUrls").isEmpty
+ .jsonPath("$.reproduction").isEqualTo("Step 1: Hack more")
+ .jsonPath("$.mitigation").isEqualTo("Another None")
+ }
+
+ private val findingBody = FindingRequestBody(
+ severity = "MEDIUM",
+ title = "Found another Bug",
+ description = "Another OTG-INFO-002 Bug",
+ impact = "Service",
+ affectedUrls = emptyList(),
+ reproduction = "Step 1: Hack more",
+ mitigation = "Another None"
+ )
+ }
+
+ @Nested
+ inner class UpdateFinding {
+ @Test
+ fun `update finding successfully`() {
+ val findingId = "43fbc63c-f624-11ec-b939-0242ac120002"
+ webTestClient.post()
+ .uri("/pentests/{findingId}/finding", findingId)
+ .header("Authorization", "Bearer $tokenAdmin")
+ .body(Mono.just(findingBody), FindingRequestBody::class.java)
+ .exchange()
+ .expectStatus().isAccepted
+ .expectHeader().valueEquals("Application-Name", "SecurityC4PO")
+ .expectBody()
+ .jsonPath("$.severity").isEqualTo("HIGH")
+ .jsonPath("$.title").isEqualTo("Updated Bug")
+ .jsonPath("$.description").isEqualTo("Updated OTG-INFO-002 Bug")
+ .jsonPath("$.impact").isEqualTo("Service")
+ .jsonPath("$.affectedUrls").isEmpty
+ .jsonPath("$.reproduction").isEqualTo("Step 1: Hack")
+ .jsonPath("$.mitigation").isEqualTo("Still None")
+ }
+
+ private val findingBody = FindingRequestBody(
+ severity = "HIGH",
+ title = "Updated Bug",
+ description = "Updated OTG-INFO-002 Bug",
+ impact = "Service",
+ affectedUrls = emptyList(),
+ reproduction = "Step 1: Hack",
+ mitigation = "Still None"
+ )
+ }
+
+ @Nested
+ inner class DeleteFinding {
+ @Test
+ fun `delete finding successfully`() {
+ val pentestId = "43fbc63c-f624-11ec-b939-0242ac120002"
+ val findingId = "ab62d365-1b1d-4da1-89bc-5496616e220f"
+ webTestClient.delete()
+ .uri("/pentests/{pentestId}/finding/{findingId}", pentestId, findingId)
+ .header("Authorization", "Bearer $tokenAdmin")
+ .exchange()
+ .expectStatus().isOk
+ .expectHeader().valueEquals("Application-Name", "SecurityC4PO")
+ .expectBody()
+ .jsonPath("$.id").isEqualTo("ab62d365-1b1d-4da1-89bc-5496616e220f")
+ }
+ }
+
+ private fun persistBasicTestScenario() {
+ // setup test data
+ // project
+ val projectOne = Project(
+ id = "d2e126ba-f608-11ec-b939-0242ac120025",
+ client = "E Corp",
+ title = "Some Mock API (v1.0) Scanning",
+ createdAt = "2021-01-10T18:05:00Z",
+ tester = "Novatester",
+ createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032"
+ )
+ // pentests
+ val pentestOne = Pentest(
+ id = "9c8af320-f608-11ec-b939-0242ac120002",
+ projectId = "d2e126ba-f608-11ec-b939-0242ac120025",
+ category = PentestCategory.INFORMATION_GATHERING,
+ refNumber = "OTG-INFO-001",
+ status = PentestStatus.NOT_STARTED,
+ findingIds = emptyList(),
+ commentIds = emptyList()
+ )
+ val pentestTwo = Pentest(
+ id = "43fbc63c-f624-11ec-b939-0242ac120002",
+ projectId = "d2e126ba-f608-11ec-b939-0242ac120025",
+ category = PentestCategory.INFORMATION_GATHERING,
+ refNumber = "OTG-INFO-002",
+ status = PentestStatus.IN_PROGRESS,
+ findingIds = listOf("ab62d365-1b1d-4da1-89bc-5496616e220f"),
+ commentIds = emptyList()
+ )
+ val pentestThree = Pentest(
+ id = "16vbc63c-f624-11ec-b939-0242ac120002",
+ projectId = "d2e126ba-f608-11ec-b939-0242ac120025",
+ category = PentestCategory.AUTHENTICATION_TESTING,
+ refNumber = "OTG-AUTHN-001",
+ status = PentestStatus.COMPLETED,
+ findingIds = emptyList(),
+ commentIds = emptyList()
+ )
+ // Finding
+ val findingOne = Finding(
+ id = "ab62d365-1b1d-4da1-89bc-5496616e220f",
+ severity = Severity.LOW,
+ title = "Found Bug",
+ description = "OTG-INFO-002 Bug",
+ impact = "Service",
+ affectedUrls = emptyList(),
+ reproduction = "Step 1: Hack",
+ mitigation = "None"
+ )
+ // persist test data in database
+ mongoTemplate.save(ProjectEntity(projectOne))
+ mongoTemplate.save(PentestEntity(pentestOne))
+ mongoTemplate.save(PentestEntity(pentestTwo))
+ mongoTemplate.save(PentestEntity(pentestThree))
+ mongoTemplate.save(FindingEntity(findingOne))
+ }
+
+ private fun configureAdminToken() {
+ tokenAdmin = getAccessToken("test_admin", "test", "c4po_local", "c4po_realm_local")
+ }
+
+ private fun cleanUp() {
+ mongoTemplate.findAllAndRemove(Query(), ProjectEntity::class.java)
+ mongoTemplate.findAllAndRemove(Query(), PentestEntity::class.java)
+ mongoTemplate.findAllAndRemove(Query(), FindingEntity::class.java)
+
+ tokenAdmin = "n/a"
+ }
+}
\ No newline at end of file
diff --git a/security-c4po-api/src/test/resources/collections/comments.json b/security-c4po-api/src/test/resources/collections/comments.json
index 1873d18..eb532da 100644
--- a/security-c4po-api/src/test/resources/collections/comments.json
+++ b/security-c4po-api/src/test/resources/collections/comments.json
@@ -10,7 +10,7 @@
"data": {
"_id": "89703b19-16c7-49e5-8e33-0c706313e5fe",
"title": "Test Comment",
- "description": "Test Comment Description",
+ "description": "No related findings",
"relatedFindings": []
},
"_class": "com.securityc4po.api.comment.CommentEntity"
@@ -25,8 +25,8 @@
},
"data": {
"_id": "df516de6-ca5e-44a6-ac50-db89bb17aac3",
- "title": "New Test",
- "description": "New Test",
+ "title": "New Test Comment",
+ "description": "Two related findings",
"relatedFindings": [
"0bda8950-94fa-4ec6-8fa7-e09f5a8cd3e8",
"4ddb84f6-068c-4319-a8ee-1000008bb75a"
@@ -44,8 +44,8 @@
},
"data": {
"_id": "e55e943b-6a48-4d84-8d72-b48d7d9de5b7",
- "title": "Wow another one?",
- "description": "Epic!",
+ "title": "Another Test Comment",
+ "description": "One related findings",
"relatedFindings": [
"5e22d38f-a4f6-4809-84ea-a803b5f1f9fc"
]