diff --git a/komga-webui/src/views/SettingsUsers.vue b/komga-webui/src/views/SettingsUsers.vue
index 8c67cc286..3c1a36c51 100644
--- a/komga-webui/src/views/SettingsUsers.vue
+++ b/komga-webui/src/views/SettingsUsers.vue
@@ -40,7 +40,9 @@
-
+
mdi-delete
@@ -90,6 +92,9 @@ export default Vue.extend({
computed: {
users (): UserWithSharedLibrariesDto[] {
return this.$store.state.komgaUsers.users
+ },
+ me (): UserDto {
+ return this.$store.state.komgaUsers.me
}
},
async mounted () {
diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/UserController.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/UserController.kt
index 367fcf68e..a98f80ad5 100644
--- a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/UserController.kt
+++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/UserController.kt
@@ -33,20 +33,20 @@ private val logger = KotlinLogging.logger {}
@RestController
@RequestMapping("api/v1/users", produces = [MediaType.APPLICATION_JSON_VALUE])
class UserController(
- private val userDetailsLifecycle: KomgaUserDetailsLifecycle,
- private val userRepository: KomgaUserRepository,
- private val libraryRepository: LibraryRepository
+ private val userDetailsLifecycle: KomgaUserDetailsLifecycle,
+ private val userRepository: KomgaUserRepository,
+ private val libraryRepository: LibraryRepository
) {
@GetMapping("me")
fun getMe(@AuthenticationPrincipal principal: KomgaPrincipal): UserDto =
- principal.user.toDto()
+ principal.user.toDto()
@PatchMapping("me/password")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun updatePassword(
- @AuthenticationPrincipal principal: KomgaPrincipal,
- @Valid @RequestBody newPasswordDto: PasswordUpdateDto
+ @AuthenticationPrincipal principal: KomgaPrincipal,
+ @Valid @RequestBody newPasswordDto: PasswordUpdateDto
) {
userDetailsLifecycle.updatePassword(principal, newPasswordDto.password, false)
}
@@ -54,22 +54,25 @@ class UserController(
@GetMapping
@PreAuthorize("hasRole('ADMIN')")
fun getAll(): List =
- userRepository.findAll().map { it.toWithSharedLibrariesDto() }
+ userRepository.findAll().map { it.toWithSharedLibrariesDto() }
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
@PreAuthorize("hasRole('ADMIN')")
fun addOne(@Valid @RequestBody newUser: UserCreationDto): UserDto =
- try {
- (userDetailsLifecycle.createUser(newUser.toUserDetails()) as KomgaPrincipal).toDto()
- } catch (e: UserEmailAlreadyExistsException) {
- throw ResponseStatusException(HttpStatus.BAD_REQUEST, "A user with this email already exists")
- }
+ try {
+ (userDetailsLifecycle.createUser(newUser.toUserDetails()) as KomgaPrincipal).toDto()
+ } catch (e: UserEmailAlreadyExistsException) {
+ throw ResponseStatusException(HttpStatus.BAD_REQUEST, "A user with this email already exists")
+ }
@DeleteMapping("{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
- @PreAuthorize("hasRole('ADMIN')")
- fun delete(@PathVariable id: Long) {
+ @PreAuthorize("hasRole('ADMIN') and #principal.user.id != #id")
+ fun delete(
+ @PathVariable id: Long,
+ @AuthenticationPrincipal principal: KomgaPrincipal
+ ) {
userRepository.findByIdOrNull(id)?.let {
userDetailsLifecycle.deleteUser(it)
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@@ -79,8 +82,8 @@ class UserController(
@ResponseStatus(HttpStatus.NO_CONTENT)
@PreAuthorize("hasRole('ADMIN')")
fun updateSharesLibraries(
- @PathVariable id: Long,
- @Valid @RequestBody sharedLibrariesUpdateDto: SharedLibrariesUpdateDto
+ @PathVariable id: Long,
+ @Valid @RequestBody sharedLibrariesUpdateDto: SharedLibrariesUpdateDto
) {
userRepository.findByIdOrNull(id)?.let { user ->
if (sharedLibrariesUpdateDto.all) {
@@ -96,59 +99,59 @@ class UserController(
}
data class UserDto(
- val id: Long,
- val email: String,
- val roles: List
+ val id: Long,
+ val email: String,
+ val roles: List
)
fun KomgaUser.toDto() =
- UserDto(
- id = id,
- email = email,
- roles = roles.map { it.name }
- )
+ UserDto(
+ id = id,
+ email = email,
+ roles = roles.map { it.name }
+ )
data class UserWithSharedLibrariesDto(
- val id: Long,
- val email: String,
- val roles: List,
- val sharedAllLibraries: Boolean,
- val sharedLibraries: List
+ val id: Long,
+ val email: String,
+ val roles: List,
+ val sharedAllLibraries: Boolean,
+ val sharedLibraries: List
)
data class SharedLibraryDto(
- val id: Long,
- val name: String
+ val id: Long,
+ val name: String
)
fun KomgaUser.toWithSharedLibrariesDto() =
- UserWithSharedLibrariesDto(
- id = id,
- email = email,
- roles = roles.map { it.name },
- sharedAllLibraries = sharedAllLibraries,
- sharedLibraries = sharedLibraries.map { SharedLibraryDto(it.id, it.name) }
- )
+ UserWithSharedLibrariesDto(
+ id = id,
+ email = email,
+ roles = roles.map { it.name },
+ sharedAllLibraries = sharedAllLibraries,
+ 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,
- val roles: List = emptyList()
+ @get:Email val email: String,
+ @get:NotBlank val password: String,
+ val roles: List = emptyList()
) {
fun toUserDetails(): UserDetails =
- User.withUsername(email)
- .password(password)
- .roles(*roles.toTypedArray())
- .build()
+ User.withUsername(email)
+ .password(password)
+ .roles(*roles.toTypedArray())
+ .build()
}
data class PasswordUpdateDto(
- @get:NotBlank val password: String
+ @get:NotBlank val password: String
)
data class SharedLibrariesUpdateDto(
- val all: Boolean,
- val libraryIds: Set
+ val all: Boolean,
+ val libraryIds: Set
)