112 lines
3.2 KiB
Kotlin
112 lines
3.2 KiB
Kotlin
package com.securityc4po.api.project
|
|
|
|
import com.fasterxml.jackson.annotation.JsonFormat
|
|
import com.securityc4po.api.ResponseBody
|
|
import com.securityc4po.api.pentest.PentestStatus
|
|
import org.springframework.data.mongodb.core.index.Indexed
|
|
import java.math.RoundingMode
|
|
import java.text.DecimalFormat
|
|
import java.time.Instant
|
|
import java.util.UUID
|
|
|
|
data class Project(
|
|
@Indexed(background = true, unique = true)
|
|
val id: String = UUID.randomUUID().toString(),
|
|
val client: String,
|
|
val title: String,
|
|
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssZ")
|
|
val createdAt: String = Instant.now().toString(),
|
|
val tester: String? = null,
|
|
val projectPentests: List<ProjectPentest> = emptyList(),
|
|
val createdBy: String
|
|
)
|
|
|
|
fun buildProject(body: ProjectRequestBody, projectEntity: ProjectEntity): Project{
|
|
return Project(
|
|
id = projectEntity.data.id,
|
|
client = body.client,
|
|
title = body.title,
|
|
createdAt = projectEntity.data.createdAt,
|
|
tester = body.tester,
|
|
projectPentests = projectEntity.data.projectPentests,
|
|
createdBy = projectEntity.data.createdBy
|
|
)
|
|
}
|
|
|
|
fun Project.toProjectResponseBody(): ResponseBody {
|
|
return mapOf(
|
|
"id" to id,
|
|
"client" to client,
|
|
"title" to title,
|
|
"createdAt" to createdAt,
|
|
"tester" to tester,
|
|
/* ToDo: Calculate percentage in BE type: float */
|
|
"testingProgress" to calculateProgress(),
|
|
"createdBy" to createdBy
|
|
)
|
|
}
|
|
|
|
fun Project.toProjectDeleteResponseBody(): ResponseBody {
|
|
return mapOf(
|
|
"id" to id
|
|
)
|
|
}
|
|
|
|
fun Project.calculateProgress(): Float {
|
|
// Total number of pentests listet in the OWASP testing guide
|
|
// https://owasp.org/www-project-web-security-testing-guide/assets/archive/OWASP_Testing_Guide_v4.pdf
|
|
val TOTALPENTESTS = 95
|
|
|
|
return if (projectPentests.isEmpty())
|
|
0F
|
|
else {
|
|
var completedPentests = 0
|
|
projectPentests.forEach { projectPentest ->
|
|
if (projectPentest.status == PentestStatus.TRIAGED) {
|
|
completedPentests++
|
|
}
|
|
}
|
|
val df = DecimalFormat("#.##")
|
|
df.roundingMode = RoundingMode.DOWN
|
|
val progress = completedPentests / TOTALPENTESTS
|
|
df.format(progress).toFloat()
|
|
}
|
|
}
|
|
|
|
data class ProjectOverview(
|
|
val projects: List<Project>
|
|
)
|
|
|
|
data class ProjectRequestBody(
|
|
val client: String,
|
|
val title: String,
|
|
val tester: String
|
|
)
|
|
|
|
/**
|
|
* Validates if a [ProjectRequestBody] is valid
|
|
*
|
|
* @return Boolean describing if the body is valid
|
|
*/
|
|
fun ProjectRequestBody.isValid(): Boolean {
|
|
return when {
|
|
this.client.isBlank() -> false
|
|
this.title.isBlank() -> false
|
|
this.tester.isBlank() -> false
|
|
else -> true
|
|
}
|
|
}
|
|
|
|
fun ProjectRequestBody.toProject(): Project {
|
|
return Project(
|
|
id = UUID.randomUUID().toString(),
|
|
client = this.client,
|
|
title = this.title,
|
|
createdAt = Instant.now().toString(),
|
|
tester = this.tester,
|
|
// ToDo: Should be changed to SUB from Token after adding AUTH Header
|
|
createdBy = UUID.randomUUID().toString()
|
|
|
|
)
|
|
}
|