Compare commits
1 Commits
main
...
mhg_c4po_7
Author | SHA1 | Date |
---|---|---|
|
862862cdcd |
|
@ -49,6 +49,7 @@
|
|||
size="small"
|
||||
shape="round"
|
||||
class="add-finding-button"
|
||||
[disabled]="pentestInfo$.getValue().status === notStartedStatus"
|
||||
(click)="onClickAddFinding()">
|
||||
<fa-icon [icon]="fa.faPlus" class="new-finding-icon"></fa-icon>
|
||||
{{'finding.add' | translate}}
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {PentestService} from '@shared/services/pentest.service';
|
||||
import {BehaviorSubject, Observable} from 'rxjs';
|
||||
import {Pentest} from '@shared/models/pentest.model';
|
||||
import {Pentest, transformPentestToRequestBody} from '@shared/models/pentest.model';
|
||||
import {UntilDestroy, untilDestroyed} from '@ngneat/until-destroy';
|
||||
import {filter, mergeMap, tap} from 'rxjs/operators';
|
||||
import {NotificationService, PopupType} from '@shared/services/notification.service';
|
||||
import {Finding, FindingDialogBody, FindingEntry, transformFindingsToObjectiveEntries} from '@shared/models/finding.model';
|
||||
import {
|
||||
Finding,
|
||||
FindingDialogBody,
|
||||
FindingEntry,
|
||||
transformFindingsToObjectiveEntries,
|
||||
transformFindingToRequestBody
|
||||
} from '@shared/models/finding.model';
|
||||
import {NbGetters, NbTreeGridDataSource, NbTreeGridDataSourceBuilder} from '@nebular/theme';
|
||||
import * as FA from '@fortawesome/free-solid-svg-icons';
|
||||
import {isNotNullOrUndefined} from 'codelyzer/util/isNotNullOrUndefined';
|
||||
import {FindingDialogService} from '@shared/modules/finding-dialog/service/finding-dialog.service';
|
||||
import {FindingDialogComponent} from '@shared/modules/finding-dialog/finding-dialog.component';
|
||||
import {PentestStatus} from '@shared/models/pentest-status.model';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
|
@ -20,6 +27,13 @@ import {FindingDialogComponent} from '@shared/modules/finding-dialog/finding-dia
|
|||
})
|
||||
export class PentestFindingsComponent implements OnInit {
|
||||
|
||||
constructor(private readonly pentestService: PentestService,
|
||||
private dataSourceBuilder: NbTreeGridDataSourceBuilder<FindingEntry>,
|
||||
private notificationService: NotificationService,
|
||||
private findingDialogService: FindingDialogService) {
|
||||
this.dataSource = dataSourceBuilder.create(this.data, this.getters);
|
||||
}
|
||||
|
||||
@Input()
|
||||
pentestInfo$: BehaviorSubject<Pentest> = new BehaviorSubject<Pentest>(null);
|
||||
|
||||
|
@ -40,12 +54,8 @@ export class PentestFindingsComponent implements OnInit {
|
|||
expandedGetter: (node: FindingEntry) => !!node.expanded,
|
||||
};
|
||||
|
||||
constructor(private readonly pentestService: PentestService,
|
||||
private dataSourceBuilder: NbTreeGridDataSourceBuilder<FindingEntry>,
|
||||
private notificationService: NotificationService,
|
||||
private findingDialogService: FindingDialogService) {
|
||||
this.dataSource = dataSourceBuilder.create(this.data, this.getters);
|
||||
}
|
||||
// HTML only
|
||||
notStartedStatus: PentestStatus = PentestStatus.NOT_STARTED;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadFindingsData();
|
||||
|
@ -87,7 +97,10 @@ export class PentestFindingsComponent implements OnInit {
|
|||
filter(value => !!value),
|
||||
tap((value) => console.warn('FindingDialogBody: ', value)),
|
||||
mergeMap((value: FindingDialogBody) =>
|
||||
this.pentestService.saveFinding(this.pentestInfo$.getValue() ? this.pentestInfo$.getValue().id : '', value)
|
||||
this.pentestService.saveFinding(
|
||||
this.pentestInfo$.getValue() ? this.pentestInfo$.getValue().id : '',
|
||||
transformFindingToRequestBody(value)
|
||||
)
|
||||
),
|
||||
untilDestroyed(this)
|
||||
).subscribe({
|
||||
|
@ -110,7 +123,6 @@ export class PentestFindingsComponent implements OnInit {
|
|||
console.info('Coming soon..');
|
||||
}
|
||||
|
||||
// HTML only
|
||||
isLoading(): Observable<boolean> {
|
||||
return this.loading$.asObservable();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import {v4 as UUID} from 'uuid';
|
||||
import {Severity} from '@shared/models/severity.enum';
|
||||
import {Category} from '@shared/models/category.model';
|
||||
import {Pentest} from '@shared/models/pentest.model';
|
||||
|
||||
export class Finding {
|
||||
id?: string;
|
||||
|
@ -56,6 +58,25 @@ export function transformFindingsToObjectiveEntries(findings: Finding[]): Findin
|
|||
return findingEntries;
|
||||
}
|
||||
|
||||
export function transformFindingToRequestBody(finding: FindingDialogBody | Finding): Finding {
|
||||
const transformedFinding = {
|
||||
...finding,
|
||||
severity: typeof finding.severity === 'number' ? Severity[finding.severity] : finding.severity,
|
||||
title: finding.title,
|
||||
description: finding.description,
|
||||
impact: finding.impact,
|
||||
affectedUrls: finding.affectedUrls ? finding.affectedUrls : [],
|
||||
reproduction: finding.reproduction,
|
||||
mitigation: finding.mitigation,
|
||||
/* Remove Table Entry Object Properties */
|
||||
childEntries: undefined,
|
||||
kind: undefined,
|
||||
findings: undefined,
|
||||
expanded: undefined,
|
||||
} as unknown as Finding;
|
||||
return transformedFinding;
|
||||
}
|
||||
|
||||
export interface FindingDialogBody {
|
||||
title: string;
|
||||
severity: Severity;
|
||||
|
|
|
@ -133,7 +133,8 @@ export class PentestService {
|
|||
* @param pentestId the id of the pentest
|
||||
* @param finding the information of the finding
|
||||
*/
|
||||
public saveFinding(pentestId: string, finding: FindingDialogBody): Observable<Finding> {
|
||||
public saveFinding(pentestId: string, finding: Finding): Observable<Finding> {
|
||||
console.warn('Finding: ', finding);
|
||||
return this.http.post<Finding>(`${this.apiBaseURL}/${pentestId}/finding`, finding);
|
||||
}
|
||||
|
||||
|
|
|
@ -258,6 +258,55 @@
|
|||
{
|
||||
"name": "pentests",
|
||||
"item": [
|
||||
{
|
||||
"name": "Finding",
|
||||
"item": [
|
||||
{
|
||||
"name": "saveFinding",
|
||||
"request": {
|
||||
"auth": {
|
||||
"type": "bearer",
|
||||
"bearer": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICItdG1lbEV0ZHhGTnRSMW9aNXlRdE5jaFFpX0RVN2VNeV9YcU44aXY0S3hzIn0.eyJleHAiOjE2Njg0MjU2MjgsImlhdCI6MTY2ODQyNTMyOCwianRpIjoiODQyMjE5ODgtMDhkNC00YTg1LWEwNTYtZjI0N2QxZThkNDg2IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4ODg4L2F1dGgvcmVhbG1zL2M0cG9fcmVhbG1fbG9jYWwiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiMTBlMDZkN2EtOGRkMC00ZWNkLTg5NjMtMDU2YjQ1MDc5YzRmIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYzRwb19sb2NhbCIsInNlc3Npb25fc3RhdGUiOiJjYmMxMTJiNy03MGRlLTRhNjctYWRmYS1lNTA0NGE1ZDNjZDQiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImM0cG9fdXNlciIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJjNHBvX2xvY2FsIjp7InJvbGVzIjpbInVzZXIiXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6InRlc3QgdXNlciIsInByZWZlcnJlZF91c2VybmFtZSI6InR0dCIsImdpdmVuX25hbWUiOiJ0ZXN0IiwiZmFtaWx5X25hbWUiOiJ1c2VyIn0.glSjoxDFWzA4ApXGLMMaurfzfm0z9QU2mo1ZmPsH24pNjdp4A5CgxOIGkU6SKeHaPfeHvdaxevAWrkFdNGTJn_XLmAcqitNIEsrbIv76LKkNN2KNSltm1cfPM1fJPOXy91egX0SB3WoHzylw7zZZTsDncAcJEa1OCf6UUpKmKxmaqQLLTS4CMN82PNxeZFNgripoH5WqlutPdYCBK8WCgNoDh1njCIwevY12yi0gzAFtAH0I5Eqa5QwWpMWzB_Zs4WlqzSiuJVI7aqTRfrmZHe_qjR9riLMvgVoobLB0stbRH5VnHom-MNuUIw6SKVA0I9DPQb4jpF7Q4vqz8UBOMQ",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"key": "undefined",
|
||||
"type": "any"
|
||||
}
|
||||
]
|
||||
},
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"title\": \"Test Title\",\n \"severity\": \"LOW\",\n \"description\": \"Test Description\",\n \"impact\": \"Test Impact\",\n \"affectedUrls\": [\n \"https://akveo.github.io/nebular/docs/components/progress-bar/examples#nbprogressbarcomponent\"\n ],\n \"reproduction\": \"Step 1: Test\",\n \"mitigation\": \"Test Mitigatin\"\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"raw": "http://localhost:8443/pentests/11601f51-bc17-47fd-847d-0c53df5405b5/finding",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "8443",
|
||||
"path": [
|
||||
"pentests",
|
||||
"11601f51-bc17-47fd-847d-0c53df5405b5",
|
||||
"finding"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getPentestsByProjectIdAndCategory",
|
||||
"request": {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package comment
|
||||
package com.securityc4po.api.comment
|
||||
|
||||
import org.springframework.data.mongodb.core.index.Indexed
|
||||
import java.util.*
|
|
@ -1,4 +1,4 @@
|
|||
package comment
|
||||
package com.securityc4po.api.comment
|
||||
|
||||
import com.securityc4po.api.BaseEntity
|
||||
import org.springframework.data.mongodb.core.mapping.Document
|
|
@ -17,6 +17,7 @@ enum class Errorcode(val code: Int) {
|
|||
InvalidToken(3003),
|
||||
TokenWithoutField(3004),
|
||||
UserIdIsEmpty(3005),
|
||||
FindingInvalid(3006),
|
||||
|
||||
// 4XXX Unauthorized
|
||||
ProjectAdjustmentNotAuthorized(4000),
|
||||
|
@ -35,4 +36,5 @@ enum class Errorcode(val code: Int) {
|
|||
ProjectInsertionFailed(6006),
|
||||
PentestInsertionFailed(6007),
|
||||
ProjectPentestInsertionFailed(6008),
|
||||
FindingInsertionFailed(6009),
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.securityc4po.api.finding
|
||||
|
||||
import com.securityc4po.api.ResponseBody
|
||||
import org.springframework.data.mongodb.core.index.Indexed
|
||||
import java.util.*
|
||||
|
||||
data class Finding (
|
||||
@Indexed(background = true, unique = true)
|
||||
val id: String = UUID.randomUUID().toString(),
|
||||
val severity: Severity,
|
||||
val title: String,
|
||||
val description: String,
|
||||
val impact: String,
|
||||
val affectedUrls: List<String>? = emptyList(),
|
||||
val reproduction: String?,
|
||||
val mitigation: String?
|
||||
)
|
||||
|
||||
data class FindingRequestBody(
|
||||
val severity: String,
|
||||
val title: String,
|
||||
val description: String,
|
||||
val impact: String,
|
||||
val affectedUrls: List<String>? = emptyList(),
|
||||
val reproduction: String?,
|
||||
val mitigation: String?
|
||||
)
|
||||
|
||||
fun Finding.toFindingResponseBody(): ResponseBody {
|
||||
return mapOf(
|
||||
"id" to id,
|
||||
"title" to title,
|
||||
"description" to description,
|
||||
"impact" to impact,
|
||||
"affectedUrls" to affectedUrls,
|
||||
"reproduction" to reproduction,
|
||||
"mitigation" to mitigation
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates if a [FindingRequestBody] is valid
|
||||
*
|
||||
* @return Boolean describing if the body is valid
|
||||
*/
|
||||
fun FindingRequestBody.isValid(): Boolean {
|
||||
return when {
|
||||
this.title.isBlank() -> false
|
||||
this.description.isBlank() -> false
|
||||
this.impact.isBlank() -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
fun FindingRequestBody.toFinding(): Finding {
|
||||
return Finding(
|
||||
id = UUID.randomUUID().toString(),
|
||||
severity = Severity.valueOf(this.severity),
|
||||
title = this.title,
|
||||
description = this.description,
|
||||
impact = this.impact,
|
||||
affectedUrls = this.affectedUrls,
|
||||
reproduction = this.reproduction,
|
||||
mitigation = this.mitigation
|
||||
)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package finding
|
||||
package com.securityc4po.api.finding
|
||||
|
||||
import com.securityc4po.api.BaseEntity
|
||||
import org.springframework.data.mongodb.core.mapping.Document
|
||||
|
@ -9,7 +9,7 @@ open class FindingEntity(
|
|||
) : BaseEntity<Finding>(data)
|
||||
|
||||
fun FindingEntity.toFinding(): Finding {
|
||||
return finding.Finding(
|
||||
return Finding(
|
||||
this.data.id,
|
||||
this.data.severity,
|
||||
this.data.title,
|
|
@ -0,0 +1,13 @@
|
|||
package com.securityc4po.api.finding
|
||||
|
||||
import org.springframework.data.mongodb.repository.Query
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository
|
||||
import org.springframework.stereotype.Repository
|
||||
import reactor.core.publisher.Mono
|
||||
|
||||
@Repository
|
||||
interface FindingRepository : ReactiveMongoRepository<FindingEntity, String> {
|
||||
|
||||
@Query("{'data._id' : ?0}")
|
||||
fun findFindingById(id: String): Mono<FindingEntity>
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package com.securityc4po.api.finding
|
||||
|
||||
import com.securityc4po.api.configuration.BC_BAD_CAST_TO_ABSTRACT_COLLECTION
|
||||
import com.securityc4po.api.configuration.MESSAGE_BAD_CAST_TO_ABSTRACT_COLLECTION
|
||||
import com.securityc4po.api.configuration.error.handler.*
|
||||
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.pentest.PentestService
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
|
||||
import org.springframework.stereotype.Service
|
||||
import reactor.core.publisher.Mono
|
||||
|
||||
@Service
|
||||
@SuppressFBWarnings(BC_BAD_CAST_TO_ABSTRACT_COLLECTION, MESSAGE_BAD_CAST_TO_ABSTRACT_COLLECTION)
|
||||
class FindingService(private val findingRepository: FindingRepository, private val pentestService: PentestService) {
|
||||
|
||||
var logger = getLoggerFor<FindingService>()
|
||||
|
||||
/**
|
||||
* Save [Finding]
|
||||
*
|
||||
* @throws [InvalidModelException] if the [Finding] is invalid
|
||||
* @throws [TransactionInterruptedException] if the [Finding] could not be stored
|
||||
* @return saved [Finding]
|
||||
*/
|
||||
fun saveFinding(pentestId: String, body: FindingRequestBody): Mono<Finding> {
|
||||
validate(
|
||||
require = body.isValid(),
|
||||
logging = { logger.warn("Finding not valid.") },
|
||||
mappedException = InvalidModelException(
|
||||
"Finding not valid.", Errorcode.FindingInvalid
|
||||
)
|
||||
)
|
||||
val finding = body.toFinding()
|
||||
val findingEntity = FindingEntity(finding)
|
||||
return findingRepository.insert(findingEntity).flatMap { newFindingEntity: FindingEntity ->
|
||||
val finding = newFindingEntity.toFinding()
|
||||
// After successfully saving finding add id to pentest
|
||||
pentestService.updatePentestFinding(pentestId, finding.id).onErrorMap {
|
||||
TransactionInterruptedException(
|
||||
"Pentest could not be updated in Database.",
|
||||
Errorcode.PentestInsertionFailed
|
||||
)
|
||||
}.map {
|
||||
finding
|
||||
}
|
||||
}.doOnError {
|
||||
throw wrappedException(
|
||||
logging = { logger.warn("Finding could not be stored in Database. Thrown exception: ", it) },
|
||||
mappedException = TransactionInterruptedException(
|
||||
"Finding could not be stored.",
|
||||
Errorcode.FindingInsertionFailed
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package finding
|
||||
package com.securityc4po.api.finding
|
||||
|
||||
enum class Severity {
|
||||
LOW,
|
|
@ -11,7 +11,7 @@ data class Pentest(
|
|||
val category: PentestCategory,
|
||||
val refNumber: String,
|
||||
val status: PentestStatus,
|
||||
val findingIds: List<String> = emptyList(),
|
||||
var findingIds: List<String> = emptyList(),
|
||||
val commentIds: List<String> = emptyList()
|
||||
)
|
||||
|
||||
|
@ -27,6 +27,18 @@ fun buildPentest(body: PentestRequestBody, pentestEntity: PentestEntity): Pentes
|
|||
)
|
||||
}
|
||||
|
||||
/*fun addFindingtoPentest(findingId: String, pentestEntity: PentestEntity): Pentest {
|
||||
return Pentest(
|
||||
id = pentestEntity.data.id,
|
||||
projectId = pentestEntity.data.projectId,
|
||||
category = pentestEntity.data.category,
|
||||
refNumber = pentestEntity.data.refNumber,
|
||||
status = pentestEntity.data.status,
|
||||
findingIds = pentestEntity.data.findingIds,
|
||||
commentIds = pentestEntity.data.commentIds
|
||||
)
|
||||
}*/
|
||||
|
||||
fun Pentest.toPentestResponseBody(): ResponseBody {
|
||||
return mapOf(
|
||||
"id" to id,
|
||||
|
|
|
@ -4,6 +4,9 @@ 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.toFindingResponseBody
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.http.ResponseEntity.noContent
|
||||
import org.springframework.web.bind.annotation.*
|
||||
|
@ -17,9 +20,8 @@ import reactor.core.publisher.Mono
|
|||
allowedHeaders = ["*"],
|
||||
methods = [RequestMethod.GET, RequestMethod.DELETE, RequestMethod.POST, RequestMethod.PATCH]
|
||||
)
|
||||
|
||||
@SuppressFBWarnings(BC_BAD_CAST_TO_ABSTRACT_COLLECTION)
|
||||
class PentestController(private val pentestService: PentestService) {
|
||||
class PentestController(private val pentestService: PentestService, private val findingService: FindingService) {
|
||||
|
||||
var logger = getLoggerFor<PentestController>()
|
||||
|
||||
|
@ -69,4 +71,15 @@ class PentestController(private val pentestService: PentestService) {
|
|||
ResponseEntity.accepted().body(it.toPentestResponseBody())
|
||||
}
|
||||
}
|
||||
|
||||
// ToDo: Add Documentation & Tests
|
||||
@PostMapping("/{pentestId}/finding")
|
||||
fun saveFinidng(
|
||||
@PathVariable(value = "pentestId") pentestId: String,
|
||||
@RequestBody body: FindingRequestBody
|
||||
): Mono<ResponseEntity<ResponseBody>> {
|
||||
return this.findingService.saveFinding(pentestId, body).map {
|
||||
ResponseEntity.accepted().body(it.toFindingResponseBody())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,37 @@ class PentestService(private val pentestRepository: PentestRepository, private v
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update [Pentest] for Finding
|
||||
*
|
||||
* @throws [InvalidModelException] if the [Pentest] is invalid
|
||||
* @throws [TransactionInterruptedException] if the [Pentest] could not be updated
|
||||
* @return updated [Pentest]
|
||||
*/
|
||||
fun updatePentestFinding(pentestId: String, findingId: String): Mono<Pentest> {
|
||||
return pentestRepository.findPentestById(pentestId).switchIfEmpty {
|
||||
logger.warn("Pentest with id $pentestId not found. Updating not possible.")
|
||||
val msg = "Pentest with id $pentestId not found."
|
||||
val ex = EntityNotFoundException(msg, Errorcode.PentestNotFound)
|
||||
throw ex
|
||||
}.flatMap { currentPentestEntity: PentestEntity ->
|
||||
if (currentPentestEntity.data.findingIds.find { pentestData -> pentestData == findingId } == null) {
|
||||
currentPentestEntity.data.findingIds += findingId
|
||||
}
|
||||
currentPentestEntity.lastModified = Instant.now()
|
||||
this.pentestRepository.save(currentPentestEntity).map {
|
||||
it.toPentest()
|
||||
}.doOnError {
|
||||
throw wrappedException(
|
||||
logging = { logger.warn("Pentest could not be updated in Database. Thrown exception: ", it) },
|
||||
mappedException = TransactionInterruptedException(
|
||||
"Pentest could not be updated.",
|
||||
Errorcode.PentestInsertionFailed
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,7 +17,6 @@ import reactor.kotlin.core.publisher.switchIfEmpty
|
|||
allowedHeaders = ["*"],
|
||||
methods = [RequestMethod.GET, RequestMethod.DELETE, RequestMethod.POST, RequestMethod.PATCH]
|
||||
)
|
||||
|
||||
@SuppressFBWarnings(BC_BAD_CAST_TO_ABSTRACT_COLLECTION)
|
||||
class ProjectController(private val projectService: ProjectService) {
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ class ProjectService(private val projectRepository: ProjectRepository) {
|
|||
throw ex
|
||||
}.flatMap {projectEntity: ProjectEntity ->
|
||||
val currentProjectPentestStatus = projectEntity.data.projectPentests.find { projectPentestData -> projectPentestData.pentestId == projectPentest.pentestId }
|
||||
if (currentProjectPentestStatus !== null) {
|
||||
if (currentProjectPentestStatus != null) {
|
||||
projectEntity.data.projectPentests.find { data -> data.pentestId == projectPentest.pentestId }!!.status = projectPentest.status
|
||||
} else {
|
||||
projectEntity.data.projectPentests += projectPentest
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
package finding
|
||||
|
||||
import org.springframework.data.mongodb.core.index.Indexed
|
||||
import java.util.*
|
||||
|
||||
data class Finding (
|
||||
@Indexed(background = true, unique = true)
|
||||
val id: String = UUID.randomUUID().toString(),
|
||||
val severity: Severity,
|
||||
val title: String,
|
||||
val description: String,
|
||||
val impact: String,
|
||||
val affectedUrls: List<String>? = emptyList(),
|
||||
val reproduction: String,
|
||||
val mitigation: String
|
||||
)
|
|
@ -0,0 +1,23 @@
|
|||
[{
|
||||
"_id": {
|
||||
"$oid": "6372223efea5724fd22bae8a"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668424254533"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "ef31449d-71ec-4736-952f-8b20e53117d5",
|
||||
"severity": "LOW",
|
||||
"title": "Test Title",
|
||||
"description": "Test Description",
|
||||
"impact": "Test Impact",
|
||||
"affectedUrls": [
|
||||
"https://akveo.github.io/nebular/docs/components/progress-bar/examples#nbprogressbarcomponent"
|
||||
],
|
||||
"reproduction": "Step 1: Test",
|
||||
"mitigation": "Test Mitigatin"
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
}]
|
File diff suppressed because it is too large
Load Diff
|
@ -4,7 +4,7 @@
|
|||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668176064717"
|
||||
"$numberLong": "1668425376081"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
|
@ -17,6 +17,294 @@
|
|||
{
|
||||
"pentestId": "11601f51-bc17-47fd-847d-0c53df5405b5",
|
||||
"status": "IN_PROGRESS"
|
||||
},
|
||||
{
|
||||
"pentestId": "9a073a08-e4fc-4450-8202-c902455b66ec",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "981c5e24-7276-47f8-a821-ff5976292ad4",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "2d46a183-8f11-4fbc-bbf1-e439f7282bb9",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "eb4f80f3-caac-4fef-a5dd-53616701f171",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "0ab8de31-9d5e-4b6b-a43c-12207c160863",
|
||||
"status": "IN_PROGRESS"
|
||||
},
|
||||
{
|
||||
"pentestId": "3ed9e894-58e8-46b9-9859-cde675fec17c",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "53fdab75-ea52-4cea-85ed-df8b67f41b72",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "6270d4bc-5f39-4358-ad0a-fd5791191f28",
|
||||
"status": "IN_PROGRESS"
|
||||
},
|
||||
{
|
||||
"pentestId": "1a90f468-470a-4b1e-9783-cc761b1770ee",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "6eb37869-baef-4a5b-9ac0-bf202a49874f",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "da89c933-1413-4186-ad2c-f1967cb8dbb4",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "b3682591-f6c3-4969-bf15-69f4d495ef18",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "9e8e2736-afc9-4f63-b29f-567f9f316c83",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "3405bdd6-1ae2-4876-9c18-443a791cec9c",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "2fd387b3-b7a5-4297-9790-5d7845214c05",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "a61116c5-1859-4df3-8252-7788c31472d8",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "47d8b39d-9fa7-4772-8605-84aa0531f49e",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "bd2b8899-0cd9-41fd-a975-257aac48b81f",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "b9bde632-c275-4566-b693-c57a3dad47f3",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "32cc5c4e-7234-42b7-8031-c2e231bc0404",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "07e34e95-7dda-499a-8be8-0e8378f0e0d0",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "b70f6720-ee17-49d6-8838-bd776cd18d0a",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "9fb260ea-333f-44c6-884b-e46352564e2a",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "87f492f7-991b-4e04-9531-5dba0bc34b1b",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "6d846445-d470-447a-96b3-8f4b57df3221",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "123c43ae-6870-4883-a1c5-2f99946e2c2d",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "8be5b377-3eb0-4b54-81d2-8cfd5ea1f0f1",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "6b1d2b71-9e31-4e78-a82e-5325c699658c",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "77e765ef-40fb-4b6e-9d80-1e06cae7d4a3",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "5821cd2c-aa17-4339-b697-1b4089d3bf93",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "bb57b94f-c8bc-4dd9-b4bf-e14d0a97cc31",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "a5e3aaba-268e-4a40-92f9-05c0dae4cc0f",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "18ed1ddb-524a-4333-af90-7716bd51dc7b",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "c2d19d1e-39e5-4862-82c9-d88c5d91f630",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "728e294f-e27d-4bef-903b-d9eeb54cf086",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "91cd7aee-acda-4c95-ba35-16932448f29f",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "e496d9ba-7775-479e-8904-864c04fec3f9",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "ee87e923-63d7-40bc-b41e-049fe087e1dd",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "cbe94eaf-c734-4d6f-96ec-7d84a4a5b5cc",
|
||||
"status": "IN_PROGRESS"
|
||||
},
|
||||
{
|
||||
"pentestId": "c9ecfc9f-23f1-4744-a578-54b0c96a9e87",
|
||||
"status": "IN_PROGRESS"
|
||||
},
|
||||
{
|
||||
"pentestId": "ca0c10a1-8fcc-4b0b-98c0-2403709d7e50",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "bce6f266-2c70-4e45-a1db-d767e4bcc1f8",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "be0b07a3-64e4-4122-a362-dd657b8b6b0a",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "8f2230fb-bd5c-4047-9db6-74bc49be9cc1",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "a1b00a90-cb14-475f-ba3a-5807a21df704",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "af2e7766-ecd1-4015-b4e1-c0b978643a0f",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "27b64044-b3ff-48bf-9220-837b420f3904",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "b5eb1683-700a-4522-8b53-45809e665643",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "86b4d382-e433-4bac-ab6e-530a0dce299d",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "7a118a29-f983-4219-834c-f01554231910",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "ac9bc697-a53f-4278-98b9-05d8ba19a50d",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "13cecebb-321a-4ef8-8116-f6814652f7d7",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "048287bc-c41b-49a1-aeb5-2cc98a5bad06",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "4d1b424e-05ea-468c-9902-3626a79ccfe6",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "377d73b8-f8da-461e-909b-524a38a37ed6",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "16e10ad9-f49d-4a74-9de7-10a49e2401e2",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "4c68c22e-6073-4ec8-aebb-45ad2a3cc848",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "276e5823-b517-445c-b182-e6eda6478d44",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "84c661c0-2775-440a-97c5-ff35f345cabb",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "fb6d909c-8d16-48e3-b0e5-aba9bf3e8eae",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "0b211e22-dd63-46cc-a12f-be7ac73d7a64",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "63310549-e2a8-4dd0-a91a-9cfa06e2dc41",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "ac8d52d0-f0c8-47ec-ab13-24f40dc4f9e6",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "3ddc4950-f662-4ec1-9a04-b9c3591d8b06",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "4c11d176-2ec5-4ed9-9c8a-c1edd33b262c",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "b9a6f4ba-62e6-442b-a274-b3ffe209d248",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "705e28a2-b0a4-4b8c-9922-10c5c67faf65",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "4c59259d-4a24-43ef-8738-fe214e0b0673",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "a7ab3344-db7d-495a-8e55-dd572ea7c5e0",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "195e7f58-a7b2-4571-9c66-1e91a0dfca28",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "543a9768-4e5c-4c70-9aae-977afa542afa",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "a17516de-e92a-43b9-a415-203dce48fb0e",
|
||||
"status": "OPEN"
|
||||
}
|
||||
],
|
||||
"createdBy": "3c4ae87f-0d56-4634-a824-b4883c403c8a"
|
||||
|
|
Loading…
Reference in New Issue