add Library root sanitization for non-admin users

This commit is contained in:
Gauthier Roebroeck 2019-12-23 11:34:05 +08:00
parent 874b3c057e
commit 809181d760
2 changed files with 67 additions and 8 deletions

View file

@ -37,27 +37,33 @@ class LibraryController(
) {
@GetMapping
fun getAll(@AuthenticationPrincipal principal: KomgaPrincipal): List<LibraryDto> =
fun getAll(
@AuthenticationPrincipal principal: KomgaPrincipal
): List<LibraryDto> =
if (principal.user.sharedAllLibraries) {
libraryRepository.findAll(Sort.by("name"))
} else {
principal.user.sharedLibraries
}.map { it.toDto() }
}.map { it.toDto(includeRoot = principal.user.isAdmin()) }
@GetMapping("{id}")
fun getOne(@AuthenticationPrincipal principal: KomgaPrincipal, @PathVariable id: Long): LibraryDto =
fun getOne(
@AuthenticationPrincipal principal: KomgaPrincipal,
@PathVariable id: Long
): LibraryDto =
libraryRepository.findByIdOrNull(id)?.let {
if (!principal.user.canAccessLibrary(it)) throw ResponseStatusException(HttpStatus.UNAUTHORIZED)
it.toDto()
it.toDto(includeRoot = principal.user.isAdmin())
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@PostMapping
@PreAuthorize("hasRole('ADMIN')")
fun addOne(
@AuthenticationPrincipal principal: KomgaPrincipal,
@Valid @RequestBody library: LibraryCreationDto
): LibraryDto =
try {
libraryLifecycle.addLibrary(Library(library.name, library.root)).toDto()
libraryLifecycle.addLibrary(Library(library.name, library.root)).toDto(includeRoot = principal.user.isAdmin())
} catch (e: Exception) {
when (e) {
is FileNotFoundException,
@ -90,8 +96,8 @@ data class LibraryDto(
val root: String
)
fun Library.toDto() = LibraryDto(
fun Library.toDto(includeRoot: Boolean) = LibraryDto(
id = id,
name = name,
root = root.toString()
root = if (includeRoot) root.toURI().path else ""
)

View file

@ -1,6 +1,11 @@
package org.gotson.komga.interfaces.web.rest
import org.gotson.komga.domain.model.UserRoles
import org.gotson.komga.domain.model.makeLibrary
import org.gotson.komga.domain.persistence.LibraryRepository
import org.gotson.komga.interfaces.web.WithMockCustomUser
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
@ -19,10 +24,23 @@ import org.springframework.test.web.servlet.post
@SpringBootTest
@AutoConfigureMockMvc(printOnlyOnFailure = false)
class LibraryControllerTest(
@Autowired private val mockMvc: MockMvc
@Autowired private val mockMvc: MockMvc,
@Autowired private val libraryRepository: LibraryRepository
) {
private val route = "/api/v1/libraries"
private val library = makeLibrary(url = "file:/library1")
@BeforeAll
fun `setup library`() {
libraryRepository.save(library)
}
@AfterAll
fun `teardown library`() {
libraryRepository.deleteAll()
}
@Nested
inner class AnonymousUser {
@Test
@ -78,4 +96,39 @@ class LibraryControllerTest(
}
}
}
@Nested
inner class DtoRootSanitization {
@Test
@WithMockCustomUser
fun `given regular user when getting libraries then root is hidden`() {
mockMvc.get(route)
.andExpect {
status { isOk }
jsonPath("$[0].root") { value("") }
}
mockMvc.get("${route}/${library.id}")
.andExpect {
status { isOk }
jsonPath("$.root") { value("") }
}
}
@Test
@WithMockCustomUser(roles = [UserRoles.ADMIN])
fun `given admin user when getting books then root is available`() {
mockMvc.get(route)
.andExpect {
status { isOk }
jsonPath("$[0].root") { value("/library1") }
}
mockMvc.get("${route}/${library.id}")
.andExpect {
status { isOk }
jsonPath("$.root") { value("/library1") }
}
}
}
}