Skip to content

Commit

Permalink
fix(add library): special characters handling
Browse files Browse the repository at this point in the history
some directories with special characters could not be explored and selected
  • Loading branch information
gotson committed Mar 18, 2020
1 parent ca03111 commit 15afa93
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 49 deletions.
12 changes: 4 additions & 8 deletions komga-webui/src/services/komga-filesystem.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,17 @@ import { AxiosInstance } from 'axios'
const API_FILESYSTEM = '/api/v1/filesystem'

export default class KomgaFilesystemService {
private http: AxiosInstance;
private http: AxiosInstance

constructor (http: AxiosInstance) {
this.http = http
}

async getDirectoryListing (path: String = ''): Promise<DirectoryListingDto> {
try {
return (await this.http.get(API_FILESYSTEM,
{
params: {
path: path
}
}
)).data
return (await this.http.post(API_FILESYSTEM, {
path: path
})).data
} catch (e) {
let msg = 'An error occurred while trying to retrieve directory listing'
if (e.response.data.message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import com.fasterxml.jackson.annotation.JsonInclude
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
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
Expand All @@ -21,50 +21,54 @@ class FileSystemController {

private val fs = FileSystems.getDefault()

@GetMapping
@PostMapping
fun getDirectoryListing(
@RequestParam(name = "path", required = false) path: String?
@RequestBody(required = false) request: DirectoryRequestDto = DirectoryRequestDto()
): DirectoryListingDto =
if (path.isNullOrEmpty()) {
if (request.path.isEmpty()) {
DirectoryListingDto(
directories = fs.rootDirectories.map { it.toDto() }
)
} else {
val p = fs.getPath(request.path)
if (!p.isAbsolute) throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Path must be absolute")
try {
DirectoryListingDto(
directories = fs.rootDirectories.map { it.toDto() }
parent = (p.parent ?: "").toString(),
directories = Files.list(p).use { dirStream ->
dirStream.asSequence()
.filter { Files.isDirectory(it) }
.filter { !Files.isHidden(it) }
.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.toString() })
.map { it.toDto() }
.toList()
}
)
} 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.asSequence()
.filter { Files.isDirectory(it) }
.filter { !Files.isHidden(it) }
.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.toString() })
.map { it.toDto() }
.toList()
}
)
} catch (e: Exception) {
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Path does not exist")
}
} catch (e: Exception) {
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Path does not exist")
}
}
}

data class DirectoryRequestDto(
val path: String = ""
)

@JsonInclude(JsonInclude.Include.NON_NULL)
data class DirectoryListingDto(
val parent: String? = null,
val directories: List<PathDto>
val parent: String? = null,
val directories: List<PathDto>
)

data class PathDto(
val type: String,
val name: String,
val path: String
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()
)
PathDto(
type = if (Files.isDirectory(this)) "directory" else "file",
name = (fileName ?: this).toString(),
path = toString()
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ 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.http.MediaType
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.get
import org.springframework.test.web.servlet.post
import java.nio.file.Files

@ExtendWith(SpringExtension::class)
Expand All @@ -23,22 +24,23 @@ class FileSystemControllerTest(
@Test
@WithAnonymousUser
fun `given anonymous user when getDirectoryListing then return unauthorized`() {
mockMvc.get(route)
mockMvc.post(route)
.andExpect { status { isUnauthorized } }
}

@Test
@WithMockUser
fun `given regular user when getDirectoryListing then return forbidden`() {
mockMvc.get(route)
mockMvc.post(route)
.andExpect { status { isForbidden } }
}

@Test
@WithMockUser(roles = ["USER", "ADMIN"])
fun `given relative path param when getDirectoryListing then return bad request`() {
mockMvc.get(route) {
param("path", ".")
mockMvc.post(route) {
contentType = MediaType.APPLICATION_JSON
content = "."
}.andExpect { status { isBadRequest } }
}

Expand All @@ -48,8 +50,9 @@ class FileSystemControllerTest(
val parent = Files.createTempDirectory(null)
Files.delete(parent)

mockMvc.get(route) {
param("path", parent.toString())
mockMvc.post(route) {
contentType = MediaType.APPLICATION_JSON
content = parent.toString()
}.andExpect { status { isBadRequest } }
}
}

0 comments on commit 15afa93

Please sign in to comment.