-
-
Notifications
You must be signed in to change notification settings - Fork 267
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
154 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ enum class UserRoles { | |
FILE_DOWNLOAD, | ||
PAGE_STREAMING, | ||
KOBO_SYNC, | ||
KOREADER_SYNC, | ||
; | ||
|
||
companion object { | ||
|
31 changes: 31 additions & 0 deletions
31
...in/org/gotson/komga/infrastructure/security/apikey/HeaderApiKeyAuthenticationConverter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.gotson.komga.infrastructure.security.apikey | ||
|
||
import jakarta.servlet.http.HttpServletRequest | ||
import org.gotson.komga.infrastructure.security.TokenEncoder | ||
import org.springframework.security.authentication.AuthenticationDetailsSource | ||
import org.springframework.security.core.Authentication | ||
import org.springframework.security.web.authentication.AuthenticationConverter | ||
|
||
/** | ||
* A strategy that retrieves the API key from the [headerName], | ||
* and convert it to an [ApiKeyAuthenticationToken] | ||
* | ||
* @property headerName the header name from which to retrieve the API key | ||
* @property tokenEncoder the encoder to use to encode the API key in the [Authentication] object | ||
* @property authenticationDetailsSource the [AuthenticationDetailsSource] to enrich the [Authentication] details | ||
*/ | ||
class HeaderApiKeyAuthenticationConverter( | ||
private val headerName: String, | ||
private val tokenEncoder: TokenEncoder, | ||
private val authenticationDetailsSource: AuthenticationDetailsSource<HttpServletRequest, *>, | ||
) : AuthenticationConverter { | ||
override fun convert(request: HttpServletRequest): Authentication? = | ||
request | ||
.getHeader(headerName) | ||
?.let { | ||
val (maskedToken, hashedToken) = it.take(6) + "*".repeat(6) to tokenEncoder.encode(it) | ||
ApiKeyAuthenticationToken | ||
.unauthenticated(maskedToken, hashedToken) | ||
.apply { details = authenticationDetailsSource.buildDetails(request) } | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
komga/src/main/kotlin/org/gotson/komga/interfaces/api/kosync/KoreaderSyncController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package org.gotson.komga.interfaces.api.kosync | ||
|
||
import com.fasterxml.jackson.databind.JsonNode | ||
import io.github.oshai.kotlinlogging.KotlinLogging | ||
import org.gotson.komga.interfaces.api.kosync.dto.UserAuthenticationDto | ||
import org.springframework.http.HttpStatus | ||
import org.springframework.http.MediaType | ||
import org.springframework.web.bind.annotation.GetMapping | ||
import org.springframework.web.bind.annotation.PathVariable | ||
import org.springframework.web.bind.annotation.PostMapping | ||
import org.springframework.web.bind.annotation.PutMapping | ||
import org.springframework.web.bind.annotation.RequestBody | ||
import org.springframework.web.bind.annotation.RequestMapping | ||
import org.springframework.web.bind.annotation.RestController | ||
import org.springframework.web.server.ResponseStatusException | ||
|
||
private val logger = KotlinLogging.logger {} | ||
|
||
@RestController | ||
@RequestMapping("/kosync", produces = [MediaType.APPLICATION_JSON_VALUE]) | ||
class KoreaderSyncController { | ||
@PostMapping("users/create") | ||
fun registerUser(): Unit = throw ResponseStatusException(HttpStatus.FORBIDDEN) | ||
|
||
@GetMapping("users/auth") | ||
fun authorize() = UserAuthenticationDto() | ||
|
||
@GetMapping("syncs/progress/{bookHash}") | ||
fun getProgress( | ||
@PathVariable bookHash: String, | ||
) { | ||
logger.debug { "Received progress request for hash: $bookHash" } | ||
throw ResponseStatusException(HttpStatus.NOT_FOUND) | ||
} | ||
|
||
@PutMapping("syncs/progress") | ||
fun updateProgress( | ||
@RequestBody body: JsonNode, | ||
) { | ||
logger.debug { "Received progress update: $body" } | ||
throw ResponseStatusException(HttpStatus.NOT_FOUND) | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
komga/src/main/kotlin/org/gotson/komga/interfaces/api/kosync/dto/UserAuthenticationDto.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package org.gotson.komga.interfaces.api.kosync.dto | ||
|
||
data class UserAuthenticationDto( | ||
val authorized: String = "OK", | ||
) |
71 changes: 71 additions & 0 deletions
71
komga/src/test/kotlin/org/gotson/komga/interfaces/api/kosync/KoreaderSyncControllerTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package org.gotson.komga.interfaces.api.kosync | ||
|
||
import org.gotson.komga.domain.model.KomgaUser | ||
import org.gotson.komga.domain.model.UserRoles | ||
import org.gotson.komga.domain.persistence.KomgaUserRepository | ||
import org.gotson.komga.domain.service.KomgaUserLifecycle | ||
import org.junit.jupiter.api.AfterAll | ||
import org.junit.jupiter.api.BeforeAll | ||
import org.junit.jupiter.api.Test | ||
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.test.web.servlet.MockMvc | ||
import org.springframework.test.web.servlet.get | ||
import org.springframework.test.web.servlet.post | ||
|
||
@SpringBootTest | ||
@AutoConfigureMockMvc(printOnlyOnFailure = false) | ||
class KoreaderSyncControllerTest( | ||
@Autowired private val mockMvc: MockMvc, | ||
@Autowired private val userRepository: KomgaUserRepository, | ||
@Autowired private val komgaUserLifecycle: KomgaUserLifecycle, | ||
) { | ||
private val user1 = | ||
KomgaUser( | ||
"[email protected]", | ||
"", | ||
roles = setOf(UserRoles.KOREADER_SYNC), | ||
) | ||
private lateinit var apiKey: String | ||
|
||
@BeforeAll | ||
fun setup() { | ||
userRepository.insert(user1) | ||
apiKey = komgaUserLifecycle.createApiKey(user1, "test")!!.key | ||
} | ||
|
||
@AfterAll | ||
fun teardown() { | ||
komgaUserLifecycle.deleteUser(user1) | ||
} | ||
|
||
@Test | ||
fun `when creating user then forbidden is thrown`() { | ||
mockMvc | ||
.post("/kosync/users/create") | ||
.andExpect { | ||
status { isForbidden() } | ||
} | ||
} | ||
|
||
@Test | ||
fun `given missing X-Auth-User header when authenticating user then forbidden is thrown`() { | ||
mockMvc | ||
.get("/kosync/users/auth") | ||
.andExpect { | ||
status { isForbidden() } | ||
} | ||
} | ||
|
||
@Test | ||
fun `given api key in X-Auth-User header when authenticating user then returns OK`() { | ||
mockMvc | ||
.get("/kosync/users/auth") { | ||
header("x-auth-user", apiKey) | ||
}.andExpect { | ||
status { isOk() } | ||
jsonPath("authorized") { value("OK") } | ||
} | ||
} | ||
} |