From fb5a3c062c4e328143ff49bc26fabd292d04fe0a Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer Date: Mon, 27 May 2024 12:19:24 +0200 Subject: [PATCH] feat: allow access to MTBFile endpoint for non-token users --- .../input/MtbFileRestControllerTest.kt | 70 ++++++++++++++++++- .../config/AppSecurityConfiguration.kt | 4 +- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt index d8c1321..521ec52 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt @@ -22,9 +22,11 @@ package dev.dnpm.etl.processor.input import com.fasterxml.jackson.databind.ObjectMapper import de.ukw.ccc.bwhc.dto.* import dev.dnpm.etl.processor.config.AppSecurityConfiguration -import dev.dnpm.etl.processor.services.RequestProcessor import dev.dnpm.etl.processor.security.TokenRepository +import dev.dnpm.etl.processor.security.UserRoleRepository +import dev.dnpm.etl.processor.services.RequestProcessor import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.mockito.ArgumentMatchers.anyString @@ -37,6 +39,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.http.MediaType +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.anonymous import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user import org.springframework.test.context.ContextConfiguration @@ -91,6 +94,19 @@ class MtbFileRestControllerTest { verify(requestProcessor, times(1)).processMtbFile(any()) } + @Test + fun testShouldGrantPermissionToSendMtbFileToAdminUser() { + mockMvc.post("/mtbfile") { + with(user("onkostarserver").roles("ADMIN")) + contentType = MediaType.APPLICATION_JSON + content = ObjectMapper().writeValueAsString(mtbFile) + }.andExpect { + status { isAccepted() } + } + + verify(requestProcessor, times(1)).processMtbFile(any()) + } + @Test fun testShouldDenyPermissionToSendMtbFile() { mockMvc.post("/mtbfile") { @@ -104,6 +120,19 @@ class MtbFileRestControllerTest { verify(requestProcessor, never()).processMtbFile(any()) } + @Test + fun testShouldDenyPermissionToSendMtbFileForUser() { + mockMvc.post("/mtbfile") { + with(user("fakeuser").roles("USER")) + contentType = MediaType.APPLICATION_JSON + content = ObjectMapper().writeValueAsString(mtbFile) + }.andExpect { + status { isForbidden() } + } + + verify(requestProcessor, never()).processMtbFile(any()) + } + @Test fun testShouldGrantPermissionToDeletePatientData() { mockMvc.delete("/mtbfile/12345678") { @@ -126,6 +155,45 @@ class MtbFileRestControllerTest { verify(requestProcessor, never()).processDeletion(anyString()) } + @Nested + @MockBean(UserRoleRepository::class, ClientRegistrationRepository::class) + @TestPropertySource( + properties = [ + "app.pseudonymize.generator=BUILDIN", + "app.security.admin-user=admin", + "app.security.admin-password={noop}very-secret", + "app.security.enable-tokens=true", + "app.security.enable-oidc=true" + ] + ) + inner class WithOidcEnabled { + @Test + fun testShouldGrantPermissionToSendMtbFileToAdminUser() { + mockMvc.post("/mtbfile") { + with(user("onkostarserver").roles("ADMIN")) + contentType = MediaType.APPLICATION_JSON + content = ObjectMapper().writeValueAsString(mtbFile) + }.andExpect { + status { isAccepted() } + } + + verify(requestProcessor, times(1)).processMtbFile(any()) + } + + @Test + fun testShouldGrantPermissionToSendMtbFileToUser() { + mockMvc.post("/mtbfile") { + with(user("onkostarserver").roles("USER")) + contentType = MediaType.APPLICATION_JSON + content = ObjectMapper().writeValueAsString(mtbFile) + }.andExpect { + status { isAccepted() } + } + + verify(requestProcessor, times(1)).processMtbFile(any()) + } + } + companion object { val mtbFile: MtbFile = MtbFile.builder() diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt index 0da9398..6b063bd 100644 --- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt +++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt @@ -89,7 +89,7 @@ class AppSecurityConfiguration( http { authorizeRequests { authorize("/configs/**", hasRole("ADMIN")) - authorize("/mtbfile/**", hasAnyRole("MTBFILE")) + authorize("/mtbfile/**", hasAnyRole("MTBFILE", "ADMIN", "USER")) authorize("/report/**", hasAnyRole("ADMIN", "USER")) authorize("*.css", permitAll) authorize("*.ico", permitAll) @@ -147,7 +147,7 @@ class AppSecurityConfiguration( http { authorizeRequests { authorize("/configs/**", hasRole("ADMIN")) - authorize("/mtbfile/**", hasAnyRole("MTBFILE")) + authorize("/mtbfile/**", hasAnyRole("MTBFILE", "ADMIN")) authorize("/report/**", hasRole("ADMIN")) authorize(anyRequest, permitAll) }