mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-16 08:15:48 +00:00
Fix various issues with SSO users
This commit is contained in:
@@ -56,7 +56,7 @@ function SsoManagementLayout({getConfig, formik, setSaveMessage}: any) {
|
|||||||
<Checkbox className="items-baseline" value="auto-register-new-users" isDisabled>
|
<Checkbox className="items-baseline" value="auto-register-new-users" isDisabled>
|
||||||
Automatically create new users after registration
|
Automatically create new users after registration
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
<Tooltip content={"Currently not configurable due to a bug"} placement="right">
|
<Tooltip content={"Currently not configurable (always enabled)"} placement="right">
|
||||||
<Warning weight="fill"/>
|
<Warning weight="fill"/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import {UserPreferenceService} from "Frontend/util/user-preference-service";
|
|||||||
import SearchBar from "Frontend/components/general/SearchBar";
|
import SearchBar from "Frontend/components/general/SearchBar";
|
||||||
import {useSnapshot} from "valtio/react";
|
import {useSnapshot} from "valtio/react";
|
||||||
import {gameState} from "Frontend/state/GameState";
|
import {gameState} from "Frontend/state/GameState";
|
||||||
import {scanState} from "Frontend/state/ScanState";
|
|
||||||
import ScanProgressPopover from "Frontend/components/general/ScanProgressPopover";
|
import ScanProgressPopover from "Frontend/components/general/ScanProgressPopover";
|
||||||
import {isAdmin} from "Frontend/util/utils";
|
import {isAdmin} from "Frontend/util/utils";
|
||||||
|
|
||||||
@@ -27,7 +26,6 @@ export default function MainLayout() {
|
|||||||
const isHomePage = location.pathname === "/";
|
const isHomePage = location.pathname === "/";
|
||||||
const [isExploding, setIsExploding] = useState(false);
|
const [isExploding, setIsExploding] = useState(false);
|
||||||
const games = useSnapshot(gameState).games;
|
const games = useSnapshot(gameState).games;
|
||||||
const scans = useSnapshot(scanState);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let newTitle = `Gameyfin - ${routeMetadata?.title}`;
|
let newTitle = `Gameyfin - ${routeMetadata?.title}`;
|
||||||
|
|||||||
@@ -7,15 +7,15 @@ import jakarta.annotation.security.RolesAllowed
|
|||||||
import org.gameyfin.app.config.dto.ConfigEntryDto
|
import org.gameyfin.app.config.dto.ConfigEntryDto
|
||||||
import org.gameyfin.app.config.dto.ConfigUpdateDto
|
import org.gameyfin.app.config.dto.ConfigUpdateDto
|
||||||
import org.gameyfin.app.core.Role
|
import org.gameyfin.app.core.Role
|
||||||
|
import org.gameyfin.app.users.UserService
|
||||||
import org.gameyfin.app.users.util.isAdmin
|
import org.gameyfin.app.users.util.isAdmin
|
||||||
import org.springframework.security.core.context.SecurityContextHolder
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails
|
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
|
|
||||||
@Endpoint
|
@Endpoint
|
||||||
@RolesAllowed(Role.Names.ADMIN)
|
@RolesAllowed(Role.Names.ADMIN)
|
||||||
class ConfigEndpoint(
|
class ConfigEndpoint(
|
||||||
private val configService: ConfigService
|
private val configService: ConfigService,
|
||||||
|
private val userService: UserService,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
val log = KotlinLogging.logger { }
|
val log = KotlinLogging.logger { }
|
||||||
@@ -25,7 +25,7 @@ class ConfigEndpoint(
|
|||||||
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
fun subscribe(): Flux<List<ConfigUpdateDto>> {
|
fun subscribe(): Flux<List<ConfigUpdateDto>> {
|
||||||
val user = SecurityContextHolder.getContext().authentication.principal as UserDetails
|
val user = userService.getCurrentUser()
|
||||||
return if (user.isAdmin()) ConfigService.subscribe()
|
return if (user.isAdmin()) ConfigService.subscribe()
|
||||||
else Flux.empty()
|
else Flux.empty()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ import com.vaadin.hilla.Endpoint
|
|||||||
import jakarta.annotation.security.PermitAll
|
import jakarta.annotation.security.PermitAll
|
||||||
import jakarta.annotation.security.RolesAllowed
|
import jakarta.annotation.security.RolesAllowed
|
||||||
import org.gameyfin.app.core.Role
|
import org.gameyfin.app.core.Role
|
||||||
|
import org.gameyfin.app.users.UserService
|
||||||
import org.gameyfin.app.users.util.isAdmin
|
import org.gameyfin.app.users.util.isAdmin
|
||||||
import org.springframework.security.core.context.SecurityContextHolder
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails
|
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
|
|
||||||
@Endpoint
|
@Endpoint
|
||||||
@RolesAllowed(Role.Names.ADMIN)
|
@RolesAllowed(Role.Names.ADMIN)
|
||||||
class LogEndpoint(
|
class LogEndpoint(
|
||||||
private val logService: LogService
|
private val logService: LogService,
|
||||||
|
private val userService: UserService,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun reloadLogConfig() {
|
fun reloadLogConfig() {
|
||||||
@@ -21,7 +21,7 @@ class LogEndpoint(
|
|||||||
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
fun getApplicationLogs(): Flux<String> {
|
fun getApplicationLogs(): Flux<String> {
|
||||||
val user = SecurityContextHolder.getContext().authentication.principal as UserDetails
|
val user = userService.getCurrentUser()
|
||||||
return if (user.isAdmin()) logService.streamLogs()
|
return if (user.isAdmin()) logService.streamLogs()
|
||||||
else Flux.empty()
|
else Flux.empty()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,21 +5,21 @@ import jakarta.annotation.security.PermitAll
|
|||||||
import jakarta.annotation.security.RolesAllowed
|
import jakarta.annotation.security.RolesAllowed
|
||||||
import org.gameyfin.app.core.Role
|
import org.gameyfin.app.core.Role
|
||||||
import org.gameyfin.app.core.plugins.dto.PluginUpdateDto
|
import org.gameyfin.app.core.plugins.dto.PluginUpdateDto
|
||||||
|
import org.gameyfin.app.users.UserService
|
||||||
import org.gameyfin.app.users.util.isAdmin
|
import org.gameyfin.app.users.util.isAdmin
|
||||||
import org.gameyfin.pluginapi.core.config.PluginConfigValidationResult
|
import org.gameyfin.pluginapi.core.config.PluginConfigValidationResult
|
||||||
import org.springframework.security.core.context.SecurityContextHolder
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails
|
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
|
|
||||||
@Endpoint
|
@Endpoint
|
||||||
@RolesAllowed(Role.Names.ADMIN)
|
@RolesAllowed(Role.Names.ADMIN)
|
||||||
class PluginEndpoint(
|
class PluginEndpoint(
|
||||||
private val pluginService: PluginService
|
private val pluginService: PluginService,
|
||||||
|
private val userService: UserService,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
fun subscribe(): Flux<List<PluginUpdateDto>> {
|
fun subscribe(): Flux<List<PluginUpdateDto>> {
|
||||||
val user = SecurityContextHolder.getContext().authentication.principal as UserDetails
|
val user = userService.getCurrentUser()
|
||||||
return if (user.isAdmin()) PluginService.subscribe()
|
return if (user.isAdmin()) PluginService.subscribe()
|
||||||
else Flux.empty()
|
else Flux.empty()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
package org.gameyfin.app.libraries
|
package org.gameyfin.app.libraries
|
||||||
|
|
||||||
import com.vaadin.hilla.Endpoint
|
import com.vaadin.hilla.Endpoint
|
||||||
import org.gameyfin.app.libraries.dto.LibraryDto
|
|
||||||
import org.gameyfin.app.libraries.dto.LibraryEvent
|
|
||||||
import jakarta.annotation.security.PermitAll
|
import jakarta.annotation.security.PermitAll
|
||||||
import jakarta.annotation.security.RolesAllowed
|
import jakarta.annotation.security.RolesAllowed
|
||||||
import org.gameyfin.app.core.Role
|
import org.gameyfin.app.core.Role
|
||||||
|
import org.gameyfin.app.libraries.dto.LibraryDto
|
||||||
|
import org.gameyfin.app.libraries.dto.LibraryEvent
|
||||||
import org.gameyfin.app.libraries.dto.LibraryScanProgress
|
import org.gameyfin.app.libraries.dto.LibraryScanProgress
|
||||||
import org.gameyfin.app.libraries.dto.LibraryUpdateDto
|
import org.gameyfin.app.libraries.dto.LibraryUpdateDto
|
||||||
import org.gameyfin.app.libraries.enums.ScanType
|
import org.gameyfin.app.libraries.enums.ScanType
|
||||||
|
import org.gameyfin.app.users.UserService
|
||||||
import org.gameyfin.app.users.util.isAdmin
|
import org.gameyfin.app.users.util.isAdmin
|
||||||
import org.springframework.security.core.context.SecurityContextHolder
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails
|
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
|
|
||||||
@Endpoint
|
@Endpoint
|
||||||
@PermitAll
|
@PermitAll
|
||||||
class LibraryEndpoint(
|
class LibraryEndpoint(
|
||||||
private val libraryService: LibraryService
|
private val libraryService: LibraryService,
|
||||||
|
private val userService: UserService,
|
||||||
) {
|
) {
|
||||||
fun subscribeToLibraryEvents(): Flux<List<LibraryEvent>> {
|
fun subscribeToLibraryEvents(): Flux<List<LibraryEvent>> {
|
||||||
return LibraryService.subscribeToLibraryEvents()
|
return LibraryService.subscribeToLibraryEvents()
|
||||||
@@ -27,7 +27,7 @@ class LibraryEndpoint(
|
|||||||
|
|
||||||
|
|
||||||
fun subscribeToScanProgressEvents(): Flux<List<LibraryScanProgress>> {
|
fun subscribeToScanProgressEvents(): Flux<List<LibraryScanProgress>> {
|
||||||
val user = SecurityContextHolder.getContext().authentication.principal as UserDetails
|
val user = userService.getCurrentUser()
|
||||||
return if (user.isAdmin()) LibraryService.subscribeToScanProgressEvents()
|
return if (user.isAdmin()) LibraryService.subscribeToScanProgressEvents()
|
||||||
else Flux.empty()
|
else Flux.empty()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,19 @@ class UserService(
|
|||||||
override fun loadUserByUsername(username: String): UserDetails {
|
override fun loadUserByUsername(username: String): UserDetails {
|
||||||
val user = getByUsernameNonNull(username)
|
val user = getByUsernameNonNull(username)
|
||||||
|
|
||||||
|
if (user.oidcProviderId != null && user.password == null) {
|
||||||
|
// If the user is an OIDC user, we return a UserDetails with no password
|
||||||
|
return User(
|
||||||
|
user.username,
|
||||||
|
"", // OIDC users do not have a password
|
||||||
|
user.enabled,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
toAuthorities(user.roles)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return User(
|
return User(
|
||||||
user.username,
|
user.username,
|
||||||
user.password,
|
user.password,
|
||||||
@@ -132,7 +145,11 @@ class UserService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun registerOrUpdateUser(user: org.gameyfin.app.users.entities.User): org.gameyfin.app.users.entities.User {
|
fun registerOrUpdateUser(user: org.gameyfin.app.users.entities.User): org.gameyfin.app.users.entities.User {
|
||||||
user.password = passwordEncoder.encode(user.password)
|
// OIDC users can have null passwords, so we only encode if a password is provided
|
||||||
|
if (user.password != null) {
|
||||||
|
user.password = passwordEncoder.encode(user.password)
|
||||||
|
}
|
||||||
|
|
||||||
return userRepository.save(user)
|
return userRepository.save(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,3 +15,7 @@ fun UserDetails.hasRole(role: Role): Boolean {
|
|||||||
fun UserDetails.isAdmin(): Boolean {
|
fun UserDetails.isAdmin(): Boolean {
|
||||||
return hasRole(Role.SUPERADMIN) || hasRole(Role.ADMIN)
|
return hasRole(Role.SUPERADMIN) || hasRole(Role.ADMIN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun User.isAdmin(): Boolean {
|
||||||
|
return hasRole(Role.SUPERADMIN) || hasRole(Role.ADMIN)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user