Compare commits
1 Commits
main
...
skz_c4po_8
Author | SHA1 | Date |
---|---|---|
|
d7d04ef3ef |
|
@ -10,6 +10,9 @@
|
||||||
"item": [
|
"item": [
|
||||||
{
|
{
|
||||||
"name": "getProjects",
|
"name": "getProjects",
|
||||||
|
"protocolProfileBehavior": {
|
||||||
|
"disableBodyPruning": true
|
||||||
|
},
|
||||||
"request": {
|
"request": {
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "oauth2",
|
"type": "oauth2",
|
||||||
|
@ -38,6 +41,43 @@
|
||||||
},
|
},
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"header": [],
|
"header": [],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://localhost:8443/projects",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"localhost"
|
||||||
|
],
|
||||||
|
"port": "8443",
|
||||||
|
"path": [
|
||||||
|
"projects"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "saveProject",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"client\": \"Novatec\",\n \"title\": \"log4j Pentest\",\n \"tester\": \"Stipe\",\n \"createyBy\": \"10e06d7a-8dd0-4ecd-8963-056b45079c4f\"\n}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"url": {
|
"url": {
|
||||||
"raw": "http://localhost:8443/projects",
|
"raw": "http://localhost:8443/projects",
|
||||||
"protocol": "http",
|
"protocol": "http",
|
||||||
|
|
|
@ -39,10 +39,28 @@ include::{snippets}/getProjects/http-response.adoc[]
|
||||||
|
|
||||||
include::{snippets}/getProjects/response-fields.adoc[]
|
include::{snippets}/getProjects/response-fields.adoc[]
|
||||||
|
|
||||||
|
=== Save project
|
||||||
|
|
||||||
|
To save a project, call the POST request /projects
|
||||||
|
|
||||||
|
==== Request example
|
||||||
|
|
||||||
|
include::{snippets}/saveProject/http-request.adoc[]
|
||||||
|
|
||||||
|
==== Response example
|
||||||
|
|
||||||
|
include::{snippets}/saveProject/http-response.adoc[]
|
||||||
|
|
||||||
|
==== Response structure
|
||||||
|
|
||||||
|
include::{snippets}/saveProject/response-fields.adoc[]
|
||||||
|
|
||||||
== Change History
|
== Change History
|
||||||
|
|
||||||
|===
|
|===
|
||||||
|Date |Change
|
|Date |Change
|
||||||
|
|2021-12-22
|
||||||
|
|Added POST endpoint to save Projects
|
||||||
|2021-02-14
|
|2021-02-14
|
||||||
|Added GET endpoint to receive Projects
|
|Added GET endpoint to receive Projects
|
||||||
|2021-02-12
|
|2021-02-12
|
||||||
|
|
|
@ -37,3 +37,21 @@ fun ProjectOverview.toProjectOverviewResponseBody(): ResponseBody {
|
||||||
"projects" to projects
|
"projects" to projects
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class ProjectRequestBody(
|
||||||
|
val client: String,
|
||||||
|
val title: String,
|
||||||
|
val tester: String? = null,
|
||||||
|
val createdBy: String
|
||||||
|
)
|
||||||
|
|
||||||
|
fun ProjectRequestBody.toProject(): Project {
|
||||||
|
return Project(
|
||||||
|
id = UUID.randomUUID().toString(),
|
||||||
|
client = this.client,
|
||||||
|
title = this.title,
|
||||||
|
createdAt = Instant.now().toString(),
|
||||||
|
tester = this.tester,
|
||||||
|
createdBy = this.createdBy
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import reactor.core.publisher.Mono
|
||||||
origins = [],
|
origins = [],
|
||||||
allowCredentials = "false",
|
allowCredentials = "false",
|
||||||
allowedHeaders = ["*"],
|
allowedHeaders = ["*"],
|
||||||
methods = [RequestMethod.GET]
|
methods = [RequestMethod.GET, RequestMethod.POST]
|
||||||
)
|
)
|
||||||
@SuppressFBWarnings(BC_BAD_CAST_TO_ABSTRACT_COLLECTION)
|
@SuppressFBWarnings(BC_BAD_CAST_TO_ABSTRACT_COLLECTION)
|
||||||
class ProjectController(private val projectService: ProjectService) {
|
class ProjectController(private val projectService: ProjectService) {
|
||||||
|
@ -23,12 +23,21 @@ class ProjectController(private val projectService: ProjectService) {
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
fun getProjects(): Mono<ResponseEntity<List<ResponseBody>>> {
|
fun getProjects(): Mono<ResponseEntity<List<ResponseBody>>> {
|
||||||
return projectService.getProjects().map {
|
return projectService.getProjects().map { projectList ->
|
||||||
it.map {
|
projectList.map {
|
||||||
it.toProjectResponseBody()
|
it.toProjectResponseBody()
|
||||||
}
|
}
|
||||||
}.map {
|
}.map {
|
||||||
ResponseEntity.ok(it)
|
ResponseEntity.ok(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
fun saveProject(
|
||||||
|
@RequestBody body: ProjectRequestBody
|
||||||
|
): Mono<ResponseEntity<ResponseBody>> {
|
||||||
|
return this.projectService.saveProject(body).map {
|
||||||
|
ResponseEntity.accepted().body(it.toProjectResponseBody())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,4 +23,14 @@ class ProjectService(private val projectRepository: ProjectRepository) {
|
||||||
it.map { projectEntity -> projectEntity.toProject() }
|
it.map { projectEntity -> projectEntity.toProject() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun saveProject(body: ProjectRequestBody): Mono<Project> {
|
||||||
|
val project = body.toProject()
|
||||||
|
val projectEntity = ProjectEntity(project)
|
||||||
|
return projectRepository.insert(projectEntity).map {
|
||||||
|
it.toProject()
|
||||||
|
}.doOnError {
|
||||||
|
logger.warn("Project could not be stored in Database. Thrown exception: ", it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.springframework.restdocs.operation.preprocess.Preprocessors
|
||||||
import org.springframework.restdocs.payload.JsonFieldType
|
import org.springframework.restdocs.payload.JsonFieldType
|
||||||
import org.springframework.restdocs.payload.PayloadDocumentation
|
import org.springframework.restdocs.payload.PayloadDocumentation
|
||||||
import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation
|
import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation
|
||||||
|
import reactor.core.publisher.Mono
|
||||||
|
|
||||||
@SuppressFBWarnings(
|
@SuppressFBWarnings(
|
||||||
SIC_INNER_SHOULD_BE_STATIC,
|
SIC_INNER_SHOULD_BE_STATIC,
|
||||||
|
@ -90,6 +91,43 @@ class ProjectControllerDocumentationTest : BaseDocumentationIntTest() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
inner class SaveProject {
|
||||||
|
@Test
|
||||||
|
fun saveProject() {
|
||||||
|
webTestClient.post().uri("/projects")
|
||||||
|
.header("Authorization", "Bearer $tokenAdmin")
|
||||||
|
.body(Mono.just(project), ProjectRequestBody::class.java)
|
||||||
|
.exchange()
|
||||||
|
.expectStatus().isAccepted
|
||||||
|
.expectHeader().valueEquals("Application-Name", "SecurityC4PO")
|
||||||
|
.expectBody().json(Json.write(project))
|
||||||
|
.consumeWith(WebTestClientRestDocumentation.document("{methodName}",
|
||||||
|
Preprocessors.preprocessRequest(Preprocessors.prettyPrint(),
|
||||||
|
Preprocessors.modifyUris().removePort(),
|
||||||
|
Preprocessors.removeHeaders("Host", "Content-Length")),
|
||||||
|
Preprocessors.preprocessResponse(
|
||||||
|
Preprocessors.prettyPrint()
|
||||||
|
),
|
||||||
|
PayloadDocumentation.relaxedResponseFields(
|
||||||
|
PayloadDocumentation.fieldWithPath("id").type(JsonFieldType.STRING).description("The id of the requested project"),
|
||||||
|
PayloadDocumentation.fieldWithPath("client").type(JsonFieldType.STRING).description("The name of the client of the requested project"),
|
||||||
|
PayloadDocumentation.fieldWithPath("title").type(JsonFieldType.STRING).description("The title of the requested project"),
|
||||||
|
PayloadDocumentation.fieldWithPath("createdAt").type(JsonFieldType.STRING).description("The date where the project was created at"),
|
||||||
|
PayloadDocumentation.fieldWithPath("tester").type(JsonFieldType.STRING).description("The user that is assigned as a tester in the project"),
|
||||||
|
PayloadDocumentation.fieldWithPath("createdBy").type(JsonFieldType.STRING).description("The id of the user that created the project")
|
||||||
|
)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
val project = ProjectRequestBody(
|
||||||
|
client = "Novatec",
|
||||||
|
title = "log4j Pentest",
|
||||||
|
tester = "Stipe",
|
||||||
|
createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun persistBasicTestScenario() {
|
private fun persistBasicTestScenario() {
|
||||||
// setup test data
|
// setup test data
|
||||||
val projectOne = Project(
|
val projectOne = Project(
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.springframework.boot.web.server.LocalServerPort
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate
|
import org.springframework.data.mongodb.core.MongoTemplate
|
||||||
import org.springframework.data.mongodb.core.query.Query
|
import org.springframework.data.mongodb.core.query.Query
|
||||||
import org.springframework.test.web.reactive.server.WebTestClient
|
import org.springframework.test.web.reactive.server.WebTestClient
|
||||||
|
import reactor.core.publisher.Mono
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
|
||||||
@SuppressFBWarnings(
|
@SuppressFBWarnings(
|
||||||
|
@ -87,6 +88,33 @@ class ProjectControllerIntTest : BaseIntTest() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
inner class SaveProject {
|
||||||
|
@Test
|
||||||
|
fun `save project successfully`() {
|
||||||
|
webTestClient.post().uri("/projects")
|
||||||
|
.header("Authorization", "Bearer $tokenAdmin")
|
||||||
|
.body(Mono.just(project), ProjectRequestBody::class.java)
|
||||||
|
.exchange()
|
||||||
|
.expectStatus().isAccepted
|
||||||
|
.expectHeader().valueEquals("Application-Name", "SecurityC4PO")
|
||||||
|
.expectBody().json(Json.write(project))
|
||||||
|
.jsonPath("$.client").isEqualTo("Novatec")
|
||||||
|
.jsonPath("$.title").isEqualTo("log4j Pentest")
|
||||||
|
.jsonPath("$.tester").isEqualTo("Stipe")
|
||||||
|
.jsonPath("$.createdBy").isEqualTo("f8aab31f-4925-4242-a6fa-f98135b4b032")
|
||||||
|
}
|
||||||
|
|
||||||
|
val project = Project(
|
||||||
|
id = "4f6567a8-76fd-487b-8602-f82d0ca4d1f9",
|
||||||
|
client = "Novatec",
|
||||||
|
title = "log4j Pentest",
|
||||||
|
createdAt = "2021-04-10T18:05:00Z",
|
||||||
|
tester = "Stipe",
|
||||||
|
createdBy = "f8aab31f-4925-4242-a6fa-f98135b4b032"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun persistBasicTestScenario() {
|
private fun persistBasicTestScenario() {
|
||||||
// setup test data
|
// setup test data
|
||||||
val projectOne = Project(
|
val projectOne = Project(
|
||||||
|
|
|
@ -22,7 +22,6 @@ class ProjectServiceTest {
|
||||||
inner class GetProjects {
|
inner class GetProjects {
|
||||||
@Test
|
@Test
|
||||||
fun `happy path - getProjects successfully`() {
|
fun `happy path - getProjects successfully`() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue