diff --git a/.idea/runConfigurations/komga__bootRun__dev_demo.xml b/.idea/runConfigurations/komga__bootRun__dev_demo.xml new file mode 100644 index 000000000..773f6a079 --- /dev/null +++ b/.idea/runConfigurations/komga__bootRun__dev_demo.xml @@ -0,0 +1,26 @@ + + + + + + + + true + + + \ No newline at end of file diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/UserController.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/UserController.kt index 52d19da88..27fd7f3b3 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/UserController.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/UserController.kt @@ -8,6 +8,7 @@ import org.gotson.komga.infrastructure.security.KomgaPrincipal import org.gotson.komga.infrastructure.security.KomgaUserDetailsLifecycle import org.gotson.komga.infrastructure.security.UserEmailAlreadyExistsException import org.gotson.komga.interfaces.rest.dto.toDto +import org.springframework.core.env.Environment import org.springframework.data.repository.findByIdOrNull import org.springframework.http.HttpStatus import org.springframework.http.MediaType @@ -36,9 +37,12 @@ private val logger = KotlinLogging.logger {} class UserController( private val userDetailsLifecycle: KomgaUserDetailsLifecycle, private val userRepository: KomgaUserRepository, - private val libraryRepository: LibraryRepository + private val libraryRepository: LibraryRepository, + env: Environment ) { + private val demo = env.activeProfiles.contains("demo") + @GetMapping("me") fun getMe(@AuthenticationPrincipal principal: KomgaPrincipal): UserDto = principal.user.toDto() @@ -49,6 +53,7 @@ class UserController( @AuthenticationPrincipal principal: KomgaPrincipal, @Valid @RequestBody newPasswordDto: PasswordUpdateDto ) { + if (demo) throw ResponseStatusException(HttpStatus.FORBIDDEN) userDetailsLifecycle.updatePassword(principal, newPasswordDto.password, false) } diff --git a/komga/src/test/kotlin/org/gotson/komga/interfaces/rest/UserControllerTest.kt b/komga/src/test/kotlin/org/gotson/komga/interfaces/rest/UserControllerTest.kt new file mode 100644 index 000000000..68d21141b --- /dev/null +++ b/komga/src/test/kotlin/org/gotson/komga/interfaces/rest/UserControllerTest.kt @@ -0,0 +1,38 @@ +package org.gotson.komga.interfaces.rest + +import org.gotson.komga.infrastructure.security.KomgaUserDetailsLifecycle +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.http.MediaType +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.context.junit.jupiter.SpringExtension +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.patch + +@ExtendWith(SpringExtension::class) +@SpringBootTest +@AutoConfigureTestDatabase +@AutoConfigureMockMvc(printOnlyOnFailure = false) +@ActiveProfiles("demo") +class UserControllerTest( + @Autowired private val userDetailsLifecycle: KomgaUserDetailsLifecycle, + @Autowired private val mockMvc: MockMvc + +) { + @Test + @WithMockCustomUser + fun `given demo profile is active when a user tries to update its password via api then returns forbidden`() { + val jsonString = """{"password":"new"}""" + + mockMvc.patch("/api/v1/users/me/password") { + contentType = MediaType.APPLICATION_JSON + content = jsonString + }.andExpect { + status { isForbidden } + } + } +}