Skip to content

Commit

Permalink
feat: unpublish-endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
NilsOveTen committed Nov 30, 2023
1 parent d284cef commit 2b77414
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ class PublicServiceController(private val publicServiceService: PublicServiceSer
} else {
ResponseEntity(HttpStatus.FORBIDDEN)
}

@PostMapping(value = ["/{id}/unpublish"], produces = [MediaType.APPLICATION_JSON_VALUE])
fun unpublishPublicService(
@AuthenticationPrincipal jwt: Jwt,
@PathVariable catalogId: String,
@PathVariable id: String,
): ResponseEntity<PublicService> =
if (endpointPermissions.hasOrgWritePermission(jwt, catalogId)) {
ResponseEntity(publicServiceService.unpublishPublicService(id, catalogId), HttpStatus.OK)
} else {
ResponseEntity(HttpStatus.FORBIDDEN)
}
}

private fun locationHeaderForCreated(newId: String, catalogId: String): HttpHeaders =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ class ServiceController(private val serviceService: ServiceService, private val
} else {
ResponseEntity(HttpStatus.FORBIDDEN)
}

@PostMapping(value = ["/{id}/unpublish"], produces = [MediaType.APPLICATION_JSON_VALUE])
fun unpublishService(
@AuthenticationPrincipal jwt: Jwt,
@PathVariable catalogId: String,
@PathVariable id: String,
): ResponseEntity<Service> =
if (endpointPermissions.hasOrgWritePermission(jwt, catalogId)) {
ResponseEntity(serviceService.unpublishService(id, catalogId), HttpStatus.OK)
} else {
ResponseEntity(HttpStatus.FORBIDDEN)
}
}

private fun locationHeaderForCreated(newId: String, catalogId: String): HttpHeaders =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ class PublicServiceService(private val publicServiceRepository: PublicServiceRep
throw ex
}

fun unpublishPublicService(id: String, catalogId: String): PublicService? =
try {
findPublicServiceById(id, catalogId)
?. also { if (!it.published) throw CustomBadRequestException() }
?.let { publicServiceRepository.save(it.copy(published = false)) }
?: throw CustomNotFoundException()
} catch (ex: Exception) {
logger.error("Failed to unpublish public service with id $id in catalog $catalogId", ex)
throw ex
}

fun publishedServicesInCatalog(catalogId: String): List<PublicService> =
publicServiceRepository.getByCatalogIdAndPublished(catalogId, true)

Expand Down
11 changes: 11 additions & 0 deletions src/main/kotlin/no/digdir/servicecatalog/service/ServiceService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ class ServiceService(private val serviceRepository: ServiceRepository) {
throw ex
}

fun unpublishService(id: String, catalogId: String): Service? =
try {
findServiceById(id, catalogId)
?. also { if (!it.published) throw CustomBadRequestException() }
?.let { serviceRepository.save(it.copy(published = false)) }
?: throw CustomNotFoundException()
} catch (ex: Exception) {
logger.error("Failed to unpublish service with id $id in catalog $catalogId", ex)
throw ex
}

fun publishedServicesInCatalog(catalogId: String): List<Service> =
serviceRepository.getByCatalogIdAndPublished(catalogId, true)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,6 @@ class PublicServices: ApiTestContext() {
}
}


@Nested
internal inner class PublishPublicService {
val pathService1 = "/internal/catalogs/910244132/public-services/1/publish"
Expand Down Expand Up @@ -502,4 +501,81 @@ class PublicServices: ApiTestContext() {
Assertions.assertEquals(HttpStatus.BAD_REQUEST.value(), response["status"])
}
}

@Nested
internal inner class UnpublishPublicService {
val path = "/internal/catalogs/910244132/public-services/0/unpublish"
@Test
fun `unauthorized when missing token` () {
val response = apiAuthorizedRequest(
path,
port,
null,
null,
HttpMethod.POST)

Assertions.assertEquals(HttpStatus.UNAUTHORIZED.value(), response["status"])
}

@Test
fun `forbidden when authenticated as read user` () {
val response = apiAuthorizedRequest(
path,
port,
null,
JwtToken(Access.ORG_READ).toString(),
HttpMethod.POST)

Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response["status"])
}

