mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-13 16:40:01 +00:00
BE implementation of request system
This commit is contained in:
+1
-1
@@ -265,4 +265,4 @@
|
||||
"disableUsageStatistics": true,
|
||||
"hash": "962eccc3fa0735d5234901be4f9e384096113c45bec22564a53688096d62aef4"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
package org.gameyfin.app.core.filesystem
|
||||
|
||||
import org.gameyfin.app.config.ConfigService
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.apache.commons.io.FilenameUtils
|
||||
import org.gameyfin.app.config.ConfigProperties
|
||||
import org.gameyfin.app.libraries.Library
|
||||
import org.gameyfin.app.config.ConfigService
|
||||
import org.gameyfin.app.libraries.entities.Library
|
||||
import org.springframework.stereotype.Service
|
||||
import java.io.File
|
||||
import java.nio.file.FileSystems
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.gameyfin.app.games.dto.*
|
||||
import org.gameyfin.app.games.entities.*
|
||||
import org.gameyfin.app.games.extensions.toDtos
|
||||
import org.gameyfin.app.games.repositories.GameRepository
|
||||
import org.gameyfin.app.libraries.Library
|
||||
import org.gameyfin.app.libraries.entities.Library
|
||||
import org.gameyfin.app.media.ImageService
|
||||
import org.gameyfin.app.users.UserService
|
||||
import org.gameyfin.pluginapi.gamemetadata.*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.gameyfin.app.games.entities
|
||||
|
||||
import jakarta.persistence.*
|
||||
import org.gameyfin.app.libraries.Library
|
||||
import org.gameyfin.app.libraries.entities.Library
|
||||
import org.gameyfin.pluginapi.gamemetadata.GameFeature
|
||||
import org.gameyfin.pluginapi.gamemetadata.Genre
|
||||
import org.gameyfin.pluginapi.gamemetadata.PlayerPerspective
|
||||
|
||||
@@ -12,19 +12,19 @@ import org.gameyfin.app.games.extensions.toUserDto
|
||||
class GameEntityListener {
|
||||
@PostPersist
|
||||
fun created(game: Game) {
|
||||
GameService.Companion.emitUser(GameUserEvent.Created(game.toUserDto()))
|
||||
GameService.Companion.emitAdmin(GameAdminEvent.Created(game.toAdminDto()))
|
||||
GameService.emitUser(GameUserEvent.Created(game.toUserDto()))
|
||||
GameService.emitAdmin(GameAdminEvent.Created(game.toAdminDto()))
|
||||
}
|
||||
|
||||
@PostUpdate
|
||||
fun updated(game: Game) {
|
||||
GameService.Companion.emitUser(GameUserEvent.Updated(game.toUserDto()))
|
||||
GameService.Companion.emitAdmin(GameAdminEvent.Updated(game.toAdminDto()))
|
||||
GameService.emitUser(GameUserEvent.Updated(game.toUserDto()))
|
||||
GameService.emitAdmin(GameAdminEvent.Updated(game.toAdminDto()))
|
||||
}
|
||||
|
||||
@PostRemove
|
||||
fun deleted(game: Game) {
|
||||
GameService.Companion.emitUser(GameUserEvent.Deleted(game.id!!))
|
||||
GameService.Companion.emitAdmin(GameAdminEvent.Deleted(game.id!!))
|
||||
GameService.emitUser(GameUserEvent.Deleted(game.id!!))
|
||||
GameService.emitAdmin(GameAdminEvent.Deleted(game.id!!))
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package org.gameyfin.app.libraries
|
||||
|
||||
import org.gameyfin.app.games.GameService
|
||||
import org.gameyfin.app.games.entities.Game
|
||||
import org.gameyfin.app.libraries.entities.Library
|
||||
import org.springframework.stereotype.Service
|
||||
import java.time.Instant
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.gameyfin.app.libraries
|
||||
|
||||
import org.gameyfin.app.libraries.entities.Library
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
import org.springframework.data.jpa.repository.Query
|
||||
|
||||
|
||||
@@ -4,9 +4,8 @@ import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.gameyfin.app.core.filesystem.FilesystemService
|
||||
import org.gameyfin.app.games.GameService
|
||||
import org.gameyfin.app.games.entities.Game
|
||||
import org.gameyfin.app.libraries.dto.LibraryScanProgress
|
||||
import org.gameyfin.app.libraries.dto.LibraryScanStatus
|
||||
import org.gameyfin.app.libraries.dto.LibraryScanStep
|
||||
import org.gameyfin.app.libraries.dto.*
|
||||
import org.gameyfin.app.libraries.entities.Library
|
||||
import org.gameyfin.app.libraries.enums.ScanType
|
||||
import org.gameyfin.app.libraries.scan.*
|
||||
import org.gameyfin.app.media.ImageService
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.gameyfin.app.libraries
|
||||
import com.vaadin.hilla.exception.EndpointException
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.gameyfin.app.libraries.dto.*
|
||||
import org.gameyfin.app.libraries.entities.DirectoryMapping
|
||||
import org.gameyfin.app.libraries.entities.Library
|
||||
import org.gameyfin.app.libraries.enums.ScanType
|
||||
import org.gameyfin.app.libraries.extensions.toDtos
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.gameyfin.app.libraries.dto
|
||||
|
||||
import org.gameyfin.app.libraries.LibraryScanResult
|
||||
import org.gameyfin.app.libraries.enums.ScanType
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.gameyfin.app.libraries
|
||||
package org.gameyfin.app.libraries.dto
|
||||
|
||||
interface LibraryScanResult {
|
||||
/**
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.gameyfin.app.libraries
|
||||
package org.gameyfin.app.libraries.entities
|
||||
|
||||
import jakarta.persistence.*
|
||||
|
||||
+2
-3
@@ -1,8 +1,7 @@
|
||||
package org.gameyfin.app.libraries
|
||||
package org.gameyfin.app.libraries.entities
|
||||
|
||||
import org.gameyfin.app.games.entities.Game
|
||||
import jakarta.persistence.*
|
||||
import org.gameyfin.app.games.entities.LibraryEntityListener
|
||||
import org.gameyfin.app.games.entities.Game
|
||||
import org.hibernate.annotations.CreationTimestamp
|
||||
import org.hibernate.annotations.UpdateTimestamp
|
||||
import java.time.Instant
|
||||
+1
-2
@@ -1,9 +1,8 @@
|
||||
package org.gameyfin.app.games.entities
|
||||
package org.gameyfin.app.libraries.entities
|
||||
|
||||
import jakarta.persistence.PostPersist
|
||||
import jakarta.persistence.PostRemove
|
||||
import jakarta.persistence.PostUpdate
|
||||
import org.gameyfin.app.libraries.Library
|
||||
import org.gameyfin.app.libraries.LibraryService
|
||||
import org.gameyfin.app.libraries.dto.LibraryAdminEvent
|
||||
import org.gameyfin.app.libraries.dto.LibraryUserEvent
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.gameyfin.app.libraries.extensions
|
||||
|
||||
import org.gameyfin.app.core.security.isCurrentUserAdmin
|
||||
import org.gameyfin.app.libraries.Library
|
||||
import org.gameyfin.app.libraries.dto.*
|
||||
import org.gameyfin.app.libraries.entities.Library
|
||||
|
||||
|
||||
fun Library.toDto(): LibraryDto {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.gameyfin.app.requests
|
||||
|
||||
import com.vaadin.flow.server.auth.AnonymousAllowed
|
||||
import com.vaadin.hilla.Endpoint
|
||||
import jakarta.annotation.security.PermitAll
|
||||
import jakarta.annotation.security.RolesAllowed
|
||||
import org.gameyfin.app.core.Role
|
||||
import org.gameyfin.app.core.annotations.DynamicPublicAccess
|
||||
import org.gameyfin.app.requests.dto.GameRequestCreationDto
|
||||
import org.gameyfin.app.requests.dto.GameRequestEvent
|
||||
import org.gameyfin.app.requests.status.GameRequestStatus
|
||||
import org.springframework.stereotype.Service
|
||||
import reactor.core.publisher.Flux
|
||||
|
||||
@Endpoint
|
||||
@Service
|
||||
@DynamicPublicAccess
|
||||
@AnonymousAllowed
|
||||
class GameRequestEndpoint(
|
||||
private val gameRequestService: GameRequestService
|
||||
) {
|
||||
|
||||
fun subscribe(): Flux<List<GameRequestEvent>> {
|
||||
return GameRequestService.subscribe()
|
||||
}
|
||||
|
||||
fun getAll() = gameRequestService.getAll()
|
||||
|
||||
fun create(gameRequest: GameRequestCreationDto) {
|
||||
gameRequestService.createRequest(gameRequest)
|
||||
}
|
||||
|
||||
@PermitAll
|
||||
fun toggleVote(gameRequestId: Long) {
|
||||
gameRequestService.toggleRequestVote(gameRequestId)
|
||||
}
|
||||
|
||||
@RolesAllowed(Role.Names.ADMIN)
|
||||
fun changeStatus(gameRequestId: Long, newStatus: GameRequestStatus) {
|
||||
gameRequestService.changeRequestStatus(gameRequestId, newStatus)
|
||||
}
|
||||
|
||||
@RolesAllowed(Role.Names.ADMIN)
|
||||
fun delete(gameRequestId: Long) {
|
||||
gameRequestService.deleteRequest(gameRequestId)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.gameyfin.app.requests
|
||||
|
||||
import org.gameyfin.app.requests.entities.GameRequest
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
|
||||
interface GameRequestRepository : JpaRepository<GameRequest, Long>
|
||||
@@ -2,8 +2,11 @@ package org.gameyfin.app.requests
|
||||
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.gameyfin.app.core.security.getCurrentAuth
|
||||
import org.gameyfin.app.games.dto.GameUserEvent
|
||||
import org.gameyfin.app.requests.dto.GameRequestCreationDto
|
||||
import org.gameyfin.app.requests.dto.GameRequestDto
|
||||
import org.gameyfin.app.requests.dto.GameRequestEvent
|
||||
import org.gameyfin.app.requests.entities.GameRequest
|
||||
import org.gameyfin.app.requests.extensions.toDtos
|
||||
import org.gameyfin.app.requests.status.GameRequestStatus
|
||||
import org.gameyfin.app.users.UserService
|
||||
import org.springframework.stereotype.Service
|
||||
@@ -22,9 +25,9 @@ class GameRequestService(
|
||||
private val log = KotlinLogging.logger {}
|
||||
|
||||
/* Websockets */
|
||||
private val gameRequestEvents = Sinks.many().multicast().onBackpressureBuffer<GameUserEvent>(1024, false)
|
||||
private val gameRequestEvents = Sinks.many().multicast().onBackpressureBuffer<GameRequestEvent>(1024, false)
|
||||
|
||||
fun subscribe(): Flux<List<GameUserEvent>> {
|
||||
fun subscribe(): Flux<List<GameRequestEvent>> {
|
||||
log.debug { "New user subscription for gameRequestEvents" }
|
||||
return gameRequestEvents.asFlux()
|
||||
.buffer(100.milliseconds.toJavaDuration())
|
||||
@@ -36,11 +39,16 @@ class GameRequestService(
|
||||
}
|
||||
}
|
||||
|
||||
fun emit(event: GameUserEvent) {
|
||||
fun emit(event: GameRequestEvent) {
|
||||
gameRequestEvents.tryEmitNext(event)
|
||||
}
|
||||
}
|
||||
|
||||
fun getAll(): List<GameRequestDto> {
|
||||
val entities = gameRequestRepository.findAll()
|
||||
return entities.toDtos()
|
||||
}
|
||||
|
||||
fun createRequest(gameRequest: GameRequestCreationDto) {
|
||||
val currentUser = userService.getByUsername(getCurrentAuth().name)
|
||||
|
||||
@@ -54,4 +62,36 @@ class GameRequestService(
|
||||
|
||||
gameRequestRepository.save(gameRequest)
|
||||
}
|
||||
|
||||
fun deleteRequest(id: Long) {
|
||||
val gameRequest = gameRequestRepository.findById(id)
|
||||
.orElseThrow { NoSuchElementException("No game request found with id $id") }
|
||||
gameRequestRepository.delete(gameRequest)
|
||||
}
|
||||
|
||||
fun changeRequestStatus(id: Long, status: GameRequestStatus) {
|
||||
val gameRequest = gameRequestRepository.findById(id)
|
||||
.orElseThrow { NoSuchElementException("No game request found with id $id") }
|
||||
gameRequest.status = status
|
||||
gameRequestRepository.save(gameRequest)
|
||||
}
|
||||
|
||||
fun toggleRequestVote(id: Long) {
|
||||
val currentUser =
|
||||
userService.getByUsername(getCurrentAuth().name) ?: throw IllegalStateException("Current user not found")
|
||||
val gameRequest = gameRequestRepository.findById(id)
|
||||
.orElseThrow { NoSuchElementException("No game request found with id $id") }
|
||||
|
||||
if (gameRequest.requester?.id == currentUser.id) {
|
||||
throw IllegalStateException("You cannot vote for your own request")
|
||||
}
|
||||
|
||||
if (gameRequest.voters.contains(currentUser)) {
|
||||
gameRequest.voters.remove(currentUser)
|
||||
} else {
|
||||
gameRequest.voters.add(currentUser)
|
||||
}
|
||||
|
||||
gameRequestRepository.save(gameRequest)
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,18 @@
|
||||
package org.gameyfin.app.requests.dto
|
||||
|
||||
import org.gameyfin.app.requests.entities.ExternalProviderIds
|
||||
import org.gameyfin.app.requests.status.GameRequestStatus
|
||||
import org.gameyfin.app.users.dto.UserInfoAdminDto
|
||||
import org.gameyfin.app.users.dto.UserInfoDto
|
||||
import java.time.Instant
|
||||
|
||||
class GameRequestDto(
|
||||
val id: Long,
|
||||
val title: String,
|
||||
val release: Instant,
|
||||
val externalProviderIds: ExternalProviderIds,
|
||||
val status: GameRequestStatus,
|
||||
val requester: UserInfoAdminDto
|
||||
val requester: UserInfoDto?,
|
||||
val voters: List<UserInfoDto>,
|
||||
val createdAt: Instant?,
|
||||
val updatedAt: Instant?
|
||||
)
|
||||
+14
-11
@@ -1,42 +1,45 @@
|
||||
package org.gameyfin.app.requests
|
||||
package org.gameyfin.app.requests.entities
|
||||
|
||||
import jakarta.persistence.*
|
||||
import org.gameyfin.app.requests.status.GameRequestStatus
|
||||
import org.gameyfin.app.users.entities.User
|
||||
import org.hibernate.annotations.CreationTimestamp
|
||||
import org.hibernate.annotations.UpdateTimestamp
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener
|
||||
import java.time.Instant
|
||||
|
||||
typealias ExternalProviderIds = Map<String, String>
|
||||
|
||||
@Entity
|
||||
@EntityListeners(GameRequestEntityListener::class, AuditingEntityListener::class)
|
||||
class GameRequest(
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
var id: Long? = null,
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(nullable = false, updatable = false)
|
||||
var createdAt: Instant? = null,
|
||||
|
||||
@UpdateTimestamp
|
||||
@Column(nullable = false)
|
||||
var updatedAt: Instant? = null,
|
||||
|
||||
@Column(nullable = false)
|
||||
val title: String,
|
||||
|
||||
@Column(nullable = false)
|
||||
val release: Instant,
|
||||
|
||||
@ElementCollection
|
||||
val externalProviderIds: ExternalProviderIds,
|
||||
|
||||
@Column(nullable = false)
|
||||
var status: GameRequestStatus,
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
var requester: User? = null,
|
||||
|
||||
@OneToMany
|
||||
var voters: MutableList<User> = mutableListOf(),
|
||||
|
||||
@ElementCollection
|
||||
val externalProviderIds: ExternalProviderIds
|
||||
@CreationTimestamp
|
||||
@Column(nullable = false, updatable = false)
|
||||
var createdAt: Instant? = null,
|
||||
|
||||
@UpdateTimestamp
|
||||
@Column(nullable = false)
|
||||
var updatedAt: Instant? = null
|
||||
)
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.gameyfin.app.requests.entities
|
||||
|
||||
import jakarta.persistence.PostPersist
|
||||
import jakarta.persistence.PostRemove
|
||||
import jakarta.persistence.PostUpdate
|
||||
import org.gameyfin.app.requests.GameRequestService
|
||||
import org.gameyfin.app.requests.dto.GameRequestEvent
|
||||
import org.gameyfin.app.requests.extensions.toDto
|
||||
|
||||
class GameRequestEntityListener {
|
||||
@PostPersist
|
||||
fun created(gameRequest: GameRequest) {
|
||||
GameRequestService.emit(GameRequestEvent.Created(gameRequest.toDto()))
|
||||
}
|
||||
|
||||
@PostUpdate
|
||||
fun updated(gameRequest: GameRequest) {
|
||||
GameRequestService.emit(GameRequestEvent.Updated(gameRequest.toDto()))
|
||||
}
|
||||
|
||||
@PostRemove
|
||||
fun deleted(gameRequest: GameRequest) {
|
||||
GameRequestService.emit(GameRequestEvent.Deleted(gameRequest.id!!))
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package org.gameyfin.app.requests.extensions
|
||||
|
||||
import org.gameyfin.app.requests.GameRequest
|
||||
import org.gameyfin.app.requests.dto.GameRequestDto
|
||||
import org.gameyfin.app.requests.entities.GameRequest
|
||||
import org.gameyfin.app.users.extensions.toUserInfoDto
|
||||
|
||||
fun GameRequest.toDto(): GameRequestDto {
|
||||
return GameRequestDto(
|
||||
@@ -10,6 +11,13 @@ fun GameRequest.toDto(): GameRequestDto {
|
||||
release = this.release,
|
||||
externalProviderIds = this.externalProviderIds,
|
||||
status = this.status,
|
||||
requester = this.requester.toDto()
|
||||
requester = this.requester?.toUserInfoDto(),
|
||||
voters = this.voters.map { it.toUserInfoDto() },
|
||||
createdAt = this.createdAt,
|
||||
updatedAt = this.updatedAt
|
||||
)
|
||||
}
|
||||
|
||||
fun Collection<GameRequest>.toDtos(): List<GameRequestDto> {
|
||||
return this.map { it.toDto() }
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package org.gameyfin.app.setup
|
||||
import com.vaadin.flow.server.auth.AnonymousAllowed
|
||||
import com.vaadin.hilla.Endpoint
|
||||
import com.vaadin.hilla.exception.EndpointException
|
||||
import org.gameyfin.app.users.dto.UserInfoAdminDto
|
||||
import org.gameyfin.app.users.dto.ExtendedUserInfoDto
|
||||
import org.gameyfin.app.users.dto.UserRegistrationDto
|
||||
|
||||
@Endpoint
|
||||
@@ -16,7 +16,7 @@ class SetupEndpoint(
|
||||
}
|
||||
|
||||
@AnonymousAllowed
|
||||
fun registerSuperAdmin(superAdminRegistration: UserRegistrationDto): UserInfoAdminDto {
|
||||
fun registerSuperAdmin(superAdminRegistration: UserRegistrationDto): ExtendedUserInfoDto {
|
||||
if (setupService.isSetupCompleted()) throw EndpointException("Setup already completed")
|
||||
return setupService.createInitialAdminUser(superAdminRegistration)
|
||||
}
|
||||
|
||||
@@ -3,9 +3,10 @@ package org.gameyfin.app.setup
|
||||
import org.gameyfin.app.core.Role
|
||||
import org.gameyfin.app.users.RoleService
|
||||
import org.gameyfin.app.users.UserService
|
||||
import org.gameyfin.app.users.dto.UserInfoAdminDto
|
||||
import org.gameyfin.app.users.dto.ExtendedUserInfoDto
|
||||
import org.gameyfin.app.users.dto.UserRegistrationDto
|
||||
import org.gameyfin.app.users.entities.User
|
||||
import org.gameyfin.app.users.extensions.toExtendedUserInfoDto
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
@@ -26,7 +27,7 @@ class SetupService(
|
||||
/**
|
||||
* Creates the initial user with Super-Admin permissions
|
||||
*/
|
||||
fun createInitialAdminUser(registration: UserRegistrationDto): UserInfoAdminDto {
|
||||
fun createInitialAdminUser(registration: UserRegistrationDto): ExtendedUserInfoDto {
|
||||
val superAdmin = User(
|
||||
username = registration.username,
|
||||
password = registration.password,
|
||||
@@ -36,6 +37,6 @@ class SetupService(
|
||||
)
|
||||
|
||||
val user = userService.registerOrUpdateUser(superAdmin)
|
||||
return userService.toUserInfo(user)
|
||||
return user.toExtendedUserInfoDto()
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import jakarta.annotation.security.PermitAll
|
||||
import jakarta.annotation.security.RolesAllowed
|
||||
import org.gameyfin.app.core.Role
|
||||
import org.gameyfin.app.core.security.getCurrentAuth
|
||||
import org.gameyfin.app.users.dto.UserInfoAdminDto
|
||||
import org.gameyfin.app.users.dto.ExtendedUserInfoDto
|
||||
import org.gameyfin.app.users.dto.UserUpdateDto
|
||||
import org.gameyfin.app.users.enums.RoleAssignmentResult
|
||||
import org.springframework.security.core.Authentication
|
||||
@@ -18,7 +18,7 @@ class UserEndpoint(
|
||||
private val roleService: RoleService
|
||||
) {
|
||||
@AnonymousAllowed
|
||||
fun getUserInfo(): UserInfoAdminDto? {
|
||||
fun getUserInfo(): ExtendedUserInfoDto? {
|
||||
val auth = getCurrentAuth()
|
||||
if (!auth.isAuthenticated || auth.principal == "anonymousUser") return null
|
||||
return userService.getUserInfo()
|
||||
@@ -36,7 +36,7 @@ class UserEndpoint(
|
||||
}
|
||||
|
||||
@RolesAllowed(Role.Names.ADMIN)
|
||||
fun getAllUsers(): List<UserInfoAdminDto> {
|
||||
fun getAllUsers(): List<ExtendedUserInfoDto> {
|
||||
return userService.getAllUsers()
|
||||
}
|
||||
|
||||
|
||||
@@ -9,15 +9,15 @@ import org.gameyfin.app.core.events.*
|
||||
import org.gameyfin.app.core.security.getCurrentAuth
|
||||
import org.gameyfin.app.games.entities.Image
|
||||
import org.gameyfin.app.media.ImageService
|
||||
import org.gameyfin.app.users.dto.UserInfoAdminDto
|
||||
import org.gameyfin.app.users.dto.ExtendedUserInfoDto
|
||||
import org.gameyfin.app.users.dto.UserRegistrationDto
|
||||
import org.gameyfin.app.users.dto.UserUpdateDto
|
||||
import org.gameyfin.app.users.emailconfirmation.EmailConfirmationService
|
||||
import org.gameyfin.app.users.enums.RoleAssignmentResult
|
||||
import org.gameyfin.app.users.extensions.toAuthorities
|
||||
import org.gameyfin.app.users.extensions.toExtendedUserInfoDto
|
||||
import org.gameyfin.app.users.persistence.UserRepository
|
||||
import org.springframework.context.ApplicationEventPublisher
|
||||
import org.springframework.security.core.GrantedAuthority
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority
|
||||
import org.springframework.security.core.userdetails.User
|
||||
import org.springframework.security.core.userdetails.UserDetails
|
||||
import org.springframework.security.core.userdetails.UserDetailsService
|
||||
@@ -56,7 +56,7 @@ class UserService(
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
toAuthorities(user.roles)
|
||||
user.roles.toAuthorities()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ class UserService(
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
toAuthorities(user.roles)
|
||||
user.roles.toAuthorities()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -77,8 +77,8 @@ class UserService(
|
||||
fun findByOidcProviderId(oidcProviderId: String): org.gameyfin.app.users.entities.User? =
|
||||
userRepository.findByOidcProviderId(oidcProviderId)
|
||||
|
||||
fun getAllUsers(): List<UserInfoAdminDto> {
|
||||
return userRepository.findAll().map { u -> toUserInfo(u) }
|
||||
fun getAllUsers(): List<ExtendedUserInfoDto> {
|
||||
return userRepository.findAll().map { it.toExtendedUserInfoDto() }
|
||||
}
|
||||
|
||||
fun getByEmail(email: String): org.gameyfin.app.users.entities.User? {
|
||||
@@ -93,20 +93,20 @@ class UserService(
|
||||
return userRepository.findByUsername(username) ?: throw UsernameNotFoundException("Unknown user '$username'")
|
||||
}
|
||||
|
||||
fun getUserInfo(): UserInfoAdminDto {
|
||||
fun getUserInfo(): ExtendedUserInfoDto {
|
||||
val auth = getCurrentAuth()
|
||||
val principal = auth.principal
|
||||
|
||||
if (principal is OidcUser) {
|
||||
val oidcUser = org.gameyfin.app.users.entities.User(principal)
|
||||
val userInfoDto = toUserInfo(oidcUser)
|
||||
val userInfoDto = oidcUser.toExtendedUserInfoDto()
|
||||
userInfoDto.roles = roleService.extractGrantedAuthorities(principal.authorities)
|
||||
.mapNotNull { Role.Companion.safeValueOf(it.authority) }
|
||||
.mapNotNull { Role.safeValueOf(it.authority) }
|
||||
return userInfoDto
|
||||
}
|
||||
|
||||
val user = getByUsernameNonNull(auth.name)
|
||||
return toUserInfo(user)
|
||||
return user.toExtendedUserInfoDto()
|
||||
}
|
||||
|
||||
fun getAvatar(username: String): Image? {
|
||||
@@ -158,7 +158,7 @@ class UserService(
|
||||
RegistrationAttemptWithExistingEmailEvent(
|
||||
this,
|
||||
it,
|
||||
Utils.Companion.getBaseUrl()
|
||||
Utils.getBaseUrl()
|
||||
)
|
||||
)
|
||||
return
|
||||
@@ -179,12 +179,12 @@ class UserService(
|
||||
if (adminNeedsToApprove) {
|
||||
eventPublisher.publishEvent(UserRegistrationWaitingForApprovalEvent(this, user))
|
||||
} else {
|
||||
eventPublisher.publishEvent(AccountStatusChangedEvent(this, user, Utils.Companion.getBaseUrl()))
|
||||
eventPublisher.publishEvent(AccountStatusChangedEvent(this, user, Utils.getBaseUrl()))
|
||||
}
|
||||
|
||||
if (!user.emailConfirmed) {
|
||||
val token = emailConfirmationService.generate(user)
|
||||
eventPublisher.publishEvent(EmailNeedsConfirmationEvent(this, token, Utils.Companion.getBaseUrl()))
|
||||
eventPublisher.publishEvent(EmailNeedsConfirmationEvent(this, token, Utils.getBaseUrl()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ class UserService(
|
||||
user.email = it
|
||||
user.emailConfirmed = false
|
||||
val token = emailConfirmationService.generate(user)
|
||||
eventPublisher.publishEvent(EmailNeedsConfirmationEvent(this, token, Utils.Companion.getBaseUrl()))
|
||||
eventPublisher.publishEvent(EmailNeedsConfirmationEvent(this, token, Utils.getBaseUrl()))
|
||||
}
|
||||
|
||||
userRepository.save(user)
|
||||
@@ -246,7 +246,7 @@ class UserService(
|
||||
return RoleAssignmentResult.TARGET_POWER_LEVEL_TOO_HIGH
|
||||
}
|
||||
|
||||
val newAssignedRoles = roleNames.mapNotNull { r -> Role.Companion.safeValueOf(r) }
|
||||
val newAssignedRoles = roleNames.mapNotNull { r -> Role.safeValueOf(r) }
|
||||
val newAssignedRolesLevel = roleService.getHighestRole(newAssignedRoles).powerLevel
|
||||
val currentUserLevel = roleService.getHighestRoleFromAuthorities(currentUser.authorities).powerLevel
|
||||
|
||||
@@ -276,29 +276,12 @@ class UserService(
|
||||
val user = getByUsernameNonNull(username)
|
||||
user.enabled = enabled
|
||||
userRepository.save(user)
|
||||
eventPublisher.publishEvent(AccountStatusChangedEvent(this, user, Utils.Companion.getBaseUrl()))
|
||||
eventPublisher.publishEvent(AccountStatusChangedEvent(this, user, Utils.getBaseUrl()))
|
||||
}
|
||||
|
||||
fun deleteUser(username: String) {
|
||||
val user = getByUsernameNonNull(username)
|
||||
userRepository.delete(user)
|
||||
eventPublisher.publishEvent(AccountDeletedEvent(this, user, Utils.Companion.getBaseUrl()))
|
||||
}
|
||||
|
||||
fun toUserInfo(user: org.gameyfin.app.users.entities.User): UserInfoAdminDto {
|
||||
return UserInfoAdminDto(
|
||||
username = user.username,
|
||||
email = user.email,
|
||||
emailConfirmed = user.emailConfirmed,
|
||||
enabled = user.enabled,
|
||||
hasAvatar = user.avatar != null,
|
||||
avatarId = user.avatar?.id,
|
||||
managedBySso = user.oidcProviderId != null,
|
||||
roles = user.roles
|
||||
)
|
||||
}
|
||||
|
||||
private fun toAuthorities(roles: Collection<Role>): List<GrantedAuthority> {
|
||||
return roles.map { r -> SimpleGrantedAuthority(r.roleName) }
|
||||
eventPublisher.publishEvent(AccountDeletedEvent(this, user, Utils.getBaseUrl()))
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@ package org.gameyfin.app.users.dto
|
||||
|
||||
import org.gameyfin.app.core.Role
|
||||
|
||||
data class UserInfoAdminDto(
|
||||
data class ExtendedUserInfoDto(
|
||||
val username: String,
|
||||
val managedBySso: Boolean,
|
||||
val email: String,
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package org.gameyfin.app.users.dto
|
||||
|
||||
data class UserInfoUserDto(
|
||||
data class UserInfoDto(
|
||||
val username: String,
|
||||
val hasAvatar: Boolean,
|
||||
val avatarId: Long? = null,
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.gameyfin.app.users.extensions
|
||||
|
||||
import org.gameyfin.app.core.Role
|
||||
import org.gameyfin.app.users.dto.ExtendedUserInfoDto
|
||||
import org.gameyfin.app.users.dto.UserInfoDto
|
||||
import org.gameyfin.app.users.entities.User
|
||||
import org.springframework.security.core.GrantedAuthority
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority
|
||||
|
||||
fun User.toUserInfoDto(): UserInfoDto {
|
||||
return UserInfoDto(
|
||||
username = this.username,
|
||||
hasAvatar = this.avatar != null,
|
||||
avatarId = this.avatar?.id
|
||||
)
|
||||
}
|
||||
|
||||
fun User.toExtendedUserInfoDto(): ExtendedUserInfoDto {
|
||||
return ExtendedUserInfoDto(
|
||||
username = this.username,
|
||||
email = this.email,
|
||||
emailConfirmed = this.emailConfirmed,
|
||||
enabled = this.enabled,
|
||||
hasAvatar = this.avatar != null,
|
||||
avatarId = this.avatar?.id,
|
||||
managedBySso = this.oidcProviderId != null,
|
||||
roles = this.roles
|
||||
)
|
||||
}
|
||||
|
||||
fun Collection<Role>.toAuthorities(): List<GrantedAuthority> {
|
||||
return this.map { r -> SimpleGrantedAuthority(r.roleName) }
|
||||
}
|
||||
Reference in New Issue
Block a user