feat: add claim profile

if claim profile is active, no initial user will be generated. Instead a /api/v1/claim endpoint will be provided to create an initial user

closes #104
This commit is contained in:
Gauthier Roebroeck 2020-03-03 18:51:34 +08:00
parent 60507e2305
commit b7eeb4c6cb
5 changed files with 61 additions and 11 deletions

View file

@ -87,7 +87,9 @@ class SecurityConfiguration(
"/js/**",
"/favicon.ico",
"/",
"/index.html")
"/index.html",
"/api/v1/claim"
)
}
@Bean

View file

@ -0,0 +1,42 @@
package org.gotson.komga.interfaces.rest
import org.gotson.komga.domain.model.UserRoles
import org.gotson.komga.infrastructure.security.KomgaPrincipal
import org.gotson.komga.infrastructure.security.KomgaUserDetailsLifecycle
import org.gotson.komga.interfaces.rest.dto.toDto
import org.springframework.context.annotation.Profile
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.security.core.userdetails.User
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestHeader
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.server.ResponseStatusException
import javax.validation.constraints.Email
import javax.validation.constraints.NotBlank
@Profile("claim")
@RestController
@RequestMapping("api/v1/claim", produces = [MediaType.APPLICATION_JSON_VALUE])
@Validated
class ClaimController(
private val userDetailsLifecycle: KomgaUserDetailsLifecycle
) {
@PostMapping
fun claimAdmin(
@Email @RequestHeader("X-Komga-Email") email: String,
@NotBlank @RequestHeader("X-Komga-Password") password: String
): UserDto {
if (userDetailsLifecycle.countUsers() > 0)
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "This server has already been claimed")
return (userDetailsLifecycle.createUser(
User.withUsername(email)
.password(password)
.roles(UserRoles.ADMIN.name)
.build()) as KomgaPrincipal
).toDto()
}
}

View file

@ -7,6 +7,7 @@ import org.gotson.komga.domain.persistence.LibraryRepository
import org.gotson.komga.infrastructure.security.KomgaPrincipal
import org.gotson.komga.infrastructure.security.KomgaUserDetailsLifecycle
import org.gotson.komga.infrastructure.security.UserEmailAlreadyExistsException
import org.gotson.komga.interfaces.rest.dto.toDto
import org.springframework.data.repository.findByIdOrNull
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
@ -104,13 +105,6 @@ data class UserDto(
val roles: List<String>
)
fun KomgaUser.toDto() =
UserDto(
id = id,
email = email,
roles = roles.map { it.name }
)
data class UserWithSharedLibrariesDto(
val id: Long,
val email: String,
@ -133,8 +127,6 @@ fun KomgaUser.toWithSharedLibrariesDto() =
sharedLibraries = sharedLibraries.map { SharedLibraryDto(it.id, it.name) }
)
fun KomgaPrincipal.toDto() = user.toDto()
data class UserCreationDto(
@get:Email val email: String,
@get:NotBlank val password: String,

View file

@ -0,0 +1,14 @@
package org.gotson.komga.interfaces.rest.dto
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.infrastructure.security.KomgaPrincipal
import org.gotson.komga.interfaces.rest.UserDto
fun KomgaUser.toDto() =
UserDto(
id = id,
email = email,
roles = roles.map { it.name }
)
fun KomgaPrincipal.toDto() = user.toDto()

View file

@ -15,7 +15,7 @@ import org.springframework.stereotype.Controller
private val logger = KotlinLogging.logger {}
@Profile("dev", "prod")
@Profile("(dev | prod) & !claim")
@Controller
class InitialUserController(
private val userDetailsLifecycle: KomgaUserDetailsLifecycle,