refactor: move user roles to separate database table

This commit is contained in:
Gauthier Roebroeck 2025-01-08 16:46:19 +08:00
parent 6dcebb4e07
commit cbb0d6151d
52 changed files with 352 additions and 339 deletions

View file

@ -0,0 +1,68 @@
CREATE TABLE USER_ROLE
(
USER_ID varchar NOT NULL,
ROLE varchar NOT NULL,
PRIMARY KEY (USER_ID, ROLE),
FOREIGN KEY (USER_ID) REFERENCES USER (ID)
);
insert into USER_ROLE
select id, "ADMIN"
from user
where ROLE_ADMIN = 1;
insert into USER_ROLE
select id, "KOREADER_SYNC"
from user
where ROLE_ADMIN = 1;
insert into USER_ROLE
select id, "FILE_DOWNLOAD"
from user
where ROLE_FILE_DOWNLOAD = 1;
insert into USER_ROLE
select id, "PAGE_STREAMING"
from user
where ROLE_PAGE_STREAMING = 1;
insert into USER_ROLE
select id, "KOBO_SYNC"
from user
where ROLE_KOBO_SYNC = 1;
-- Remove columns ROLE_ADMIN, ROLE_FILE_DOWNLOAD, ROLE_PAGE_STREAMING, ROLE_KOBO_SYNC from USER
PRAGMA foreign_keys= OFF;
create table USER_dg_tmp
(
ID varchar not null
primary key,
CREATED_DATE datetime default CURRENT_TIMESTAMP not null,
LAST_MODIFIED_DATE datetime default CURRENT_TIMESTAMP not null,
EMAIL varchar not null
unique,
PASSWORD varchar not null,
SHARED_ALL_LIBRARIES boolean default 1 not null,
AGE_RESTRICTION integer,
AGE_RESTRICTION_ALLOW_ONLY boolean
);
insert into USER_dg_tmp(ID, CREATED_DATE, LAST_MODIFIED_DATE, EMAIL, PASSWORD, SHARED_ALL_LIBRARIES, AGE_RESTRICTION,
AGE_RESTRICTION_ALLOW_ONLY)
select ID,
CREATED_DATE,
LAST_MODIFIED_DATE,
EMAIL,
PASSWORD,
SHARED_ALL_LIBRARIES,
AGE_RESTRICTION,
AGE_RESTRICTION_ALLOW_ONLY
from USER;
drop table USER;
alter table USER_dg_tmp
rename to USER;
PRAGMA foreign_keys= ON;

View file

