mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-17 08:15:44 +00:00
Implement dynamic config management
Start implementation of library management
This commit is contained in:
@@ -2,9 +2,11 @@ package de.grimsi.gameyfin
|
|||||||
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
import org.springframework.boot.runApplication
|
import org.springframework.boot.runApplication
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement
|
||||||
|
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
|
@EnableTransactionManagement
|
||||||
class GameyfinApplication
|
class GameyfinApplication
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package de.grimsi.gameyfin.config
|
||||||
|
|
||||||
|
import com.vaadin.hilla.Endpoint
|
||||||
|
import de.grimsi.gameyfin.meta.Roles
|
||||||
|
import jakarta.annotation.security.RolesAllowed
|
||||||
|
|
||||||
|
@Endpoint
|
||||||
|
@RolesAllowed(Roles.Names.SUPERADMIN, Roles.Names.ADMIN)
|
||||||
|
class ConfigController(
|
||||||
|
private val appConfigService: ConfigService
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun getConfig(key: String): String {
|
||||||
|
return appConfigService.getConfigValue(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setConfig(config: Pair<String, String>) {
|
||||||
|
appConfigService.setConfigValue(config.first, config.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resetConfig(key: String) {
|
||||||
|
appConfigService.resetConfigValue(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteConfig(key: String) {
|
||||||
|
appConfigService.deleteConfig(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package de.grimsi.gameyfin.config
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
sealed class ConfigProperty<T : Serializable>(val type: KClass<T>, val key: String, val default: T? = null) {
|
||||||
|
|
||||||
|
/** Libraries */
|
||||||
|
// Allow access to game libraries without login
|
||||||
|
data object LibraryAllowPublicAccess :
|
||||||
|
ConfigProperty<Boolean>(Boolean::class, "library.allow-public-access", false)
|
||||||
|
|
||||||
|
// Enable automatic library scanning using file system watchers
|
||||||
|
data object LibraryEnableFilesystemWatcher :
|
||||||
|
ConfigProperty<Boolean>(Boolean::class, "library.scan.enable-filesystem-watcher", true)
|
||||||
|
|
||||||
|
// Enable periodic refresh of video game meta-data and set the schedule (default is once per week)
|
||||||
|
data object LibraryMetadataUpdateEnabled :
|
||||||
|
ConfigProperty<Boolean>(Boolean::class, "library.metadata.update.enabled", true)
|
||||||
|
|
||||||
|
data object LibraryMetadataUpdateSchedule :
|
||||||
|
ConfigProperty<String>(String::class, "library.metadata.update.schedule", "0 0 * * 0")
|
||||||
|
|
||||||
|
/** User management */
|
||||||
|
// Allow new users to sign up by themselves
|
||||||
|
data object UsersAllowNewSignUps : ConfigProperty<Boolean>(Boolean::class, "users.sign-ups.allow", false)
|
||||||
|
|
||||||
|
// If an administrator needs to confirm new sign-ups before they are allowed to log in
|
||||||
|
data object UsersConfirmNewSignUps :
|
||||||
|
ConfigProperty<Boolean>(Boolean::class, "users.sign-ups.confirm", false)
|
||||||
|
|
||||||
|
/** Notifications */
|
||||||
|
// Settings for the mail server used by Gameyfin to send notifications
|
||||||
|
data object NotificationsEmailHost : ConfigProperty<String>(String::class, "notifications.email.host")
|
||||||
|
data object NotificationsEmailPort : ConfigProperty<String>(String::class, "notifications.email.port")
|
||||||
|
data object NotificationsEmailUsername : ConfigProperty<String>(String::class, "notifications.email.username")
|
||||||
|
data object NotificationsEmailPassword : ConfigProperty<String>(String::class, "notifications.email.password")
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
package de.grimsi.gameyfin.config
|
||||||
|
|
||||||
|
import de.grimsi.gameyfin.config.entities.ConfigEntry
|
||||||
|
import de.grimsi.gameyfin.config.persistence.ConfigRepository
|
||||||
|
import jakarta.transaction.Transactional
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import java.io.Serializable
|
||||||
|
import kotlin.reflect.safeCast
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional
|
||||||
|
class ConfigService(
|
||||||
|
private val appConfigRepository: ConfigRepository
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current value of a config property in a type-safe way.
|
||||||
|
* Used internally.
|
||||||
|
*
|
||||||
|
* @param configProperty: The config property containing necessary type information
|
||||||
|
* @return The current value if set or the default value
|
||||||
|
* @throws IllegalArgumentException if no value is set and no default value exists
|
||||||
|
*/
|
||||||
|
fun <T : Serializable> getConfigValue(configProperty: ConfigProperty<T>): T {
|
||||||
|
val appConfig = appConfigRepository.findById(configProperty.key).orElse(null)
|
||||||
|
return if (appConfig != null) {
|
||||||
|
getValue(appConfig.value, configProperty)
|
||||||
|
} else {
|
||||||
|
configProperty.default ?: throw IllegalArgumentException("No value found for key: ${configProperty.key}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current value of a config property in a *not* type-safe way.
|
||||||
|
* Used for the external API.
|
||||||
|
*
|
||||||
|
* @param key: The key of the config property
|
||||||
|
* @return The current value if set or the default value
|
||||||
|
* @throws IllegalArgumentException if no value is set and no default value exists
|
||||||
|
*/
|
||||||
|
fun getConfigValue(key: String): String {
|
||||||
|
val configProperty = findConfigProperty(key)
|
||||||
|
val appConfig = appConfigRepository.findById(configProperty.key).orElse(null)
|
||||||
|
|
||||||
|
return if (appConfig != null) {
|
||||||
|
getValue(appConfig.value, configProperty).toString()
|
||||||
|
} else {
|
||||||
|
configProperty.default?.toString()
|
||||||
|
?: throw IllegalArgumentException("No value found for key: ${configProperty.key}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value for a specified key.
|
||||||
|
* Checks if the value can be cast to the type defined for the config property.
|
||||||
|
*
|
||||||
|
* @param key: Key of the target config property
|
||||||
|
* @param value: Value to set the config property to
|
||||||
|
* @throws IllegalArgumentException if the value can't be cast to the type defined for the config property
|
||||||
|
*/
|
||||||
|
fun <T : Serializable> setConfigValue(key: String, value: T) {
|
||||||
|
val configKey = findConfigProperty(key)
|
||||||
|
|
||||||
|
if (configKey.type.safeCast(value) == null) {
|
||||||
|
throw IllegalArgumentException("Type mismatch for key: ${configKey.key}")
|
||||||
|
}
|
||||||
|
|
||||||
|
val appConfig = ConfigEntry(configKey.key, value.toString())
|
||||||
|
appConfigRepository.save(appConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset a given config property to its default value if it has a default value.
|
||||||
|
* Otherwise, delete the config key from the database.
|
||||||
|
*
|
||||||
|
* @param key: Key of the config property
|
||||||
|
*/
|
||||||
|
fun resetConfigValue(key: String) {
|
||||||
|
val configKey = findConfigProperty(key)
|
||||||
|
|
||||||
|
if (configKey.default == null) {
|
||||||
|
deleteConfig(key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val appConfig = appConfigRepository.findById(configKey.key).orElse(null)
|
||||||
|
if (appConfig != null) {
|
||||||
|
appConfig.value = configKey.default.toString()
|
||||||
|
appConfigRepository.save(appConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a config property from the database
|
||||||
|
*
|
||||||
|
* @param key: Key of the config property
|
||||||
|
*/
|
||||||
|
fun deleteConfig(key: String) {
|
||||||
|
val configKey = findConfigProperty(key)
|
||||||
|
appConfigRepository.deleteById(configKey.key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of the config property in a type-safe way.
|
||||||
|
*/
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private fun <T : Serializable> getValue(value: String, configProperty: ConfigProperty<T>): T {
|
||||||
|
return when (configProperty.type) {
|
||||||
|
String::class -> value as T
|
||||||
|
Boolean::class -> value.toBoolean() as T
|
||||||
|
Number::class -> value.toInt() as T
|
||||||
|
Float::class -> value.toFloat() as T
|
||||||
|
else -> {
|
||||||
|
throw RuntimeException("Unknown config type ${configProperty.type}: '$value' for key ${configProperty.key}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a config property
|
||||||
|
*/
|
||||||
|
private fun findConfigProperty(key: String): ConfigProperty<*> {
|
||||||
|
// Use reflection to get all objects defined within ConfigKey
|
||||||
|
val configProperties = ConfigProperty::class.sealedSubclasses.flatMap { subclass ->
|
||||||
|
subclass.objectInstance?.let { listOf(it) } ?: listOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the matching config key based on the string key
|
||||||
|
return configProperties.find { it.key == key }
|
||||||
|
?: throw IllegalArgumentException("Unknown configuration key: $key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package de.grimsi.gameyfin.config.entities
|
||||||
|
|
||||||
|
import jakarta.persistence.Column
|
||||||
|
import jakarta.persistence.Entity
|
||||||
|
import jakarta.persistence.Id
|
||||||
|
import jakarta.persistence.Table
|
||||||
|
import jakarta.validation.constraints.NotNull
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "app_config")
|
||||||
|
class ConfigEntry(
|
||||||
|
@Id
|
||||||
|
@NotNull
|
||||||
|
@Column(unique = true)
|
||||||
|
val key: String,
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
var value: String
|
||||||
|
)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package de.grimsi.gameyfin.config.persistence
|
||||||
|
|
||||||
|
import de.grimsi.gameyfin.config.entities.ConfigEntry
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
|
||||||
|
interface ConfigRepository : JpaRepository<ConfigEntry, String>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package de.grimsi.gameyfin.libraries
|
||||||
|
|
||||||
|
import com.vaadin.hilla.Endpoint
|
||||||
|
import de.grimsi.gameyfin.libraries.entities.Library
|
||||||
|
import de.grimsi.gameyfin.meta.Roles
|
||||||
|
import jakarta.annotation.security.RolesAllowed
|
||||||
|
|
||||||
|
@Endpoint
|
||||||
|
class LibraryEndpoint(
|
||||||
|
private val libraryService: LibraryService
|
||||||
|
) {
|
||||||
|
@RolesAllowed(Roles.Names.SUPERADMIN, Roles.Names.ADMIN)
|
||||||
|
fun getAllLibraries(): Collection<Library> {
|
||||||
|
return libraryService.getAllLibraries()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package de.grimsi.gameyfin.libraries
|
||||||
|
|
||||||
|
import de.grimsi.gameyfin.libraries.entities.Library
|
||||||
|
import de.grimsi.gameyfin.libraries.persistence.LibraryRepository
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class LibraryService(
|
||||||
|
private val libraryRepository: LibraryRepository
|
||||||
|
) {
|
||||||
|
fun createLibrary(library: Library): Library {
|
||||||
|
return libraryRepository.save(library)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAllLibraries(): Collection<Library> {
|
||||||
|
return libraryRepository.findAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteLibrary(library: Library) {
|
||||||
|
libraryRepository.delete(library)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateLibrary(library: Library) {
|
||||||
|
libraryRepository.save(library)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package de.grimsi.gameyfin.libraries.entities
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity
|
||||||
|
import jakarta.persistence.GeneratedValue
|
||||||
|
import jakarta.persistence.GenerationType
|
||||||
|
import jakarta.persistence.Id
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
class Library(
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
var id: Long? = null,
|
||||||
|
|
||||||
|
var path: String
|
||||||
|
)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package de.grimsi.gameyfin.libraries.persistence
|
||||||
|
|
||||||
|
import de.grimsi.gameyfin.libraries.entities.Library
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
|
||||||
|
interface LibraryRepository : JpaRepository<Library, Long>
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package de.grimsi.gameyfin.config
|
package de.grimsi.gameyfin.meta
|
||||||
|
|
||||||
enum class Roles(val roleName: String) {
|
enum class Roles(val roleName: String) {
|
||||||
SUPERADMIN(Names.SUPERADMIN),
|
SUPERADMIN(Names.SUPERADMIN),
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package de.grimsi.gameyfin.config
|
package de.grimsi.gameyfin.meta
|
||||||
|
|
||||||
import com.vaadin.flow.spring.security.VaadinWebSecurity
|
import com.vaadin.flow.spring.security.VaadinWebSecurity
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package de.grimsi.gameyfin.meta
|
||||||
|
|
||||||
|
import de.grimsi.gameyfin.meta.annotations.DynamicAccessInterceptor
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
class WebConfig(val dynamicAccessInterceptor: DynamicAccessInterceptor) : WebMvcConfigurer {
|
||||||
|
|
||||||
|
override fun addInterceptors(registry: InterceptorRegistry) {
|
||||||
|
registry.addInterceptor(dynamicAccessInterceptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package de.grimsi.gameyfin.meta.annotations
|
||||||
|
|
||||||
|
import de.grimsi.gameyfin.config.ConfigProperty
|
||||||
|
import de.grimsi.gameyfin.config.ConfigService
|
||||||
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
|
import jakarta.servlet.http.HttpServletResponse
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import org.springframework.web.method.HandlerMethod
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class DynamicAccessInterceptor(
|
||||||
|
private val configService: ConfigService
|
||||||
|
) : HandlerInterceptor {
|
||||||
|
|
||||||
|
override fun preHandle(
|
||||||
|
request: HttpServletRequest,
|
||||||
|
response: HttpServletResponse,
|
||||||
|
handler: Any
|
||||||
|
): Boolean {
|
||||||
|
val handlerMethod = (handler as? HandlerMethod) ?: return true
|
||||||
|
val method = handlerMethod.method
|
||||||
|
|
||||||
|
// Check if method is annotated with @DynamicPublicAccess
|
||||||
|
if (method.isAnnotationPresent(DynamicPublicAccess::class.java)) {
|
||||||
|
// Check if user is authenticated or public access is enabled
|
||||||
|
if (request.userPrincipal != null || configService.getConfigValue(ConfigProperty.LibraryAllowPublicAccess)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deny access if user is not logged in and public access is disabled
|
||||||
|
response.status = HttpServletResponse.SC_UNAUTHORIZED
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package de.grimsi.gameyfin.meta.annotations
|
||||||
|
|
||||||
|
import kotlin.annotation.AnnotationRetention.RUNTIME
|
||||||
|
import kotlin.annotation.AnnotationTarget.FUNCTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This annotation is used on endpoint methods which can be switched between publicly accessible and
|
||||||
|
* only accessible for registered users.
|
||||||
|
* One example would be the main library view.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Target(FUNCTION)
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
annotation class DynamicPublicAccess
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package de.grimsi.gameyfin.setup
|
package de.grimsi.gameyfin.setup
|
||||||
|
|
||||||
import de.grimsi.gameyfin.config.Roles
|
import de.grimsi.gameyfin.meta.Roles
|
||||||
import de.grimsi.gameyfin.users.UserService
|
import de.grimsi.gameyfin.users.UserService
|
||||||
import de.grimsi.gameyfin.users.entities.Role
|
import de.grimsi.gameyfin.users.entities.Role
|
||||||
import de.grimsi.gameyfin.users.entities.User
|
import de.grimsi.gameyfin.users.entities.User
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package de.grimsi.gameyfin.setup
|
package de.grimsi.gameyfin.setup
|
||||||
|
|
||||||
import com.vaadin.flow.server.auth.AnonymousAllowed
|
import com.vaadin.flow.server.auth.AnonymousAllowed
|
||||||
import de.grimsi.gameyfin.config.Roles
|
|
||||||
import de.grimsi.gameyfin.users.RoleService
|
|
||||||
import de.grimsi.gameyfin.users.UserService
|
|
||||||
import de.grimsi.gameyfin.users.dto.UserInfo
|
|
||||||
import de.grimsi.gameyfin.users.dto.UserRegistration
|
|
||||||
import de.grimsi.gameyfin.users.entities.User
|
|
||||||
import com.vaadin.hilla.Endpoint
|
import com.vaadin.hilla.Endpoint
|
||||||
import com.vaadin.hilla.exception.EndpointException
|
import com.vaadin.hilla.exception.EndpointException
|
||||||
|
import de.grimsi.gameyfin.meta.Roles
|
||||||
|
import de.grimsi.gameyfin.users.RoleService
|
||||||
|
import de.grimsi.gameyfin.users.UserService
|
||||||
|
import de.grimsi.gameyfin.users.dto.UserInfoDto
|
||||||
|
import de.grimsi.gameyfin.users.dto.UserRegistrationDto
|
||||||
|
import de.grimsi.gameyfin.users.entities.User
|
||||||
|
|
||||||
@Endpoint
|
@Endpoint
|
||||||
class SetupEndpoint(
|
class SetupEndpoint(
|
||||||
@@ -22,7 +22,7 @@ class SetupEndpoint(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AnonymousAllowed
|
@AnonymousAllowed
|
||||||
fun registerSuperAdmin(superAdminRegistration: UserRegistration): UserInfo {
|
fun registerSuperAdmin(superAdminRegistration: UserRegistrationDto): UserInfoDto {
|
||||||
if (setupService.isSetupCompleted()) throw EndpointException("Setup already completed")
|
if (setupService.isSetupCompleted()) throw EndpointException("Setup already completed")
|
||||||
|
|
||||||
val user = User(
|
val user = User(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package de.grimsi.gameyfin.setup
|
package de.grimsi.gameyfin.setup
|
||||||
|
|
||||||
import de.grimsi.gameyfin.config.Roles
|
import de.grimsi.gameyfin.meta.Roles
|
||||||
import de.grimsi.gameyfin.users.RoleService
|
import de.grimsi.gameyfin.users.RoleService
|
||||||
import de.grimsi.gameyfin.users.UserService
|
import de.grimsi.gameyfin.users.UserService
|
||||||
import de.grimsi.gameyfin.users.entities.User
|
import de.grimsi.gameyfin.users.entities.User
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package de.grimsi.gameyfin.system
|
package de.grimsi.gameyfin.system
|
||||||
|
|
||||||
import de.grimsi.gameyfin.config.Roles
|
|
||||||
import com.vaadin.hilla.Endpoint
|
import com.vaadin.hilla.Endpoint
|
||||||
|
import de.grimsi.gameyfin.meta.Roles
|
||||||
import jakarta.annotation.security.RolesAllowed
|
import jakarta.annotation.security.RolesAllowed
|
||||||
|
|
||||||
@Endpoint
|
@Endpoint
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package de.grimsi.gameyfin.users
|
package de.grimsi.gameyfin.users
|
||||||
|
|
||||||
import de.grimsi.gameyfin.config.Roles
|
import de.grimsi.gameyfin.meta.Roles
|
||||||
import de.grimsi.gameyfin.users.entities.Role
|
import de.grimsi.gameyfin.users.entities.Role
|
||||||
import de.grimsi.gameyfin.users.persistence.RoleRepository
|
import de.grimsi.gameyfin.users.persistence.RoleRepository
|
||||||
import jakarta.transaction.Transactional
|
import jakarta.transaction.Transactional
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package de.grimsi.gameyfin.users
|
package de.grimsi.gameyfin.users
|
||||||
|
|
||||||
import de.grimsi.gameyfin.config.Roles
|
|
||||||
import de.grimsi.gameyfin.users.dto.UserInfo
|
|
||||||
import de.grimsi.gameyfin.users.dto.UserRegistration
|
|
||||||
import de.grimsi.gameyfin.users.entities.User
|
|
||||||
import com.vaadin.hilla.Endpoint
|
import com.vaadin.hilla.Endpoint
|
||||||
|
import de.grimsi.gameyfin.meta.Roles
|
||||||
|
import de.grimsi.gameyfin.users.dto.UserInfoDto
|
||||||
|
import de.grimsi.gameyfin.users.dto.UserRegistrationDto
|
||||||
|
import de.grimsi.gameyfin.users.entities.User
|
||||||
import jakarta.annotation.security.PermitAll
|
import jakarta.annotation.security.PermitAll
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
import org.springframework.security.core.GrantedAuthority
|
import org.springframework.security.core.GrantedAuthority
|
||||||
@@ -16,19 +16,19 @@ class UserEndpoint(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
fun getUserInfo(): UserInfo {
|
fun getUserInfo(): UserInfoDto {
|
||||||
val auth: Authentication = SecurityContextHolder.getContext().authentication
|
val auth: Authentication = SecurityContextHolder.getContext().authentication
|
||||||
val authorities: List<String> = auth.authorities.map { g: GrantedAuthority -> g.authority }
|
val authorities: List<String> = auth.authorities.map { g: GrantedAuthority -> g.authority }
|
||||||
return UserInfo(username = auth.name, roles = authorities)
|
return UserInfoDto(username = auth.name, roles = authorities)
|
||||||
}
|
}
|
||||||
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
fun registerUser(registration: UserRegistration): UserInfo {
|
fun registerUser(registration: UserRegistrationDto): UserInfoDto {
|
||||||
val user: User = registerUser(registration, listOf(Roles.USER))
|
val user: User = registerUser(registration, listOf(Roles.USER))
|
||||||
return userService.toUserInfo(user)
|
return userService.toUserInfo(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerUser(registration: UserRegistration, roles: List<Roles>): User {
|
private fun registerUser(registration: UserRegistrationDto, roles: List<Roles>): User {
|
||||||
val user = User(
|
val user = User(
|
||||||
username = registration.username,
|
username = registration.username,
|
||||||
password = registration.password,
|
password = registration.password,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package de.grimsi.gameyfin.users
|
package de.grimsi.gameyfin.users
|
||||||
|
|
||||||
import de.grimsi.gameyfin.config.Roles
|
import de.grimsi.gameyfin.meta.Roles
|
||||||
import de.grimsi.gameyfin.users.dto.UserInfo
|
import de.grimsi.gameyfin.users.dto.UserInfoDto
|
||||||
import de.grimsi.gameyfin.users.entities.Role
|
import de.grimsi.gameyfin.users.entities.Role
|
||||||
import de.grimsi.gameyfin.users.entities.User
|
import de.grimsi.gameyfin.users.entities.User
|
||||||
import de.grimsi.gameyfin.users.persistence.UserRepository
|
import de.grimsi.gameyfin.users.persistence.UserRepository
|
||||||
@@ -50,8 +50,8 @@ class UserService(
|
|||||||
return userRepository.save(user)
|
return userRepository.save(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toUserInfo(user: User): UserInfo {
|
fun toUserInfo(user: User): UserInfoDto {
|
||||||
return UserInfo(
|
return UserInfoDto(
|
||||||
username = user.username,
|
username = user.username,
|
||||||
email = user.email,
|
email = user.email,
|
||||||
roles = user.roles.map { r -> r.rolename }
|
roles = user.roles.map { r -> r.rolename }
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package de.grimsi.gameyfin.users.dto
|
package de.grimsi.gameyfin.users.dto
|
||||||
|
|
||||||
data class UserInfo(
|
data class UserInfoDto(
|
||||||
val username: String,
|
val username: String,
|
||||||
val email: String? = null,
|
val email: String? = null,
|
||||||
val roles: List<String>
|
val roles: List<String>
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package de.grimsi.gameyfin.users.dto
|
package de.grimsi.gameyfin.users.dto
|
||||||
|
|
||||||
data class UserRegistration(
|
data class UserRegistrationDto(
|
||||||
val username: String,
|
val username: String,
|
||||||
val password: String,
|
val password: String,
|
||||||
val email: String
|
val email: String
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
package de.grimsi.gameyfin.users.util
|
package de.grimsi.gameyfin.users.util
|
||||||
|
|
||||||
import de.grimsi.gameyfin.config.Roles
|
import de.grimsi.gameyfin.meta.Roles
|
||||||
import org.springframework.security.core.userdetails.UserDetails
|
import org.springframework.security.core.userdetails.UserDetails
|
||||||
|
|
||||||
fun UserDetails.hasRole(role: Roles): Boolean {
|
fun UserDetails.hasRole(role: Roles): Boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user