diff --git a/onyxia-api/src/main/java/fr/insee/onyxia/api/controller/RestExceptionHandler.java b/onyxia-api/src/main/java/fr/insee/onyxia/api/controller/RestExceptionHandler.java new file mode 100644 index 00000000..8e684ea3 --- /dev/null +++ b/onyxia-api/src/main/java/fr/insee/onyxia/api/controller/RestExceptionHandler.java @@ -0,0 +1,15 @@ +package fr.insee.onyxia.api.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class RestExceptionHandler { + + @ResponseStatus(value = HttpStatus.FORBIDDEN) + @ExceptionHandler(AccessDeniedException.class) + public void handleAccessDeniedException(Exception ignored) {} +} diff --git a/onyxia-api/src/main/java/fr/insee/onyxia/api/controller/api/onboarding/OnboardingController.java b/onyxia-api/src/main/java/fr/insee/onyxia/api/controller/api/onboarding/OnboardingController.java index 58b49d19..ca563491 100644 --- a/onyxia-api/src/main/java/fr/insee/onyxia/api/controller/api/onboarding/OnboardingController.java +++ b/onyxia-api/src/main/java/fr/insee/onyxia/api/controller/api/onboarding/OnboardingController.java @@ -50,6 +50,7 @@ public void onboard( if (!region.getServices().isAllowNamespaceCreation()) { throw new OnboardingDisabledException(); } + checkPermissions(region, request); final KubernetesService.Owner owner = new KubernetesService.Owner(); if (request.getGroup() != null) { diff --git a/onyxia-api/src/test/java/fr/insee/onyxia/api/controller/api/onboarding/OnboardingControllerTest.java b/onyxia-api/src/test/java/fr/insee/onyxia/api/controller/api/onboarding/OnboardingControllerTest.java index f082cdb5..9a01665d 100644 --- a/onyxia-api/src/test/java/fr/insee/onyxia/api/controller/api/onboarding/OnboardingControllerTest.java +++ b/onyxia-api/src/test/java/fr/insee/onyxia/api/controller/api/onboarding/OnboardingControllerTest.java @@ -6,9 +6,11 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.fasterxml.jackson.databind.ObjectMapper; import fr.insee.onyxia.api.configuration.BaseTest; import fr.insee.onyxia.api.configuration.SecurityConfig; import fr.insee.onyxia.api.configuration.properties.RegionsConfiguration; +import fr.insee.onyxia.api.controller.exception.NamespaceAlreadyExistException; import fr.insee.onyxia.api.services.UserProvider; import fr.insee.onyxia.api.services.impl.kubernetes.KubernetesService; import fr.insee.onyxia.api.services.utils.HttpRequestUtils; @@ -25,6 +27,7 @@ class OnboardingControllerTest extends BaseTest { @Autowired private MockMvc mockMvc; + @Autowired private ObjectMapper mapper; @MockBean private UserProvider userProvider; @MockBean private RegionsConfiguration regionsConfiguration; @@ -54,10 +57,48 @@ public void should_not_create_namespace_when_allow_namespace_creation_is_false() servicesConfiguration.setAllowNamespaceCreation(false); region.setServices(servicesConfiguration); when(regionsConfiguration.getDefaultRegion()).thenReturn(region); + when(userProvider.getUser(any())).thenReturn(User.newInstance().setIdep("default").build()); + mockMvc.perform(post("/onboarding").content("{}").contentType(APPLICATION_JSON)) .andExpect(status().isBadRequest()); } + @Test + public void should_not_create_namespace_when_user_is_not_member_of_group() throws Exception { + Region region = new Region(); + Region.Services servicesConfiguration = new Region.Services(); + servicesConfiguration.setSingleNamespace(false); + servicesConfiguration.setAllowNamespaceCreation(true); + region.setServices(servicesConfiguration); + + when(regionsConfiguration.getDefaultRegion()).thenReturn(region); + when(userProvider.getUser(any())).thenReturn(User.newInstance().setIdep("default").build()); + + var onboardingRequest = new OnboardingController.OnboardingRequest(); + onboardingRequest.setGroup("some-group"); + mockMvc.perform( + post("/onboarding") + .content(mapper.writeValueAsString(onboardingRequest)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isForbidden()); + } + + @Test + public void should_not_create_namespace_when_already_exist() throws Exception { + Region region = new Region(); + Region.Services servicesConfiguration = new Region.Services(); + servicesConfiguration.setSingleNamespace(false); + servicesConfiguration.setAllowNamespaceCreation(true); + region.setServices(servicesConfiguration); + when(regionsConfiguration.getDefaultRegion()).thenReturn(region); + when(userProvider.getUser(any())).thenReturn(User.newInstance().setIdep("default").build()); + when(kubernetesService.createDefaultNamespace(any(), any())) + .thenThrow(new NamespaceAlreadyExistException()); + + mockMvc.perform(post("/onboarding").content("{}").contentType(APPLICATION_JSON)) + .andExpect(status().isConflict()); + } + @Test public void should_create_namespace() throws Exception { Region region = new Region();