@Test
fun `not found when public service in different catalog`() {
val response = apiAuthorizedRequest(
"/internal/catalogs/123456789/public-services/0/unpublish",
port,
null,
JwtToken(Access.WRONG_ORG_WRITE).toString(),
HttpMethod.POST)
Assertions.assertEquals(HttpStatus.NOT_FOUND.value(), response["status"])
}

@Test
fun `not found when public service not in database`() {
val response = apiAuthorizedRequest(
"/internal/catalogs/910244132/public-services/1000/unpublish",
port,
null,
JwtToken(Access.ORG_WRITE).toString(),
HttpMethod.POST)
Assertions.assertEquals(HttpStatus.NOT_FOUND.value(), response["status"])
}

@Test
fun `able to unpublish public service when authenticated as a write user`() {
val response = apiAuthorizedRequest(
path,
port,
null,
JwtToken(Access.ORG_WRITE).toString(),
HttpMethod.POST)
Assertions.assertEquals(HttpStatus.OK.value(), response["status"])

val result: PublicService = mapper.readValue(response["body"] as String)
val expected = PUBLIC_SERVICE_0.copy(published = false)
Assertions.assertEquals(expected, result)
}

@Test
fun `bad request when unpublishing non-published public service`() {
val response = apiAuthorizedRequest(
"/internal/catalogs/910244132/public-services/1/unpublish",
port,
null,
JwtToken(Access.ORG_WRITE).toString(),
HttpMethod.POST)

Assertions.assertEquals(HttpStatus.BAD_REQUEST.value(), response["status"])
}
}
}
78 changes: 78 additions & 0 deletions src/test/kotlin/no/digdir/servicecatalog/integration/Services.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import no.digdir.servicecatalog.model.OpEnum
import no.digdir.servicecatalog.model.Service
import no.digdir.servicecatalog.utils.ApiTestContext
import no.digdir.servicecatalog.utils.SERVICES
import no.digdir.servicecatalog.utils.SERVICE_0
import no.digdir.servicecatalog.utils.SERVICE_1
import no.digdir.servicecatalog.utils.SERVICE_2
import no.digdir.servicecatalog.utils.SERVICE_TO_BE_CREATED
Expand Down Expand Up @@ -525,4 +526,81 @@ class Services: ApiTestContext() {
Assertions.assertEquals(HttpStatus.BAD_REQUEST.value(), response["status"])
}
}

@Nested
internal inner class UnpublishService {
val path = "/internal/catalogs/910244132/services/00/unpublish"
@Test
fun `unauthorized when missing token` () {
val response = apiAuthorizedRequest(
path,
port,
null,
null,
HttpMethod.POST)

Assertions.assertEquals(HttpStatus.UNAUTHORIZED.value(), response["status"])
}

@Test
fun `forbidden when authenticated as read user` () {
val response = apiAuthorizedRequest(
path,
port,
null,
JwtToken(Access.ORG_READ).toString(),
HttpMethod.POST)

Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response["status"])
}

@Test
fun `not found when service in different catalog`() {
val response = apiAuthorizedRequest(
"/internal/catalogs/123456789/services/00/unpublish",
port,
null,
JwtToken(Access.WRONG_ORG_WRITE).toString(),
HttpMethod.POST)
Assertions.assertEquals(HttpStatus.NOT_FOUND.value(), response["status"])
}

@Test
fun `not found when service not in database`() {
val response = apiAuthorizedRequest(
"/internal/catalogs/910244132/services/1000/unpublish",
port,
null,
JwtToken(Access.ORG_WRITE).toString(),
HttpMethod.POST)
Assertions.assertEquals(HttpStatus.NOT_FOUND.value(), response["status"])
}

@Test
fun `able to unpublish service when authenticated as a write user`() {
val response = apiAuthorizedRequest(
path,
port,
null,
JwtToken(Access.ORG_WRITE).toString(),
HttpMethod.POST)
Assertions.assertEquals(HttpStatus.OK.value(), response["status"])

val result: Service = mapper.readValue(response["body"] as String)
val expected = SERVICE_0.copy(published = false)
Assertions.assertEquals(expected, result)
}

@Test
fun `bad request when unpublishing non-published service`() {
val response = apiAuthorizedRequest(
"/internal/catalogs/910244132/services/01/unpublish",
port,
null,
JwtToken(Access.ORG_WRITE).toString(),
HttpMethod.POST)

Assertions.assertEquals(HttpStatus.BAD_REQUEST.value(), response["status"])
}
}
}

0 comments on commit 2b77414

Please sign in to comment.