security-c4po/security-c4po-api/src/main/kotlin/com/securityc4po/api/project/Project.kt

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()
)
}