@ -6,22 +6,13 @@ import jakarta.validation.constraints.NotBlank
import org.gotson.komga.language.lowerNotBlank
import java.time.LocalDateTime
const val ROLE_USER = "USER"
const val ROLE_ADMIN = "ADMIN"
const val ROLE_FILE_DOWNLOAD = "FILE_DOWNLOAD"
const val ROLE_PAGE_STREAMING = "PAGE_STREAMING"
const val ROLE_KOBO_SYNC = "KOBO_SYNC"
data class KomgaUser(
@Email(regexp = ".+@.+\\..+")
@NotBlank
val email: String,
@NotBlank
val password: String,
val roleAdmin: Boolean,
val roleFileDownload: Boolean = true,
val rolePageStreaming: Boolean = true,
val roleKoboSync: Boolean = false,
val roles: Set<UserRoles> = setOf(UserRoles.FILE_DOWNLOAD, UserRoles.PAGE_STREAMING),
val sharedLibrariesIds: Set<String> = emptySet(),
val sharedAllLibraries: Boolean = true,
val restrictions: ContentRestrictions = ContentRestrictions(),
@ -30,14 +21,8 @@ data class KomgaUser(
override val lastModifiedDate: LocalDateTime = createdDate,
) : Auditable {
@delegate:Transient
val roles: Set<String> by lazy {
buildSet {
add(ROLE_USER)
if (roleAdmin) add(ROLE_ADMIN)
if (roleFileDownload) add(ROLE_FILE_DOWNLOAD)
if (rolePageStreaming) add(ROLE_PAGE_STREAMING)
if (roleKoboSync) add(ROLE_KOBO_SYNC)
}
val isAdmin: Boolean by lazy {
roles.contains(UserRoles.ADMIN)
}
/**
@ -60,7 +45,7 @@ data class KomgaUser(
else -> null
}
fun canAccessAllLibraries(): Boolean = sharedAllLibraries || roleAdmin
fun canAccessAllLibraries(): Boolean = sharedAllLibraries || isAdmin
fun canAccessLibrary(libraryId: String): Boolean = canAccessAllLibraries() || sharedLibrariesIds.any { it == libraryId }
@ -107,5 +92,5 @@ data class KomgaUser(
return !ageDenied && !labelDenied
}
override fun toString(): String = "KomgaUser(email='$email', roleAdmin=$roleAdmin, roleFileDownload=$roleFileDownload, rolePageStreaming=$rolePageStreaming, roleKoboSync=$roleKoboSync, sharedLibrariesIds=$sharedLibrariesIds, sharedAllLibraries=$sharedAllLibraries, restrictions=$restrictions, id='$id', createdDate=$createdDate, lastModifiedDate=$lastModifiedDate)"
override fun toString(): String = "KomgaUser(createdDate=$createdDate, email='$email', roles=$roles, sharedLibrariesIds=$sharedLibrariesIds, sharedAllLibraries=$sharedAllLibraries, restrictions=$restrictions, id='$id', lastModifiedDate=$lastModifiedDate)"
}

View file

@ -0,0 +1,26 @@
package org.gotson.komga.domain.model
enum class UserRoles {
ADMIN,
FILE_DOWNLOAD,
PAGE_STREAMING,
KOBO_SYNC,
;
companion object {
/**
* Returns a Set composed of the enum constant of this type with the specified name.
* The string must match exactly an identifier used to declare an enum constant in this type.
* (Extraneous whitespace characters are not permitted.)
*/
fun valuesOf(roles: Iterable<String>): Set<UserRoles> =
roles
.mapNotNull {
try {
valueOf(it)
} catch (_: Exception) {
null
}
}.toSet()
}
}

View file

@ -5,6 +5,7 @@ import org.gotson.komga.domain.model.AllowExclude
import org.gotson.komga.domain.model.ApiKey
import org.gotson.komga.domain.model.ContentRestrictions
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.jooq.main.Tables
import org.gotson.komga.jooq.main.tables.records.AnnouncementsReadRecord
@ -23,6 +24,7 @@ class KomgaUserDao(
private val dsl: DSLContext,
) : KomgaUserRepository {
private val u = Tables.USER
private val ur = Tables.USER_ROLE
private val ul = Tables.USER_LIBRARY_SHARING
private val us = Tables.USER_SHARING
private val ar = Tables.ANNOUNCEMENTS_READ
@ -60,34 +62,37 @@ class KomgaUserDao(
private fun ResultQuery<Record>.fetchAndMap() =
this
.fetchGroups({ it.into(u) }, { it.into(ul) })
.map { (ur, ulr) ->
.map { (userRecord, ulr) ->
val usr =
dsl
.selectFrom(us)
.where(us.USER_ID.eq(ur.id))
.where(us.USER_ID.eq(userRecord.id))
.toList()
val roles =
dsl
.select(ur.ROLE)
.from(ur)
.where(ur.USER_ID.eq(userRecord.id))
.fetch(ur.ROLE)
KomgaUser(
email = ur.email,
password = ur.password,
roleAdmin = ur.roleAdmin,
roleFileDownload = ur.roleFileDownload,
rolePageStreaming = ur.rolePageStreaming,
roleKoboSync = ur.roleKoboSync,
email = userRecord.email,
password = userRecord.password,
roles = UserRoles.valuesOf(roles),
sharedLibrariesIds = ulr.mapNotNull { it.libraryId }.toSet(),
sharedAllLibraries = ur.sharedAllLibraries,
sharedAllLibraries = userRecord.sharedAllLibraries,
restrictions =
ContentRestrictions(
ageRestriction =
if (ur.ageRestriction != null && ur.ageRestrictionAllowOnly != null)
AgeRestriction(ur.ageRestriction, if (ur.ageRestrictionAllowOnly) AllowExclude.ALLOW_ONLY else AllowExclude.EXCLUDE)
if (userRecord.ageRestriction != null && userRecord.ageRestrictionAllowOnly != null)
AgeRestriction(userRecord.ageRestriction, if (userRecord.ageRestrictionAllowOnly) AllowExclude.ALLOW_ONLY else AllowExclude.EXCLUDE)
else
null,
labelsAllow = usr.filter { it.allow }.map { it.label }.toSet(),
labelsExclude = usr.filterNot { it.allow }.map { it.label }.toSet(),
),
id = ur.id,
createdDate = ur.createdDate.toCurrentTimeZone(),
lastModifiedDate = ur.lastModifiedDate.toCurrentTimeZone(),
id = userRecord.id,
createdDate = userRecord.createdDate.toCurrentTimeZone(),
lastModifiedDate = userRecord.lastModifiedDate.toCurrentTimeZone(),
)
}
@ -98,10 +103,6 @@ class KomgaUserDao(
.set(u.ID, user.id)
.set(u.EMAIL, user.email)
.set(u.PASSWORD, user.password)
.set(u.ROLE_ADMIN, user.roleAdmin)
.set(u.ROLE_FILE_DOWNLOAD, user.roleFileDownload)
.set(u.ROLE_PAGE_STREAMING, user.rolePageStreaming)
.set(u.ROLE_KOBO_SYNC, user.roleKoboSync)
.set(u.SHARED_ALL_LIBRARIES, user.sharedAllLibraries)
.set(u.AGE_RESTRICTION, user.restrictions.ageRestriction?.age)
.set(
@ -113,6 +114,7 @@ class KomgaUserDao(
},
).execute()
insertRoles(user)
insertSharedLibraries(user)
insertSharingRestrictions(user)
}
@ -133,10 +135,6 @@ class KomgaUserDao(
.update(u)
.set(u.EMAIL, user.email)
.set(u.PASSWORD, user.password)
.set(u.ROLE_ADMIN, user.roleAdmin)
.set(u.ROLE_FILE_DOWNLOAD, user.roleFileDownload)
.set(u.ROLE_PAGE_STREAMING, user.rolePageStreaming)
.set(u.ROLE_KOBO_SYNC, user.roleKoboSync)
.set(u.SHARED_ALL_LIBRARIES, user.sharedAllLibraries)
.set(u.AGE_RESTRICTION, user.restrictions.ageRestriction?.age)
.set(
@ -150,6 +148,11 @@ class KomgaUserDao(
.where(u.ID.eq(user.id))
.execute()
dsl
.deleteFrom(ur)
.where(ur.USER_ID.eq(user.id))
.execute()
dsl
.deleteFrom(ul)
.where(ul.USER_ID.eq(user.id))
@ -160,6 +163,7 @@ class KomgaUserDao(
.where(us.USER_ID.eq(user.id))
.execute()
insertRoles(user)
insertSharedLibraries(user)
insertSharingRestrictions(user)
}
@ -171,6 +175,16 @@ class KomgaUserDao(
dsl.batchStore(announcementIds.map { AnnouncementsReadRecord(user.id, it) }).execute()
}
private fun insertRoles(user: KomgaUser) {
user.roles.forEach {
dsl
.insertInto(ur)
.columns(ur.USER_ID, ur.ROLE)
.values(user.id, it.name)
.execute()
}
}
private fun insertSharedLibraries(user: KomgaUser) {
user.sharedLibrariesIds.forEach {
dsl
@ -205,6 +219,7 @@ class KomgaUserDao(
dsl.deleteFrom(ar).where(ar.USER_ID.equal(userId)).execute()
dsl.deleteFrom(us).where(us.USER_ID.equal(userId)).execute()
dsl.deleteFrom(ul).where(ul.USER_ID.equal(userId)).execute()
dsl.deleteFrom(ur).where(ur.USER_ID.equal(userId)).execute()
dsl.deleteFrom(u).where(u.ID.equal(userId)).execute()
}
@ -214,6 +229,7 @@ class KomgaUserDao(
dsl.deleteFrom(ar).execute()
dsl.deleteFrom(us).execute()
dsl.deleteFrom(ul).execute()
dsl.deleteFrom(ur).execute()
dsl.deleteFrom(u).execute()
}

View file

@ -2,12 +2,11 @@ package org.gotson.komga.infrastructure.security
import io.github.oshai.kotlinlogging.KotlinLogging
import jakarta.servlet.Filter
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ROLE_KOBO_SYNC
import org.gotson.komga.domain.model.ROLE_USER
import org.gotson.komga.domain.model.UserRoles
import org.gotson.komga.infrastructure.configuration.KomgaSettingsProvider
import org.gotson.komga.infrastructure.security.apikey.ApiKeyAuthenticationFilter
import org.gotson.komga.infrastructure.security.apikey.ApiKeyAuthenticationProvider
import org.gotson.komga.infrastructure.security.apikey.HeaderApiKeyAuthenticationConverter
import org.gotson.komga.infrastructure.security.apikey.UriRegexApiKeyAuthenticationConverter
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest
import org.springframework.boot.actuate.health.HealthEndpoint
@ -81,7 +80,7 @@ class SecurityConfiguration(
// this will only show limited details as `management.endpoint.health.show-details` is set to `when-authorized`
it.requestMatchers(EndpointRequest.to(HealthEndpoint::class.java)).permitAll()
// restrict all other actuator endpoints to ADMIN only
it.requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole(ROLE_ADMIN)
it.requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole(UserRoles.ADMIN.name)
it
.requestMatchers(
@ -101,7 +100,7 @@ class SecurityConfiguration(
"/api/**",
"/opds/**",
"/sse/**",
).hasRole(ROLE_USER)
).authenticated()
}.headers { headersConfigurer ->
headersConfigurer.cacheControl { it.disable() } // headers are set in WebMvcConfiguration
headersConfigurer.frameOptions { it.sameOrigin() } // for epubreader iframes
@ -174,7 +173,7 @@ class SecurityConfiguration(
securityMatcher("/kobo/**")
authorizeHttpRequests {
authorize(anyRequest, hasRole(ROLE_KOBO_SYNC))
authorize(anyRequest, hasRole(UserRoles.KOBO_SYNC.name))
}
headers {

View file

@ -73,7 +73,7 @@ class KomgaOAuth2UserServiceConfiguration(
private fun tryCreateNewUser(email: String) =
if (komgaProperties.oauth2AccountCreation) {
logger.info { "Creating new user from OAuth2 login: $email" }
userLifecycle.createUser(KomgaUser(email, RandomStringUtils.secure().nextAlphanumeric(12), roleAdmin = false))
userLifecycle.createUser(KomgaUser(email, RandomStringUtils.secure().nextAlphanumeric(12)))
} else {
throw OAuth2AuthenticationException("ERR_1025")
}

View file

@ -14,8 +14,6 @@ import org.gotson.komga.domain.model.MediaNotReadyException
import org.gotson.komga.domain.model.MediaProfile
import org.gotson.komga.domain.model.MediaUnsupportedException
import org.gotson.komga.domain.model.R2Progression
import org.gotson.komga.domain.model.ROLE_FILE_DOWNLOAD
import org.gotson.komga.domain.model.ROLE_PAGE_STREAMING
import org.gotson.komga.domain.model.toR2Progression
import org.gotson.komga.domain.persistence.BookRepository
import org.gotson.komga.domain.persistence.MediaRepository
@ -199,7 +197,7 @@ class CommonBookController(
],
produces = [MediaType.ALL_VALUE],
)
@PreAuthorize("hasRole('$ROLE_PAGE_STREAMING')")
@PreAuthorize("hasRole('PAGE_STREAMING')")
fun getBookPageRaw(
@AuthenticationPrincipal principal: KomgaPrincipal,
request: ServletWebRequest,
@ -319,7 +317,7 @@ class CommonBookController(
],
produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE],
)
@PreAuthorize("hasRole('$ROLE_FILE_DOWNLOAD')")
@PreAuthorize("hasRole('FILE_DOWNLOAD')")
fun getBookFile(
@AuthenticationPrincipal principal: KomgaPrincipal,
@PathVariable bookId: String,

View file

@ -16,7 +16,6 @@ import org.gotson.komga.domain.model.MediaType.EPUB
import org.gotson.komga.domain.model.R2Device
import org.gotson.komga.domain.model.R2Locator
import org.gotson.komga.domain.model.R2Progression
import org.gotson.komga.domain.model.ROLE_FILE_DOWNLOAD
import org.gotson.komga.domain.model.SyncPoint
import org.gotson.komga.domain.persistence.BookRepository
import org.gotson.komga.domain.persistence.MediaRepository
@ -633,7 +632,7 @@ class KoboController(
value = ["v1/books/{bookId}/file/epub"],
produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE],
)
@PreAuthorize("hasRole('$ROLE_FILE_DOWNLOAD')")
@PreAuthorize("hasRole('FILE_DOWNLOAD')")
fun getBookFile(
@AuthenticationPrincipal principal: KomgaPrincipal,
@PathVariable bookId: String,

View file

@ -10,7 +10,6 @@ import org.gotson.komga.domain.model.BookSearch
import org.gotson.komga.domain.model.Library
import org.gotson.komga.domain.model.Media
import org.gotson.komga.domain.model.MediaProfile
import org.gotson.komga.domain.model.ROLE_PAGE_STREAMING
import org.gotson.komga.domain.model.ReadList
import org.gotson.komga.domain.model.ReadStatus
import org.gotson.komga.domain.model.SearchCondition
@ -729,7 +728,7 @@ class OpdsController(
@ApiResponse(content = [Content(mediaType = "image/*", schema = Schema(type = "string", format = "binary"))])
@GetMapping("books/{bookId}/pages/{pageNumber}", produces = ["image/png", "image/gif", "image/jpeg"])
@PreAuthorize("hasRole('$ROLE_PAGE_STREAMING')")
@PreAuthorize("hasRole('PAGE_STREAMING')")
fun getBookPageOpds(
@AuthenticationPrincipal principal: KomgaPrincipal,
request: ServletWebRequest,

View file

@ -8,7 +8,6 @@ import org.gotson.komga.domain.model.BookSearch
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.model.Library
import org.gotson.komga.domain.model.Media
import org.gotson.komga.domain.model.ROLE_PAGE_STREAMING
import org.gotson.komga.domain.model.ReadList
import org.gotson.komga.domain.model.ReadStatus
import org.gotson.komga.domain.model.SearchCondition
@ -865,7 +864,7 @@ class Opds2Controller(
value = ["books/{bookId}/pages/{pageNumber}"],
produces = [MediaType.ALL_VALUE],
)
@PreAuthorize("hasRole('$ROLE_PAGE_STREAMING')")
@PreAuthorize("hasRole('PAGE_STREAMING')")
fun getBookPage(
@AuthenticationPrincipal principal: KomgaPrincipal,
request: ServletWebRequest,

View file

@ -1,7 +1,6 @@
package org.gotson.komga.interfaces.api.rest
import com.github.benmanes.caffeine.cache.Caffeine
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.persistence.KomgaUserRepository
import org.gotson.komga.infrastructure.security.KomgaPrincipal
import org.gotson.komga.interfaces.api.rest.dto.JsonFeedDto
@ -36,7 +35,7 @@ class AnnouncementController(
.build<String, JsonFeedDto>()
@GetMapping
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun getAnnouncements(
@AuthenticationPrincipal principal: KomgaPrincipal,
): JsonFeedDto =
@ -48,7 +47,7 @@ class AnnouncementController(
}
?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@PutMapping
@ResponseStatus(HttpStatus.NO_CONTENT)
fun markAnnouncementsRead(

View file

@ -21,8 +21,6 @@ import org.gotson.komga.domain.model.Media
import org.gotson.komga.domain.model.MediaExtensionEpub
import org.gotson.komga.domain.model.MediaNotReadyException
import org.gotson.komga.domain.model.MediaProfile
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ROLE_PAGE_STREAMING
import org.gotson.komga.domain.model.ReadStatus
import org.gotson.komga.domain.model.SearchCondition
import org.gotson.komga.domain.model.SearchContext
@ -32,7 +30,6 @@ import org.gotson.komga.domain.persistence.BookMetadataRepository
import org.gotson.komga.domain.persistence.BookRepository
import org.gotson.komga.domain.persistence.MediaRepository
import org.gotson.komga.domain.persistence.ReadListRepository
import org.gotson.komga.domain.persistence.ReadProgressRepository
import org.gotson.komga.domain.persistence.ThumbnailBookRepository
import org.gotson.komga.domain.service.BookAnalyzer
import org.gotson.komga.domain.service.BookLifecycle
@ -106,7 +103,6 @@ class BookController(
private val bookAnalyzer: BookAnalyzer,
private val bookLifecycle: BookLifecycle,
private val bookRepository: BookRepository,
private val readProgressRepository: ReadProgressRepository,
private val bookMetadataRepository: BookMetadataRepository,
private val mediaRepository: MediaRepository,
private val bookDtoRepository: BookDtoRepository,
@ -167,7 +163,7 @@ class BookController(
return bookDtoRepository
.findAll(bookSearch, SearchContext(principal.user), pageRequest)
.map { it.restrictUrl(!principal.user.roleAdmin) }
.map { it.restrictUrl(!principal.user.isAdmin) }
}
@Operation(description = "Return newly added or updated books.")
@ -194,7 +190,7 @@ class BookController(
.findAll(
SearchContext(principal.user),
pageRequest,
).map { it.restrictUrl(!principal.user.roleAdmin) }
).map { it.restrictUrl(!principal.user.isAdmin) }
}
@Operation(description = "Return first unread book of series with at least one book read and no books in progress.")
@ -211,11 +207,11 @@ class BookController(
principal.user.getAuthorizedLibraryIds(libraryIds),
page,
principal.user.restrictions,
).map { it.restrictUrl(!principal.user.roleAdmin) }
).map { it.restrictUrl(!principal.user.isAdmin) }
@PageableAsQueryParam
@GetMapping("api/v1/books/duplicates")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun getDuplicateBooks(
@AuthenticationPrincipal principal: KomgaPrincipal,
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
@ -248,7 +244,7 @@ class BookController(
bookDtoRepository.findByIdOrNull(bookId, principal.user.id)?.let {
contentRestrictionChecker.checkContentRestriction(principal.user, it)
it.restrictUrl(!principal.user.roleAdmin)
it.restrictUrl(!principal.user.isAdmin)
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@GetMapping("api/v1/books/{bookId}/previous")
@ -260,7 +256,7 @@ class BookController(
return bookDtoRepository
.findPreviousInSeriesOrNull(bookId, principal.user.id)
?.restrictUrl(!principal.user.roleAdmin)
?.restrictUrl(!principal.user.isAdmin)
?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
}
@ -273,7 +269,7 @@ class BookController(
return bookDtoRepository
.findNextInSeriesOrNull(bookId, principal.user.id)
?.restrictUrl(!principal.user.roleAdmin)
?.restrictUrl(!principal.user.isAdmin)
?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
}
@ -329,7 +325,7 @@ class BookController(
}
@PostMapping(value = ["api/v1/books/{bookId}/thumbnails"], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun addUserUploadedBookThumbnail(
@AuthenticationPrincipal principal: KomgaPrincipal,
@PathVariable(name = "bookId") bookId: String,
@ -358,7 +354,7 @@ class BookController(
}
@PutMapping("api/v1/books/{bookId}/thumbnails/{thumbnailId}/selected")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun markSelectedBookThumbnail(
@AuthenticationPrincipal principal: KomgaPrincipal,
@ -372,7 +368,7 @@ class BookController(
}
@DeleteMapping("api/v1/books/{bookId}/thumbnails/{thumbnailId}")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun deleteUserUploadedBookThumbnail(
@AuthenticationPrincipal principal: KomgaPrincipal,
@ -427,7 +423,7 @@ class BookController(
value = ["api/v1/books/{bookId}/pages/{pageNumber}"],
produces = [MediaType.ALL_VALUE],
)
@PreAuthorize("hasRole('$ROLE_PAGE_STREAMING')")
@PreAuthorize("hasRole('PAGE_STREAMING')")
fun getBookPage(
@AuthenticationPrincipal principal: KomgaPrincipal,
request: ServletWebRequest,
@ -566,7 +562,7 @@ class BookController(
): WPPublicationDto = commonBookController.getWebPubManifestDivinaInternal(principal, bookId, webPubGenerator)
@PostMapping("api/v1/books/{bookId}/analyze")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun analyze(
@PathVariable bookId: String,
@ -577,7 +573,7 @@ class BookController(
}
@PostMapping("api/v1/books/{bookId}/metadata/refresh")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun refreshMetadata(
@PathVariable bookId: String,
@ -589,7 +585,7 @@ class BookController(
}
@PatchMapping("api/v1/books/{bookId}/metadata")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun updateMetadata(
@PathVariable bookId: String,
@ -608,7 +604,7 @@ class BookController(
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@PatchMapping("api/v1/books/metadata")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun updateBatchMetadata(
@Parameter(description = "A map of book IDs which values are the metadata fields to update. Set a field to null to unset the metadata. You can omit fields you don't want to update.")
@ -670,7 +666,7 @@ class BookController(
}
@PostMapping("api/v1/books/import")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun importBooks(
@RequestBody bookImportBatch: BookImportBatchDto,
@ -692,7 +688,7 @@ class BookController(
}
@DeleteMapping("api/v1/books/{bookId}/file")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun deleteBook(
@PathVariable bookId: String,
@ -704,7 +700,7 @@ class BookController(
}
@PutMapping("api/v1/books/thumbnails")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun regenerateThumbnails(
@RequestParam(name = "for_bigger_result_only", required = false) forBiggerResultOnly: Boolean = false,

View file

@ -3,6 +3,7 @@ package org.gotson.komga.interfaces.api.rest
import jakarta.validation.constraints.Email
import jakarta.validation.constraints.NotBlank
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.model.UserRoles
import org.gotson.komga.domain.service.KomgaUserLifecycle
import org.gotson.komga.interfaces.api.rest.dto.UserDto
import org.gotson.komga.interfaces.api.rest.dto.toDto
@ -42,10 +43,7 @@ class ClaimController(
KomgaUser(
email = email,
password = password,
roleAdmin = true,
roleFileDownload = true,
rolePageStreaming = true,
roleKoboSync = true,
roles = UserRoles.entries.toSet(),
),
).toDto()
}

View file

@ -9,7 +9,6 @@ import org.gotson.komga.domain.model.DirectoryNotFoundException
import org.gotson.komga.domain.model.DuplicateNameException
import org.gotson.komga.domain.model.Library
import org.gotson.komga.domain.model.PathContainedInPath
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.SearchCondition
import org.gotson.komga.domain.model.SearchContext
import org.gotson.komga.domain.model.SearchOperator
@ -60,7 +59,7 @@ class LibraryController(
libraryRepository.findAll()
} else {
libraryRepository.findAllByIds(principal.user.sharedLibrariesIds)
}.sortedBy { it.name.lowercase() }.map { it.toDto(includeRoot = principal.user.roleAdmin) }
}.sortedBy { it.name.lowercase() }.map { it.toDto(includeRoot = principal.user.isAdmin) }
@GetMapping("{libraryId}")
fun getOne(
@ -69,11 +68,11 @@ class LibraryController(
): LibraryDto =
libraryRepository.findByIdOrNull(libraryId)?.let {
if (!principal.user.canAccessLibrary(it)) throw ResponseStatusException(HttpStatus.FORBIDDEN)
it.toDto(includeRoot = principal.user.roleAdmin)
it.toDto(includeRoot = principal.user.isAdmin)
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@PostMapping
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun addOne(
@AuthenticationPrincipal principal: KomgaPrincipal,
@Valid @RequestBody
@ -111,7 +110,7 @@ class LibraryController(
analyzeDimensions = library.analyzeDimensions,
oneshotsDirectory = library.oneshotsDirectory?.ifBlank { null },
),
).toDto(includeRoot = principal.user.roleAdmin)
).toDto(includeRoot = principal.user.isAdmin)
} catch (e: Exception) {
when (e) {
is FileNotFoundException,
@ -126,7 +125,7 @@ class LibraryController(
}
@PutMapping("/{libraryId}")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
@Deprecated("Use PATCH /v1/library instead", ReplaceWith("patchOne"))
fun updateOne(
@ -138,7 +137,7 @@ class LibraryController(
}
@PatchMapping("/{libraryId}")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun patchOne(
@PathVariable libraryId: String,
@ -199,7 +198,7 @@ class LibraryController(
}
@DeleteMapping("/{libraryId}")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun deleteOne(
@PathVariable libraryId: String,
@ -210,7 +209,7 @@ class LibraryController(
}
@PostMapping("{libraryId}/scan")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun scan(
@PathVariable libraryId: String,
@ -222,7 +221,7 @@ class LibraryController(
}
@PostMapping("{libraryId}/analyze")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun analyze(
@PathVariable libraryId: String,
@ -238,7 +237,7 @@ class LibraryController(
}
@PostMapping("{libraryId}/metadata/refresh")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun refreshMetadata(
@PathVariable libraryId: String,
@ -256,7 +255,7 @@ class LibraryController(
}
@PostMapping("{libraryId}/empty-trash")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun emptyTrash(
@PathVariable libraryId: String,

View file

@ -8,7 +8,6 @@ import jakarta.validation.Valid
import org.gotson.komga.application.tasks.TaskEmitter
import org.gotson.komga.domain.model.BookPageNumbered
import org.gotson.komga.domain.model.PageHashKnown
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.persistence.PageHashRepository
import org.gotson.komga.domain.service.PageHashLifecycle
import org.gotson.komga.infrastructure.swagger.PageableAsQueryParam
@ -37,7 +36,7 @@ import org.springframework.web.server.ResponseStatusException
@RestController
@RequestMapping("api/v1/page-hashes", produces = [MediaType.APPLICATION_JSON_VALUE])
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
class PageHashController(
private val pageHashRepository: PageHashRepository,
private val pageHashLifecycle: PageHashLifecycle,

View file

@ -18,8 +18,6 @@ import org.gotson.komga.domain.model.DomainEvent
import org.gotson.komga.domain.model.DuplicateNameException
import org.gotson.komga.domain.model.Media
import org.gotson.komga.domain.model.MediaType.ZIP
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ROLE_FILE_DOWNLOAD
import org.gotson.komga.domain.model.ReadList
import org.gotson.komga.domain.model.ReadStatus
import org.gotson.komga.domain.model.SearchCondition
@ -179,7 +177,7 @@ class ReadListController(
}
@PostMapping(value = ["{id}/thumbnails"], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun addUserUploadedReadListThumbnail(
@AuthenticationPrincipal principal: KomgaPrincipal,
@PathVariable(name = "id") id: String,
@ -208,7 +206,7 @@ class ReadListController(
}
@PutMapping("{id}/thumbnails/{thumbnailId}/selected")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun markSelectedReadListThumbnail(
@AuthenticationPrincipal principal: KomgaPrincipal,
@ -224,7 +222,7 @@ class ReadListController(
}
@DeleteMapping("{id}/thumbnails/{thumbnailId}")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun deleteUserUploadedReadListThumbnail(
@AuthenticationPrincipal principal: KomgaPrincipal,
@ -239,7 +237,7 @@ class ReadListController(
}
@PostMapping
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun addOne(
@Valid @RequestBody
readList: ReadListCreationDto,
@ -259,7 +257,7 @@ class ReadListController(
}
@PostMapping("match/comicrack")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun matchFromComicRackList(
@RequestParam("file") file: MultipartFile,
): ReadListRequestMatchDto =
@ -270,7 +268,7 @@ class ReadListController(
}
@PatchMapping("{id}")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun updateOne(
@PathVariable id: String,
@ -294,7 +292,7 @@ class ReadListController(
}
@DeleteMapping("{id}")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun deleteOne(
@PathVariable id: String,
@ -352,7 +350,7 @@ class ReadListController(
)
bookDtoRepository
.findAll(bookSearch, SearchContext(principal.user), pageRequest)
.map { it.restrictUrl(!principal.user.roleAdmin) }
.map { it.restrictUrl(!principal.user.isAdmin) }
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@GetMapping("{id}/books/{bookId}/previous")
@ -369,7 +367,7 @@ class ReadListController(
principal.user.id,
principal.user.getAuthorizedLibraryIds(null),
principal.user.restrictions,
)?.restrictUrl(!principal.user.roleAdmin)
)?.restrictUrl(!principal.user.isAdmin)
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@GetMapping("{id}/books/{bookId}/next")
@ -386,7 +384,7 @@ class ReadListController(
principal.user.id,
principal.user.getAuthorizedLibraryIds(null),
principal.user.restrictions,
)?.restrictUrl(!principal.user.roleAdmin)
)?.restrictUrl(!principal.user.isAdmin)
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@GetMapping("{id}/read-progress/tachiyomi")
@ -418,7 +416,7 @@ class ReadListController(
}
@GetMapping("{id}/file", produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE])
@PreAuthorize("hasRole('$ROLE_FILE_DOWNLOAD')")
@PreAuthorize("hasRole('FILE_DOWNLOAD')")
fun getReadListFile(
@AuthenticationPrincipal principal: KomgaPrincipal,
@PathVariable id: String,

View file

@ -1,7 +1,6 @@
package org.gotson.komga.interfaces.api.rest
import com.github.benmanes.caffeine.cache.Caffeine
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.infrastructure.security.KomgaPrincipal
import org.gotson.komga.interfaces.api.rest.dto.GithubReleaseDto
import org.gotson.komga.interfaces.api.rest.dto.ReleaseDto
@ -20,7 +19,7 @@ import java.util.concurrent.TimeUnit
private const val GITHUB_API = "https://api.github.com/repos/gotson/komga/releases"
@RestController
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@RequestMapping("api/v1/releases", produces = [MediaType.APPLICATION_JSON_VALUE])
class ReleaseController(
webClientBuilder: WebClient.Builder,
@ -34,7 +33,7 @@ class ReleaseController(
.build<String, List<GithubReleaseDto>>()
@GetMapping
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun getAnnouncements(
@AuthenticationPrincipal principal: KomgaPrincipal,
): List<ReleaseDto> =

View file

@ -10,7 +10,6 @@ import org.gotson.komga.domain.model.Author
import org.gotson.komga.domain.model.Dimension
import org.gotson.komga.domain.model.DomainEvent
import org.gotson.komga.domain.model.DuplicateNameException
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ReadStatus
import org.gotson.komga.domain.model.SearchCondition
import org.gotson.komga.domain.model.SearchContext
@ -156,7 +155,7 @@ class SeriesCollectionController(
}
@PostMapping(value = ["{id}/thumbnails"], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun addUserUploadedCollectionThumbnail(
@AuthenticationPrincipal principal: KomgaPrincipal,
@PathVariable(name = "id") id: String,
@ -185,7 +184,7 @@ class SeriesCollectionController(
}
@PutMapping("{id}/thumbnails/{thumbnailId}/selected")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun markSelectedCollectionThumbnail(
@AuthenticationPrincipal principal: KomgaPrincipal,
@ -201,7 +200,7 @@ class SeriesCollectionController(
}
@DeleteMapping("{id}/thumbnails/{thumbnailId}")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun deleteUserUploadedCollectionThumbnail(
@AuthenticationPrincipal principal: KomgaPrincipal,
@ -216,7 +215,7 @@ class SeriesCollectionController(
}
@PostMapping
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun addOne(
@Valid @RequestBody
collection: CollectionCreationDto,
@ -235,7 +234,7 @@ class SeriesCollectionController(
}
@PatchMapping("{id}")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun updateOne(
@PathVariable id: String,
@ -258,7 +257,7 @@ class SeriesCollectionController(
}
@DeleteMapping("{id}")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun deleteOne(
@PathVariable id: String,
@ -339,6 +338,6 @@ class SeriesCollectionController(
seriesDtoRepository
.findAll(search, SearchContext(principal.user), pageRequest)
.map { it.restrictUrl(!principal.user.roleAdmin) }
.map { it.restrictUrl(!principal.user.isAdmin) }
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
}

View file

@ -25,8 +25,6 @@ import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.model.MarkSelectedPreference
import org.gotson.komga.domain.model.Media
import org.gotson.komga.domain.model.MediaType.ZIP
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ROLE_FILE_DOWNLOAD
import org.gotson.komga.domain.model.ReadStatus
import org.gotson.komga.domain.model.SearchCondition
import org.gotson.komga.domain.model.SearchContext
@ -220,7 +218,7 @@ class SeriesController(
return seriesDtoRepository
.findAll(seriesSearch, SearchContext(principal.user), pageRequest)
.map { it.restrictUrl(!principal.user.roleAdmin) }
.map { it.restrictUrl(!principal.user.isAdmin) }
}
@PageableAsQueryParam
@ -250,7 +248,7 @@ class SeriesController(
return seriesDtoRepository
.findAll(search, SearchContext(principal.user), pageRequest)
.map { it.restrictUrl(!principal.user.roleAdmin) }
.map { it.restrictUrl(!principal.user.isAdmin) }
}
@Deprecated("use /v1/series/list/alphabetical-groups instead")
@ -376,7 +374,7 @@ class SeriesController(
),
SearchContext(principal.user),
pageRequest,
).map { it.restrictUrl(!principal.user.roleAdmin) }
).map { it.restrictUrl(!principal.user.isAdmin) }
}
@Operation(description = "Return newly added series.")
@ -415,7 +413,7 @@ class SeriesController(
),
SearchContext(principal.user),
pageRequest,
).map { it.restrictUrl(!principal.user.roleAdmin) }
).map { it.restrictUrl(!principal.user.isAdmin) }
}
@Operation(description = "Return recently updated series, but not newly added ones.")
@ -454,7 +452,7 @@ class SeriesController(
),
SearchContext(principal.user),
pageRequest,
).map { it.restrictUrl(!principal.user.roleAdmin) }
).map { it.restrictUrl(!principal.user.isAdmin) }
}
@GetMapping("v1/series/{seriesId}")
@ -464,7 +462,7 @@ class SeriesController(
): SeriesDto =
seriesDtoRepository.findByIdOrNull(id, principal.user.id)?.let {
contentRestrictionChecker.checkContentRestriction(principal.user, it)
it.restrictUrl(!principal.user.roleAdmin)
it.restrictUrl(!principal.user.isAdmin)
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@ApiResponse(content = [Content(schema = Schema(type = "string", format = "binary"))])
@ -505,7 +503,7 @@ class SeriesController(
}
@PostMapping(value = ["v1/series/{seriesId}/thumbnails"], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun postUserUploadedSeriesThumbnail(
@PathVariable(name = "seriesId") seriesId: String,
@RequestParam("file") file: MultipartFile,
@ -533,7 +531,7 @@ class SeriesController(
}
@PutMapping("v1/series/{seriesId}/thumbnails/{thumbnailId}/selected")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun postMarkSelectedSeriesThumbnail(
@PathVariable(name = "seriesId") seriesId: String,
@ -547,7 +545,7 @@ class SeriesController(
}
@DeleteMapping("v1/series/{seriesId}/thumbnails/{thumbnailId}")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun deleteUserUploadedSeriesThumbnail(
@PathVariable(name = "seriesId") seriesId: String,
@ -613,7 +611,7 @@ class SeriesController(
search,
SearchContext(principal.user),
pageRequest,
).map { it.restrictUrl(!principal.user.roleAdmin) }
).map { it.restrictUrl(!principal.user.isAdmin) }
}
@GetMapping("v1/series/{seriesId}/collections")
@ -629,7 +627,7 @@ class SeriesController(
}
@PostMapping("v1/series/{seriesId}/analyze")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun analyze(
@PathVariable seriesId: String,
@ -638,7 +636,7 @@ class SeriesController(
}
@PostMapping("v1/series/{seriesId}/metadata/refresh")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun refreshMetadata(
@PathVariable seriesId: String,
@ -650,7 +648,7 @@ class SeriesController(
}
@PatchMapping("v1/series/{seriesId}/metadata")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun updateMetadata(
@PathVariable seriesId: String,
@ -780,7 +778,7 @@ class SeriesController(
}
@GetMapping("v1/series/{seriesId}/file", produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE])
@PreAuthorize("hasRole('$ROLE_FILE_DOWNLOAD')")
@PreAuthorize("hasRole('FILE_DOWNLOAD')")
fun getSeriesFile(
@AuthenticationPrincipal principal: KomgaPrincipal,
@PathVariable seriesId: String,
@ -827,7 +825,7 @@ class SeriesController(
}
@DeleteMapping("v1/series/{seriesId}/file")
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
@ResponseStatus(HttpStatus.ACCEPTED)
fun deleteSeries(
@PathVariable seriesId: String,

View file

@ -1,7 +1,6 @@
package org.gotson.komga.interfaces.api.rest
import jakarta.validation.Valid
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.infrastructure.configuration.KomgaSettingsProvider
import org.gotson.komga.infrastructure.kobo.KepubConverter
import org.gotson.komga.infrastructure.web.WebServerEffectiveSettings
@ -24,7 +23,7 @@ import kotlin.time.Duration.Companion.days
@RestController
@RequestMapping(value = ["api/v1/settings"], produces = [MediaType.APPLICATION_JSON_VALUE])
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
class SettingsController(
private val komgaSettingsProvider: KomgaSettingsProvider,
@Value("\${server.port:#{null}}") private val configServerPort: Int?,

View file

@ -1,7 +1,6 @@
package org.gotson.komga.interfaces.api.rest
import org.gotson.komga.application.tasks.TasksRepository
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.security.access.prepost.PreAuthorize
@ -17,6 +16,6 @@ class TaskController(
) {
@DeleteMapping("api/v1/tasks")
@ResponseStatus(HttpStatus.OK)
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun emptyTaskQueue(): Int = tasksRepository.deleteAllWithoutOwner()
}

View file

@ -5,7 +5,6 @@ import io.github.oshai.kotlinlogging.KotlinLogging
import org.gotson.komga.domain.model.CodedException
import org.gotson.komga.domain.model.MediaNotReadyException
import org.gotson.komga.domain.model.MediaProfile
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.TransientBook
import org.gotson.komga.domain.persistence.TransientBookRepository
import org.gotson.komga.domain.service.BookAnalyzer
@ -31,7 +30,7 @@ private val logger = KotlinLogging.logger {}
@RestController
@RequestMapping("api/v1/transient-books", produces = [MediaType.APPLICATION_JSON_VALUE])
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
class TransientBooksController(
private val transientBookLifecycle: TransientBookLifecycle,
private val transientBookRepository: TransientBookRepository,

View file

@ -6,11 +6,8 @@ import jakarta.validation.Valid
import org.gotson.komga.domain.model.AgeRestriction
import org.gotson.komga.domain.model.ContentRestrictions
import org.gotson.komga.domain.model.DuplicateNameException
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ROLE_FILE_DOWNLOAD
import org.gotson.komga.domain.model.ROLE_KOBO_SYNC
import org.gotson.komga.domain.model.ROLE_PAGE_STREAMING
import org.gotson.komga.domain.model.UserEmailAlreadyExistsException
import org.gotson.komga.domain.model.UserRoles
import org.gotson.komga.domain.persistence.AuthenticationActivityRepository
import org.gotson.komga.domain.persistence.KomgaUserRepository
import org.gotson.komga.domain.persistence.LibraryRepository
@ -80,12 +77,12 @@ class UserController(
}
@GetMapping
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun getAll(): List<UserDto> = userRepository.findAll().map { it.toDto() }
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun addOne(
@Valid @RequestBody
newUser: UserCreationDto,
@ -98,7 +95,7 @@ class UserController(
@DeleteMapping("{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
@PreAuthorize("hasRole('$ROLE_ADMIN') and #principal.user.id != #id")
@PreAuthorize("hasRole('ADMIN') and #principal.user.id != #id")
fun delete(
@PathVariable id: String,
@AuthenticationPrincipal principal: KomgaPrincipal,
@ -110,7 +107,7 @@ class UserController(
@PatchMapping("{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
@PreAuthorize("hasRole('$ROLE_ADMIN') and #principal.user.id != #id")
@PreAuthorize("hasRole('ADMIN') and #principal.user.id != #id")
fun updateUser(
@PathVariable id: String,
@Valid @RequestBody
@ -121,10 +118,7 @@ class UserController(
val updatedUser =
with(patch) {
existing.copy(
roleAdmin = if (isSet("roles")) roles!!.contains(ROLE_ADMIN) else existing.roleAdmin,
roleFileDownload = if (isSet("roles")) roles!!.contains(ROLE_FILE_DOWNLOAD) else existing.roleFileDownload,
rolePageStreaming = if (isSet("roles")) roles!!.contains(ROLE_PAGE_STREAMING) else existing.rolePageStreaming,
roleKoboSync = if (isSet("roles")) roles!!.contains(ROLE_KOBO_SYNC) else existing.roleKoboSync,
roles = if (isSet("roles")) UserRoles.valuesOf(roles!!) else existing.roles,
sharedAllLibraries = if (isSet("sharedLibraries")) sharedLibraries!!.all else existing.sharedAllLibraries,
sharedLibrariesIds =
if (isSet("sharedLibraries")) {
@ -167,7 +161,7 @@ class UserController(
@PatchMapping("{id}/password")
@ResponseStatus(HttpStatus.NO_CONTENT)
@PreAuthorize("hasRole('$ROLE_ADMIN') or #principal.user.id == #id")
@PreAuthorize("hasRole('ADMIN') or #principal.user.id == #id")
fun updatePassword(
@PathVariable id: String,
@AuthenticationPrincipal principal: KomgaPrincipal,
@ -187,7 +181,7 @@ class UserController(
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
@Parameter(hidden = true) page: Pageable,
): Page<AuthenticationActivityDto> {
if (demo && !principal.user.roleAdmin) throw ResponseStatusException(HttpStatus.FORBIDDEN)
if (demo && !principal.user.isAdmin) throw ResponseStatusException(HttpStatus.FORBIDDEN)
val sort =
if (page.sort.isSorted)
page.sort
@ -209,7 +203,7 @@ class UserController(
@GetMapping("authentication-activity")
@PageableAsQueryParam
@PreAuthorize("hasRole('$ROLE_ADMIN')")
@PreAuthorize("hasRole('ADMIN')")
fun getAuthenticationActivity(
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
@Parameter(hidden = true) page: Pageable,
@ -234,7 +228,7 @@ class UserController(
}
@GetMapping("{id}/authentication-activity/latest")
@PreAuthorize("hasRole('$ROLE_ADMIN') or #principal.user.id == #id")
@PreAuthorize("hasRole('ADMIN') or #principal.user.id == #id")
fun getLatestAuthenticationActivityForUser(
@PathVariable id: String,
@AuthenticationPrincipal principal: KomgaPrincipal,
@ -249,7 +243,7 @@ class UserController(
fun getApiKeys(
@AuthenticationPrincipal principal: KomgaPrincipal,
): Collection<ApiKeyDto> {
if (demo) throw ResponseStatusException(HttpStatus.FORBIDDEN)
if (demo && !principal.user.isAdmin) throw ResponseStatusException(HttpStatus.FORBIDDEN)
return userRepository.findApiKeyByUserId(principal.user.id).map { it.toDto().redacted() }
}
@ -258,7 +252,7 @@ class UserController(
@AuthenticationPrincipal principal: KomgaPrincipal,
@Valid @RequestBody apiKeyRequest: ApiKeyRequestDto,
): ApiKeyDto {
if (demo) throw ResponseStatusException(HttpStatus.FORBIDDEN)
if (demo && !principal.user.isAdmin) throw ResponseStatusException(HttpStatus.FORBIDDEN)
return try {
userLifecycle.createApiKey(principal.user, apiKeyRequest.comment)?.toDto()
} catch (e: DuplicateNameException) {

View file

@ -5,10 +5,7 @@ import jakarta.validation.constraints.NotBlank
import org.gotson.komga.domain.model.AgeRestriction
import org.gotson.komga.domain.model.AllowExclude
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ROLE_FILE_DOWNLOAD
import org.gotson.komga.domain.model.ROLE_KOBO_SYNC
import org.gotson.komga.domain.model.ROLE_PAGE_STREAMING
import org.gotson.komga.domain.model.UserRoles
import org.gotson.komga.infrastructure.security.KomgaPrincipal
data class UserDto(
@ -33,7 +30,7 @@ fun KomgaUser.toDto() =
UserDto(
id = id,
email = email,
roles = roles,
roles = roles.map { it.name }.toSet() + "USER",
sharedAllLibraries = sharedAllLibraries,
sharedLibrariesIds = sharedLibrariesIds,
labelsAllow = restrictions.labelsAllow,
@ -52,10 +49,7 @@ data class UserCreationDto(
KomgaUser(
email,
password,
roleAdmin = roles.contains(ROLE_ADMIN),
roleFileDownload = roles.contains(ROLE_FILE_DOWNLOAD),
rolePageStreaming = roles.contains(ROLE_PAGE_STREAMING),
roleKoboSync = roles.contains(ROLE_KOBO_SYNC),
roles = UserRoles.valuesOf(roles),
)
}

View file

@ -3,6 +3,7 @@ package org.gotson.komga.interfaces.scheduler
import io.github.oshai.kotlinlogging.KotlinLogging
import org.apache.commons.lang3.RandomStringUtils
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.model.UserRoles
import org.gotson.komga.domain.service.KomgaUserLifecycle
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.context.annotation.Bean
@ -39,8 +40,8 @@ class InitialUsersDevConfiguration {
@Bean
fun initialUsers(): List<KomgaUser> =
listOf(
KomgaUser("admin@example.org", "admin", roleAdmin = true, roleKoboSync = true),
KomgaUser("user@example.org", "user", roleAdmin = false),
KomgaUser("admin@example.org", "admin", roles = UserRoles.entries.toSet()),
KomgaUser("user@example.org", "user"),
)
}
@ -50,6 +51,6 @@ class InitialUsersProdConfiguration {
@Bean
fun initialUsers(): List<KomgaUser> =
listOf(
KomgaUser("admin@example.org", RandomStringUtils.secure().nextAlphanumeric(12), roleAdmin = true),
KomgaUser("admin@example.org", RandomStringUtils.secure().nextAlphanumeric(12), roles = UserRoles.entries.toSet()),
)
}

View file

@ -117,7 +117,7 @@ class SseController(
synchronized(emitters) {
emitters
.filter { if (adminOnly) it.value.roleAdmin else true }
.filter { if (adminOnly) it.value.isAdmin else true }
.filter { if (userIdOnly != null) it.value.id == userIdOnly else true }
.forEach { (emitter, _) ->
try {

View file

@ -5,7 +5,7 @@ import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
class KomgaUserTest {
val defaultUser = KomgaUser("user@example.org", "aPassword", false)
val defaultUser = KomgaUser("user@example.org", "aPassword")
@Nested
inner class ContentRestriction {

View file

@ -62,8 +62,8 @@ class BookImporterTest(
@Autowired private val readListLifecycle: ReadListLifecycle,
) {
private val library = makeLibrary("lib", "file:/library")
private val user1 = KomgaUser("user1@example.org", "", false)
private val user2 = KomgaUser("user2@example.org", "", false)
private val user1 = KomgaUser("user1@example.org", "")
private val user2 = KomgaUser("user2@example.org", "")
@MockkBean
private lateinit var mockTackReceiver: TaskEmitter

View file

@ -62,8 +62,8 @@ class BookLifecycleTest(
private lateinit var mockAnalyzer: BookAnalyzer
private val library = makeLibrary()
private val user1 = KomgaUser("user1@example.org", "", false)
private val user2 = KomgaUser("user2@example.org", "", false)
private val user1 = KomgaUser("user1@example.org", "")
private val user2 = KomgaUser("user2@example.org", "")
@BeforeAll
fun `setup library`() {

View file

@ -25,8 +25,8 @@ class KomgaUserLifecycleTest(
@SpykBean
private lateinit var apiKeyGenerator: ApiKeyGenerator
private val user1 = KomgaUser("user1@example.org", "", false)
private val user2 = KomgaUser("user2@example.org", "", false)
private val user1 = KomgaUser("user1@example.org", "")
private val user2 = KomgaUser("user2@example.org", "")
@BeforeAll
fun setup() {

View file

@ -88,7 +88,7 @@ class LibraryContentLifecycleTest(
@MockkBean
private lateinit var mockTaskEmitter: TaskEmitter
private val user = KomgaUser("user@example.org", "", false, id = "1")
private val user = KomgaUser("user@example.org", "", id = "1")
@BeforeAll
fun setup() {

View file

@ -54,7 +54,6 @@ class SyncPointLifecycleTest(
KomgaUser(
"user1@example.org",
"",
false,
sharedLibrariesIds = setOf(library1.id, library2.id),
restrictions =
ContentRestrictions(

View file

@ -63,7 +63,7 @@ class BookDtoDaoTest(
) {
private val library = makeLibrary()
private var series = makeSeries("Series")
private val user = KomgaUser("user@example.org", "", false)
private val user = KomgaUser("user@example.org", "")
@MockkBean
private lateinit var mockEventPublisher: ApplicationEventPublisher

View file

@ -69,8 +69,8 @@ class BookSearchTest(
private val library2 = makeLibrary()
private val series1 = makeSeries("Series 1").copy(libraryId = library1.id)
private val series2 = makeSeries("Series 2").copy(libraryId = library2.id)
private val user1 = KomgaUser("user1@example.org", "p", false)
private val user2 = KomgaUser("user2@example.org", "p", false)
private val user1 = KomgaUser("user1@example.org", "p")
private val user2 = KomgaUser("user2@example.org", "p")
@MockkBean
private lateinit var mockEventPublisher: ApplicationEventPublisher

View file

@ -5,6 +5,7 @@ import org.gotson.komga.domain.model.AgeRestriction
import org.gotson.komga.domain.model.AllowExclude
import org.gotson.komga.domain.model.ContentRestrictions
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.model.UserRoles
import org.gotson.komga.domain.model.makeLibrary
import org.gotson.komga.domain.persistence.LibraryRepository
import org.gotson.komga.infrastructure.jooq.offset
@ -46,10 +47,6 @@ class KomgaUserDaoTest(
KomgaUser(
email = "user@example.org",
password = "password",
roleAdmin = false,
rolePageStreaming = false,
roleFileDownload = false,
roleKoboSync = false,
sharedLibrariesIds = setOf(library.id),
sharedAllLibraries = false,
)
@ -63,10 +60,7 @@ class KomgaUserDaoTest(
assertThat(lastModifiedDate).isCloseTo(now, offset)
assertThat(email).isEqualTo("user@example.org")
assertThat(password).isEqualTo("password")
assertThat(roleAdmin).isFalse
assertThat(rolePageStreaming).isFalse
assertThat(roleFileDownload).isFalse
assertThat(roleKoboSync).isFalse
assertThat(roles).containsExactlyInAnyOrder(UserRoles.FILE_DOWNLOAD, UserRoles.PAGE_STREAMING)
assertThat(sharedLibrariesIds).containsExactly(library.id)
assertThat(sharedAllLibraries).isFalse
assertThat(restrictions.ageRestriction).isNull()
@ -81,10 +75,6 @@ class KomgaUserDaoTest(
KomgaUser(
email = "user@example.org",
password = "password",
roleAdmin = false,
rolePageStreaming = false,
roleFileDownload = false,
roleKoboSync = false,
sharedLibrariesIds = setOf(library.id),
sharedAllLibraries = false,
restrictions =
@ -109,10 +99,7 @@ class KomgaUserDaoTest(
created.copy(
email = "user2@example.org",
password = "password2",
roleAdmin = true,
rolePageStreaming = true,
roleFileDownload = true,
roleKoboSync = true,
roles = setOf(UserRoles.ADMIN, UserRoles.FILE_DOWNLOAD, UserRoles.PAGE_STREAMING, UserRoles.KOBO_SYNC),
sharedLibrariesIds = emptySet(),
sharedAllLibraries = true,
restrictions =
@ -134,10 +121,7 @@ class KomgaUserDaoTest(
.isNotEqualTo(modified.createdDate)
assertThat(email).isEqualTo("user2@example.org")
assertThat(password).isEqualTo("password2")
assertThat(roleAdmin).isTrue
assertThat(rolePageStreaming).isTrue
assertThat(roleFileDownload).isTrue
assertThat(roleKoboSync).isTrue
assertThat(roles).containsExactlyInAnyOrder(UserRoles.ADMIN, UserRoles.FILE_DOWNLOAD, UserRoles.PAGE_STREAMING, UserRoles.KOBO_SYNC)
assertThat(sharedLibrariesIds).isEmpty()
assertThat(sharedAllLibraries).isTrue
assertThat(restrictions.ageRestriction).isNotNull
@ -157,8 +141,8 @@ class KomgaUserDaoTest(
@Test
fun `given multiple users when saving then they are persisted`() {
komgaUserDao.insert(KomgaUser("user1@example.org", "p", false))
komgaUserDao.insert(KomgaUser("user2@example.org", "p", true))
komgaUserDao.insert(KomgaUser("user1@example.org", "p"))
komgaUserDao.insert(KomgaUser("user2@example.org", "p"))
val users = komgaUserDao.findAll()
@ -171,8 +155,8 @@ class KomgaUserDaoTest(
@Test
fun `given some users when counting then proper count is returned`() {
komgaUserDao.insert(KomgaUser("user1@example.org", "p", false))
komgaUserDao.insert(KomgaUser("user2@example.org", "p", true))
komgaUserDao.insert(KomgaUser("user1@example.org", "p"))
komgaUserDao.insert(KomgaUser("user2@example.org", "p"))
val count = komgaUserDao.count()
@ -181,7 +165,7 @@ class KomgaUserDaoTest(
@Test
fun `given existing user when finding by id then user is returned`() {
val existing = KomgaUser("user1@example.org", "p", false)
val existing = KomgaUser("user1@example.org", "p")
komgaUserDao.insert(existing)
val user = komgaUserDao.findByIdOrNull(existing.id)
@ -198,7 +182,7 @@ class KomgaUserDaoTest(
@Test
fun `given existing user when deleting then user is deleted`() {
val existing = KomgaUser("user1@example.org", "p", false)
val existing = KomgaUser("user1@example.org", "p")
komgaUserDao.insert(existing)
komgaUserDao.delete(existing.id)
@ -209,7 +193,7 @@ class KomgaUserDaoTest(
@Test
fun `given users when checking if exists by email then return true or false`() {
komgaUserDao.insert(
KomgaUser("user1@example.org", "p", false),
KomgaUser("user1@example.org", "p"),
)
val exists = komgaUserDao.existsByEmailIgnoreCase("USER1@EXAMPLE.ORG")
@ -222,7 +206,7 @@ class KomgaUserDaoTest(
@Test
fun `given users when finding by email then return user`() {
komgaUserDao.insert(
KomgaUser("user1@example.org", "p", false),
KomgaUser("user1@example.org", "p"),
)
val found = komgaUserDao.findByEmailIgnoreCaseOrNull("USER1@EXAMPLE.ORG")

View file

@ -30,8 +30,8 @@ class ReadProgressDaoTest(
private val library = makeLibrary()
private val series = makeSeries("Series")
private val user1 = KomgaUser("user1@example.org", "", false)
private val user2 = KomgaUser("user2@example.org", "", false)
private val user1 = KomgaUser("user1@example.org", "")
private val user2 = KomgaUser("user2@example.org", "")
private val book1 = makeBook("Book1")
private val book2 = makeBook("Book2")

View file

@ -61,7 +61,7 @@ class SeriesDtoDaoTest(
@Autowired private val searchIndexLifecycle: SearchIndexLifecycle,
) {
private val library = makeLibrary()
private val user = KomgaUser("user@example.org", "", false)
private val user = KomgaUser("user@example.org", "")
@MockkBean
private lateinit var mockEventPublisher: ApplicationEventPublisher

View file

@ -65,8 +65,8 @@ class SeriesSearchTest(
private lateinit var seriesMetadataRepository: SeriesMetadataRepository
private val library1 = makeLibrary()
private val library2 = makeLibrary()
private val user1 = KomgaUser("user1@example.org", "p", false)
private val user2 = KomgaUser("user2@example.org", "p", false)
private val user1 = KomgaUser("user1@example.org", "p")
private val user2 = KomgaUser("user2@example.org", "p")
@MockkBean
private lateinit var mockEventPublisher: ApplicationEventPublisher

View file

@ -29,7 +29,7 @@ class SessionTest(
@BeforeAll
fun setup() {
user = KomgaUser("user@example.org", "user", false)
user = KomgaUser("user@example.org", "user")
userLifecycle.createUser(user)
}

View file

@ -4,6 +4,7 @@ import org.assertj.core.api.Assertions.assertThat
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.model.Media
import org.gotson.komga.domain.model.MediaType
import org.gotson.komga.domain.model.UserRoles
import org.gotson.komga.domain.model.makeBook
import org.gotson.komga.domain.model.makeLibrary
import org.gotson.komga.domain.model.makeSeries
@ -53,8 +54,7 @@ class KoboControllerTest(
KomgaUser(
"user@example.org",
"",
false,
roleKoboSync = true,
roles = setOf(UserRoles.KOBO_SYNC),
)
private lateinit var apiKey: String

View file

@ -44,8 +44,8 @@ class OpdsControllerTest(
@Autowired private val mockMvc: MockMvc,
) {
private val library = makeLibrary(id = "1")
private val user = KomgaUser("user@example.org", "", false, id = "1")
private val user2 = KomgaUser("user2@example.org", "", false, id = "2")
private val user = KomgaUser("user@example.org", "", id = "1")
private val user2 = KomgaUser("user2@example.org", "", id = "2")
@BeforeAll
fun `setup library`() {

View file

@ -1,7 +1,5 @@
package org.gotson.komga.interfaces.api.rest
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ROLE_USER
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
@ -45,7 +43,7 @@ class ActuatorTest(
}
@Test
@WithMockUser(roles = [ROLE_USER])
@WithMockUser
fun `given regular user when getting actuator endpoints then returns forbidden`() {
mockMvc
.get("/actuator")
@ -61,7 +59,7 @@ class ActuatorTest(
}
@Test
@WithMockUser(roles = [ROLE_ADMIN])
@WithMockUser(roles = ["ADMIN"])
fun `given admin user when getting actuator endpoints then returns ok`() {
mockMvc
.get("/actuator")

View file

@ -3,7 +3,6 @@ package org.gotson.komga.interfaces.api.rest
import com.ninjasquad.springmockk.SpykBean
import io.mockk.every
import io.mockk.verify
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.interfaces.api.rest.dto.JsonFeedDto
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
@ -56,7 +55,7 @@ class AnnouncementControllerTest(
)
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `when getting announcements multiple times then the server announcements are only fetched once`() {
every { announcementController.fetchWebsiteAnnouncements() } returns mockFeed

View file

@ -8,7 +8,6 @@ import org.gotson.komga.domain.model.Dimension
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.model.MarkSelectedPreference
import org.gotson.komga.domain.model.Media
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ThumbnailBook
import org.gotson.komga.domain.model.makeBook
import org.gotson.komga.domain.model.makeLibrary
@ -71,8 +70,8 @@ class BookControllerTest(
@Autowired private val mockMvc: MockMvc,
) {
private val library = makeLibrary(id = "1")
private val user = KomgaUser("user@example.org", "", false, id = "1")
private val user2 = KomgaUser("user2@example.org", "", false, id = "2")
private val user = KomgaUser("user@example.org", "", id = "1")
private val user2 = KomgaUser("user2@example.org", "", id = "2")
@BeforeAll
fun `setup library`() {
@ -771,7 +770,7 @@ class BookControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when getting books then full url is available`() {
val createdSeries =
makeSeries(name = "series", libraryId = library.id).let { series ->
@ -958,7 +957,7 @@ class BookControllerTest(
"""{"isbn":"978-123-456-789-6"}""", // invalid check digit
],
)
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given invalid json when updating metadata then raise validation error`(jsonString: String) {
mockMvc
.patch("/api/v1/books/1/metadata") {
@ -970,7 +969,7 @@ class BookControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given valid json when updating metadata then fields are updated`() {
makeSeries(name = "series", libraryId = library.id).let { series ->
seriesLifecycle.createSeries(series).also { created ->
@ -1050,7 +1049,7 @@ class BookControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given json with blank fields when updating metadata then fields with blanks are unset`() {
makeSeries(name = "series", libraryId = library.id).let { series ->
seriesLifecycle.createSeries(series).also { created ->
@ -1095,7 +1094,7 @@ class BookControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given json with null fields when updating metadata then fields with null are unset`() {
val testDate = LocalDate.of(2020, 1, 1)
@ -1157,7 +1156,7 @@ class BookControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given json without fields when updating metadata then existing fields are untouched`() {
val testDate = LocalDate.of(2020, 1, 1)

View file

@ -1,7 +1,5 @@
package org.gotson.komga.interfaces.api.rest
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ROLE_USER
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import org.springframework.beans.factory.annotation.Autowired
@ -39,7 +37,7 @@ class FileSystemControllerTest(
}
@Test
@WithMockUser(roles = [ROLE_USER, ROLE_ADMIN])
@WithMockUser(roles = ["ADMIN"])
fun `given relative path param when getDirectoryListing then return bad request`() {
mockMvc
.post(route) {
@ -49,7 +47,7 @@ class FileSystemControllerTest(
}
@Test
@WithMockUser(roles = [ROLE_USER, ROLE_ADMIN])
@WithMockUser(roles = ["ADMIN"])
fun `given non-existent path param when getDirectoryListing then return bad request`(
@TempDir parent: Path,
) {

View file

@ -1,7 +1,5 @@
package org.gotson.komga.interfaces.api.rest
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ROLE_USER
import org.gotson.komga.domain.model.makeLibrary
import org.gotson.komga.domain.persistence.LibraryRepository
import org.hamcrest.Matchers
@ -68,7 +66,7 @@ class LibraryControllerTest(
}
@Nested
inner class UserRole {
inner class UserRoles {
@Test
@WithMockCustomUser
fun `given user with access to all libraries when getAll then return ok`() {
@ -78,7 +76,7 @@ class LibraryControllerTest(
}
@Test
@WithMockUser(roles = [ROLE_USER])
@WithMockUser
fun `given user with USER role when addOne then return forbidden`() {
// language=JSON
val jsonString = """{"name":"test", "root": "C:\\Temp"}"""
@ -127,7 +125,7 @@ class LibraryControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when getting books then root is available`() {
mockMvc
.get(route)
@ -170,7 +168,7 @@ class LibraryControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given library with exclusions when updating library then exclusions are updated`(
@TempDir tmp: Path,
) {

View file

@ -4,10 +4,7 @@ import org.gotson.komga.domain.model.AgeRestriction
import org.gotson.komga.domain.model.AllowExclude
import org.gotson.komga.domain.model.ContentRestrictions
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ROLE_FILE_DOWNLOAD
import org.gotson.komga.domain.model.ROLE_KOBO_SYNC
import org.gotson.komga.domain.model.ROLE_PAGE_STREAMING
import org.gotson.komga.domain.model.UserRoles
import org.gotson.komga.infrastructure.security.KomgaPrincipal
import org.gotson.komga.infrastructure.security.apikey.ApiKeyAuthenticationToken
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
@ -21,7 +18,7 @@ import org.springframework.security.test.context.support.WithSecurityContextFact
@WithSecurityContext(factory = WithMockCustomUserSecurityContextFactory::class, setupBefore = TestExecutionEvent.TEST_EXECUTION)
annotation class WithMockCustomUser(
val email: String = "user@example.org",
val roles: Array<String> = [ROLE_FILE_DOWNLOAD, ROLE_PAGE_STREAMING, ROLE_KOBO_SYNC],
val roles: Array<String> = ["PAGE_STREAMING", "FILE_DOWNLOAD", "KOBO_SYNC"],
val sharedAllLibraries: Boolean = true,
val sharedLibraries: Array<String> = [],
val id: String = "0",
@ -41,12 +38,9 @@ class WithMockCustomUserSecurityContextFactory : WithSecurityContextFactory<With
KomgaUser(
email = customUser.email,
password = "",
roleAdmin = customUser.roles.contains(ROLE_ADMIN),
roleFileDownload = customUser.roles.contains(ROLE_FILE_DOWNLOAD),
rolePageStreaming = customUser.roles.contains(ROLE_PAGE_STREAMING),
roleKoboSync = customUser.roles.contains(ROLE_KOBO_SYNC),
sharedAllLibraries = customUser.sharedAllLibraries,
roles = UserRoles.valuesOf(customUser.roles.toList()),
sharedLibrariesIds = customUser.sharedLibraries.toSet(),
sharedAllLibraries = customUser.sharedAllLibraries,
restrictions =
ContentRestrictions(
ageRestriction =

View file

@ -1,7 +1,6 @@
package org.gotson.komga.interfaces.api.rest
import org.gotson.komga.domain.model.Book
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ReadList
import org.gotson.komga.domain.model.makeBook
import org.gotson.komga.domain.model.makeLibrary
@ -916,7 +915,7 @@ class ReadListControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when creating read list then return ok`() {
// language=JSON
val jsonString =
@ -937,7 +936,7 @@ class ReadListControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given existing read lists when creating read list with existing name then return bad request`() {
makeReadLists()
@ -957,7 +956,7 @@ class ReadListControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given read list with duplicate bookIds when creating read list then return bad request`() {
// language=JSON
val jsonString =
@ -996,7 +995,7 @@ class ReadListControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when updating read list then return no content`() {
makeReadLists()
@ -1026,7 +1025,7 @@ class ReadListControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given existing read lists when updating read list with existing name then return bad request`() {
makeReadLists()
@ -1043,7 +1042,7 @@ class ReadListControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given existing read list when updating read list with duplicate bookIds then return bad request`() {
makeReadLists()
@ -1060,7 +1059,7 @@ class ReadListControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when updating read list then only updated fields are modified`() {
makeReadLists()
@ -1121,7 +1120,7 @@ class ReadListControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when deleting read list then return no content`() {
makeReadLists()
@ -1382,7 +1381,7 @@ class ReadListControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given invalid cbl file when matching then return bad request`() {
val content = "garbled"
@ -1398,7 +1397,7 @@ class ReadListControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given cbl file without books when matching then return bad request`() {
val content =
"""
@ -1422,7 +1421,7 @@ class ReadListControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given cbl file without name when matching then return bad request`() {
val content =
"""
@ -1447,7 +1446,7 @@ class ReadListControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given cbl file with book without series when matching then return bad request`() {
val content =
"""

View file

@ -1,6 +1,5 @@
package org.gotson.komga.interfaces.api.rest
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.Series
import org.gotson.komga.domain.model.SeriesCollection
import org.gotson.komga.domain.model.makeBook
@ -819,7 +818,7 @@ class SeriesCollectionControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when creating collection then return ok`() {
// language=JSON
val jsonString =
@ -840,7 +839,7 @@ class SeriesCollectionControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given existing collections when creating collection with existing name then return bad request`() {
makeCollections()
@ -860,7 +859,7 @@ class SeriesCollectionControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given collection with duplicate seriesIds when creating collection then return bad request`() {
// language=JSON
val jsonString =
@ -899,7 +898,7 @@ class SeriesCollectionControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when updating collection then return no content`() {
makeCollections()
@ -929,7 +928,7 @@ class SeriesCollectionControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given existing collections when updating collection with existing name then return bad request`() {
makeCollections()
@ -946,7 +945,7 @@ class SeriesCollectionControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given existing collection when updating collection with duplicate seriesIds then return bad request`() {
makeCollections()
@ -963,7 +962,7 @@ class SeriesCollectionControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when updating collection then only updated fields are modified`() {
makeCollections()
@ -1024,7 +1023,7 @@ class SeriesCollectionControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when deleting collection then return no content`() {
makeCollections()

View file

@ -8,7 +8,6 @@ import org.gotson.komga.domain.model.Dimension
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.model.MarkSelectedPreference
import org.gotson.komga.domain.model.Media
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.SeriesMetadata
import org.gotson.komga.domain.model.ThumbnailBook
import org.gotson.komga.domain.model.makeBook
@ -78,7 +77,7 @@ class SeriesControllerTest(
@BeforeAll
fun `setup library`() {
libraryRepository.insert(library)
userRepository.insert(KomgaUser("user@example.org", "", false, id = "1"))
userRepository.insert(KomgaUser("user@example.org", "", id = "1"))
}
@AfterAll
@ -724,7 +723,7 @@ class SeriesControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when getting series then url is available`() {
val createdSeries =
makeSeries(name = "series", libraryId = library.id).let { series ->
@ -784,7 +783,7 @@ class SeriesControllerTest(
"""{"language":"japanese"}""",
],
)
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given invalid json when updating metadata then raise validation error`(jsonString: String) {
mockMvc
.patch("/api/v1/series/1/metadata") {
@ -796,7 +795,7 @@ class SeriesControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given valid json when updating metadata then fields are updated`() {
val createdSeries =
makeSeries(name = "series", libraryId = library.id).let { series ->
@ -872,7 +871,7 @@ class SeriesControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given json with null fields when updating metadata then fields with null are unset`() {
val createdSeries =
makeSeries(name = "series", libraryId = library.id).let { series ->

View file

@ -1,8 +1,6 @@
package org.gotson.komga.interfaces.api.rest
import org.assertj.core.api.Assertions.assertThat
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ROLE_USER
import org.gotson.komga.domain.model.ThumbnailSize
import org.gotson.komga.infrastructure.configuration.KomgaSettingsProvider
import org.junit.jupiter.api.Nested
@ -38,7 +36,7 @@ class SettingsControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_USER])
@WithMockCustomUser
fun `given restricted user when retrieving settings then returns forbidden`() {
mockMvc
.get("/api/v1/settings")
@ -49,7 +47,7 @@ class SettingsControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when retrieving settings then settings are returned`() {
komgaSettingsProvider.deleteEmptyCollections = true
komgaSettingsProvider.deleteEmptyReadLists = false
@ -78,7 +76,7 @@ class SettingsControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when updating settings then settings are updated`() {
komgaSettingsProvider.deleteEmptyCollections = true
komgaSettingsProvider.deleteEmptyReadLists = true
@ -123,7 +121,7 @@ class SettingsControllerTest(
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `given admin user when deleting settings then deletable settings are deleted`() {
komgaSettingsProvider.deleteEmptyCollections = true
komgaSettingsProvider.deleteEmptyReadLists = true
@ -168,7 +166,7 @@ class SettingsControllerTest(
}
@ParameterizedTest
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
@ValueSource(
strings = [
//language=JSON

View file

@ -5,10 +5,7 @@ import org.gotson.komga.domain.model.AgeRestriction
import org.gotson.komga.domain.model.AllowExclude
import org.gotson.komga.domain.model.ContentRestrictions
import org.gotson.komga.domain.model.KomgaUser
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ROLE_FILE_DOWNLOAD
import org.gotson.komga.domain.model.ROLE_KOBO_SYNC
import org.gotson.komga.domain.model.ROLE_PAGE_STREAMING
import org.gotson.komga.domain.model.UserRoles
import org.gotson.komga.domain.model.makeLibrary
import org.gotson.komga.domain.persistence.KomgaUserRepository
import org.gotson.komga.domain.persistence.LibraryRepository
@ -45,7 +42,7 @@ class UserControllerTest(
@Autowired
private lateinit var userLifecycle: KomgaUserLifecycle
private val admin = KomgaUser("admin@example.org", "", true, id = "admin")
private val admin = KomgaUser("admin@example.org", "", id = "admin")
@BeforeAll
fun setup() {
@ -74,7 +71,7 @@ class UserControllerTest(
@ParameterizedTest
@ValueSource(strings = ["user", "user@domain"])
@WithMockCustomUser(roles = [ROLE_ADMIN])
@WithMockCustomUser(roles = ["ADMIN"])
fun `when creating a user with invalid email then returns bad request`(email: String) {
// language=JSON
val jsonString = """{"email":"$email","password":"password"}"""
@ -91,16 +88,16 @@ class UserControllerTest(
@Nested
inner class Update {
@Test
@WithMockCustomUser(id = "admin", roles = [ROLE_ADMIN])
@WithMockCustomUser(id = "admin", roles = ["ADMIN"])
fun `given user without roles when updating roles then roles are updated`() {
val user = KomgaUser("user@example.org", "", false, id = "user", roleFileDownload = false, rolePageStreaming = false)
val user = KomgaUser("user@example.org", "", id = "user")
userLifecycle.createUser(user)
// language=JSON
val jsonString =
"""
{
"roles": ["$ROLE_FILE_DOWNLOAD","$ROLE_PAGE_STREAMING","$ROLE_KOBO_SYNC"]
"roles": ["${UserRoles.FILE_DOWNLOAD.name}","${UserRoles.PAGE_STREAMING.name}","${UserRoles.KOBO_SYNC.name}"]
}
""".trimIndent()
@ -114,17 +111,14 @@ class UserControllerTest(
with(userRepository.findByIdOrNull(user.id)) {
assertThat(this).isNotNull
assertThat(this!!.roleFileDownload).isTrue
assertThat(this.rolePageStreaming).isTrue
assertThat(this.roleKoboSync).isTrue
assertThat(this.roleAdmin).isFalse
assertThat(this!!.roles).containsExactlyInAnyOrder(UserRoles.KOBO_SYNC, UserRoles.PAGE_STREAMING, UserRoles.FILE_DOWNLOAD)
}
}
@Test
@WithMockCustomUser(id = "admin", roles = [ROLE_ADMIN])
@WithMockCustomUser(id = "admin", roles = ["ADMIN"])
fun `given user with roles when updating roles then roles are updated`() {
val user = KomgaUser("user@example.org", "", true, id = "user", roleFileDownload = true, rolePageStreaming = true)
val user = KomgaUser("user@example.org", "", id = "user")
userLifecycle.createUser(user)
// language=JSON
@ -145,16 +139,14 @@ class UserControllerTest(
with(userRepository.findByIdOrNull(user.id)) {
assertThat(this).isNotNull
assertThat(this!!.roleFileDownload).isFalse
assertThat(this.rolePageStreaming).isFalse
assertThat(this.roleAdmin).isFalse
assertThat(this!!.roles).isEmpty()
}
}
@Test
@WithMockCustomUser(id = "admin", roles = [ROLE_ADMIN])
@WithMockCustomUser(id = "admin", roles = ["ADMIN"])
fun `given user with library restrictions when updating available libraries then they are updated`() {
val user = KomgaUser("user@example.org", "", false, id = "user", sharedAllLibraries = false, sharedLibrariesIds = setOf("1"))
val user = KomgaUser("user@example.org", "", sharedLibrariesIds = setOf("1"), sharedAllLibraries = false, id = "user")
userLifecycle.createUser(user)
// language=JSON
@ -184,9 +176,9 @@ class UserControllerTest(
}
@Test
@WithMockCustomUser(id = "admin", roles = [ROLE_ADMIN])
@WithMockCustomUser(id = "admin", roles = ["ADMIN"])
fun `given user without library restrictions when restricting libraries then they restrictions are updated`() {
val user = KomgaUser("user@example.org", "", false, id = "user", sharedAllLibraries = true)
val user = KomgaUser("user@example.org", "", sharedAllLibraries = true, id = "user")
userLifecycle.createUser(user)
// language=JSON
@ -216,9 +208,9 @@ class UserControllerTest(
}
@Test
@WithMockCustomUser(id = "admin", roles = [ROLE_ADMIN])
@WithMockCustomUser(id = "admin", roles = ["ADMIN"])
fun `given user with library restrictions when removing restrictions then the restrictions are updated`() {
val user = KomgaUser("user@example.org", "", false, id = "user", sharedAllLibraries = false, sharedLibrariesIds = setOf("2"))
val user = KomgaUser("user@example.org", "", sharedLibrariesIds = setOf("2"), sharedAllLibraries = false, id = "user")
userLifecycle.createUser(user)
// language=JSON
@ -248,9 +240,9 @@ class UserControllerTest(
}
@Test
@WithMockCustomUser(id = "admin", roles = [ROLE_ADMIN])
@WithMockCustomUser(id = "admin", roles = ["ADMIN"])
fun `given user without labels restrictions when adding restrictions then restrictions are updated`() {
val user = KomgaUser("user@example.org", "", false, id = "user")
val user = KomgaUser("user@example.org", "", id = "user")
userLifecycle.createUser(user)
// language=JSON
@ -278,19 +270,18 @@ class UserControllerTest(
}
@Test
@WithMockCustomUser(id = "admin", roles = [ROLE_ADMIN])
@WithMockCustomUser(id = "admin", roles = ["ADMIN"])
fun `given user with labels restrictions when removing restrictions then restrictions are updated`() {
val user =
KomgaUser(
"user@example.org",
"",
false,
id = "user",
restrictions =
ContentRestrictions(
labelsAllow = setOf("kids", "cute"),
labelsExclude = setOf("adult"),
),
id = "user",
)
userLifecycle.createUser(user)
@ -319,9 +310,9 @@ class UserControllerTest(
}
@Test
@WithMockCustomUser(id = "admin", roles = [ROLE_ADMIN])
@WithMockCustomUser(id = "admin", roles = ["ADMIN"])
fun `given user without age restriction when adding restrictions then restrictions are updated`() {
val user = KomgaUser("user@example.org", "", false, id = "user")
val user = KomgaUser("user@example.org", "", id = "user")
userLifecycle.createUser(user)
// language=JSON
@ -352,9 +343,9 @@ class UserControllerTest(
}
@Test
@WithMockCustomUser(id = "admin", roles = [ROLE_ADMIN])
@WithMockCustomUser(id = "admin", roles = ["ADMIN"])
fun `given user without age restriction when adding incorrect restrictions then bad request`() {
val user = KomgaUser("user@example.org", "", false, id = "user")
val user = KomgaUser("user@example.org", "", id = "user")
userLifecycle.createUser(user)
// language=JSON
@ -378,18 +369,17 @@ class UserControllerTest(
}
@Test
@WithMockCustomUser(id = "admin", roles = [ROLE_ADMIN])
@WithMockCustomUser(id = "admin", roles = ["ADMIN"])
fun `given user with age restriction when removing restriction then restrictions are updated`() {
val user =
KomgaUser(
"user@example.org",
"",
false,
id = "user",
restrictions =
ContentRestrictions(
ageRestriction = AgeRestriction(12, AllowExclude.ALLOW_ONLY),
),
id = "user",
)
userLifecycle.createUser(user)
@ -416,18 +406,17 @@ class UserControllerTest(
}
@Test
@WithMockCustomUser(id = "admin", roles = [ROLE_ADMIN])
@WithMockCustomUser(id = "admin", roles = ["ADMIN"])
fun `given user with age restriction when changing restriction then restrictions are updated`() {
val user =
KomgaUser(
"user@example.org",
"",
false,
id = "user",
restrictions =
ContentRestrictions(
ageRestriction = AgeRestriction(12, AllowExclude.ALLOW_ONLY),
),
id = "user",
)
userLifecycle.createUser(user)