add FileSystemController API endpoint

This commit is contained in:
Gauthier Roebroeck 2019-10-04 16:42:01 +08:00
parent 2af4bdbcf1
commit ee57007aa8
2 changed files with 116 additions and 0 deletions

View file

@ -0,0 +1,67 @@
package org.gotson.komga.interfaces.web.rest
import com.fasterxml.jackson.annotation.JsonInclude
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.server.ResponseStatusException
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.Path
import kotlin.streams.toList
@RestController
@RequestMapping("api/v1/filesystem", produces = [MediaType.APPLICATION_JSON_VALUE])
class FileSystemController {
private val fs = FileSystems.getDefault()
@GetMapping
fun getDirectoryListing(
@RequestParam(name = "path", required = false) path: String?
): DirectoryListingDto =
if (path.isNullOrEmpty()) {
DirectoryListingDto(
directories = fs.rootDirectories.map { it.toDto() }
)
} else {
val p = fs.getPath(path)
if (!p.isAbsolute) throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Path must be absolute")
try {
DirectoryListingDto(
parent = (p.parent ?: "").toString(),
directories = Files.list(p).use { dirStream ->
dirStream
.filter { Files.isDirectory(it) }
.sorted()
.map { it.toDto() }
.toList()
}
)
} catch (e: Exception) {
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Path does not exist")
}
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
data class DirectoryListingDto(
val parent: String? = null,
val directories: List<PathDto>
)
data class PathDto(
val type: String,
val name: String,
val path: String
)
fun Path.toDto(): PathDto =
PathDto(
type = if (Files.isDirectory(this)) "directory" else "file",
name = (fileName ?: this).toString(),
path = toString()
)

View file

@ -0,0 +1,49 @@
package org.gotson.komga.interfaces.web.rest
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.security.test.context.support.WithAnonymousUser
import org.springframework.security.test.context.support.WithMockUser
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import java.nio.file.Files
@ExtendWith(SpringExtension::class)
@SpringBootTest
@AutoConfigureMockMvc(printOnlyOnFailure = false)
class FileSystemControllerTest(
@Autowired private val mockMvc: MockMvc
) {
private val route = "/api/v1/filesystem"
@Test
@WithAnonymousUser
fun `given anonymous user when getDirectoryListing then return unauthorized`() {
mockMvc.perform(MockMvcRequestBuilders.get(route))
.andExpect(MockMvcResultMatchers.status().isUnauthorized)
}
@Test
@WithMockUser(roles = ["USER"])
fun `given relative path param when getDirectoryListing then return bad request`() {
mockMvc.perform(MockMvcRequestBuilders.get(route)
.param("path", "."))
.andExpect(MockMvcResultMatchers.status().isBadRequest)
}
@Test
@WithMockUser(roles = ["USER"])
fun `given non-existent path param when getDirectoryListing then return bad request`() {
val parent = Files.createTempDirectory(null)
Files.delete(parent)
mockMvc.perform(MockMvcRequestBuilders.get(route)
.param("path", parent.toString()))
.andExpect(MockMvcResultMatchers.status().isBadRequest)
}
}