From d917ddca45567942bda16659e9cfb6bd03535a3e Mon Sep 17 00:00:00 2001 From: "idriss.naji" Date: Fri, 20 Jan 2023 11:01:49 +0100 Subject: [PATCH] fix: vic-2340 refactoring Authority --- .../api/auth/Authority.java | 56 +++++++++++ .../RoleAuthorizationAuthorityMapper.java | 40 ++++++++ .../ApplicationSettingsController.java | 5 +- .../controller/ConsultingTypeController.java | 2 +- .../api/controller/TopicAdminController.java | 8 +- .../config/SecurityConfig.java | 13 ++- .../ApplicationSettingsControllerIT.java | 93 ++++++++++--------- .../controller/AuthenticationMockBuilder.java | 15 ++- .../ConsultingTypeControllerE2EIT.java | 6 +- .../controller/TopicAdminControllerIT.java | 26 +++--- .../api/controller/TopicControllerIT.java | 2 +- 11 files changed, 188 insertions(+), 78 deletions(-) create mode 100644 src/main/java/de/caritas/cob/consultingtypeservice/api/auth/Authority.java create mode 100644 src/main/java/de/caritas/cob/consultingtypeservice/api/auth/RoleAuthorizationAuthorityMapper.java diff --git a/src/main/java/de/caritas/cob/consultingtypeservice/api/auth/Authority.java b/src/main/java/de/caritas/cob/consultingtypeservice/api/auth/Authority.java new file mode 100644 index 00000000..fde82daf --- /dev/null +++ b/src/main/java/de/caritas/cob/consultingtypeservice/api/auth/Authority.java @@ -0,0 +1,56 @@ +package de.caritas.cob.consultingtypeservice.api.auth; + +import static java.util.Collections.emptyList; + +import com.google.common.collect.Lists; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum Authority { + TENANT_ADMIN(UserRole.TENANT_ADMIN, + Lists.newArrayList( + AuthorityValue.PATCH_APPLICATION_SETTINGS, + AuthorityValue.CREATE_CONSULTING_TYPE)), + TOPIC_ADMIN(UserRole.TOPIC_ADMIN, + Lists.newArrayList( + AuthorityValue.CREATE_TOPIC, + AuthorityValue.UPDATE_TOPIC, + AuthorityValue.GET_ALL_TOPICS_WITH_TRANSLATION, + AuthorityValue.GET_TOPICS_TRANSLATION_BY_ID)); + + private final UserRole userRole; + private final List grantedAuthorities; + + public static List getAuthoritiesByUserRole(UserRole userRole) { + Optional authorityByUserRole = + Stream.of(values()).filter(authority -> authority.userRole.equals(userRole)).findFirst(); + + return authorityByUserRole.isPresent() + ? authorityByUserRole.get().getGrantedAuthorities() + : emptyList(); + } + + public static class AuthorityValue { + + private AuthorityValue() { + } + + + public static final String PREFIX = "AUTHORIZATION_"; + public static final String PATCH_APPLICATION_SETTINGS = PREFIX + "PATCH_APPLICATION_SETTINGS"; + public static final String CREATE_CONSULTING_TYPE = PREFIX + "CREATE_CONSULTING_TYPE"; + public static final String CREATE_TOPIC = PREFIX + "CREATE_TOPIC"; + public static final String UPDATE_TOPIC = PREFIX + "UPDATE_TOPIC"; + public static final String GET_ALL_TOPICS_WITH_TRANSLATION = + PREFIX + "GET_ALL_TOPICS_WITH_TRANSLATION"; + public static final String GET_TOPICS_TRANSLATION_BY_ID = + PREFIX + "GET_TOPICS_TRANSLATION_BY_ID"; + + + } +} \ No newline at end of file diff --git a/src/main/java/de/caritas/cob/consultingtypeservice/api/auth/RoleAuthorizationAuthorityMapper.java b/src/main/java/de/caritas/cob/consultingtypeservice/api/auth/RoleAuthorizationAuthorityMapper.java new file mode 100644 index 00000000..abe9655c --- /dev/null +++ b/src/main/java/de/caritas/cob/consultingtypeservice/api/auth/RoleAuthorizationAuthorityMapper.java @@ -0,0 +1,40 @@ +package de.caritas.cob.consultingtypeservice.api.auth; + +import java.util.Collection; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; +import org.springframework.stereotype.Component; + +/** + * Own implementation of the Spring GrantedAuthoritiesMapper. + */ +@Component +public class RoleAuthorizationAuthorityMapper implements GrantedAuthoritiesMapper { + + @Override + public Collection mapAuthorities( + Collection authorities) { + Set roleNames = + authorities.stream() + .map(GrantedAuthority::getAuthority) + .map(String::toLowerCase) + .collect(Collectors.toSet()); + + return mapAuthorities(roleNames); + } + + private Set mapAuthorities(Set roleNames) { + return roleNames.parallelStream() + .map(UserRole::getRoleByValue) + .filter(Optional::isPresent) + .map(Optional::get) + .map(Authority::getAuthoritiesByUserRole) + .flatMap(Collection::parallelStream) + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toSet()); + } +} diff --git a/src/main/java/de/caritas/cob/consultingtypeservice/api/controller/ApplicationSettingsController.java b/src/main/java/de/caritas/cob/consultingtypeservice/api/controller/ApplicationSettingsController.java index 00fcf98d..fcaac914 100644 --- a/src/main/java/de/caritas/cob/consultingtypeservice/api/controller/ApplicationSettingsController.java +++ b/src/main/java/de/caritas/cob/consultingtypeservice/api/controller/ApplicationSettingsController.java @@ -6,6 +6,7 @@ import de.caritas.cob.consultingtypeservice.generated.api.controller.SettingsApi; import de.caritas.cob.consultingtypeservice.generated.api.controller.SettingsadminApi; import io.swagger.annotations.Api; +import java.util.Optional; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -15,8 +16,6 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.NativeWebRequest; -import java.util.Optional; - /** * Controller for consulting type API requests. */ @@ -46,7 +45,7 @@ public ResponseEntity getApplicationSettings() { } @Override - @PreAuthorize("hasAuthority('tenant-admin')") + @PreAuthorize("hasAuthority('AUTHORIZATION_PATCH_APPLICATION_SETTINGS')") public ResponseEntity patchApplicationSettings(ApplicationSettingsPatchDTO settingsPatchDTO) { applicationSettingsServiceFacade.patchApplicationSettings(settingsPatchDTO); var settings = applicationSettingsServiceFacade.getApplicationSettings(); diff --git a/src/main/java/de/caritas/cob/consultingtypeservice/api/controller/ConsultingTypeController.java b/src/main/java/de/caritas/cob/consultingtypeservice/api/controller/ConsultingTypeController.java index 124cc4d6..2324aff7 100644 --- a/src/main/java/de/caritas/cob/consultingtypeservice/api/controller/ConsultingTypeController.java +++ b/src/main/java/de/caritas/cob/consultingtypeservice/api/controller/ConsultingTypeController.java @@ -119,7 +119,7 @@ public ResponseEntity> getConsultingTypeGro } @Override - @PreAuthorize("hasAuthority('tenant-admin')") + @PreAuthorize("hasAuthority('AUTHORIZATION_CREATE_CONSULTING_TYPE')") public ResponseEntity createConsultingType( final ConsultingTypeDTO consultingTypeDTO) { return ResponseEntity.ok(consultingTypeService.createConsultingType(consultingTypeDTO)); diff --git a/src/main/java/de/caritas/cob/consultingtypeservice/api/controller/TopicAdminController.java b/src/main/java/de/caritas/cob/consultingtypeservice/api/controller/TopicAdminController.java index 49b70b6a..5379eaa5 100644 --- a/src/main/java/de/caritas/cob/consultingtypeservice/api/controller/TopicAdminController.java +++ b/src/main/java/de/caritas/cob/consultingtypeservice/api/controller/TopicAdminController.java @@ -29,7 +29,7 @@ public class TopicAdminController implements TopicadminApi { private AuthenticatedUser authenticatedUser; @Override - @PreAuthorize("hasAuthority('topic-admin')") + @PreAuthorize("hasAuthority('AUTHORIZATION_CREATE_TOPIC')") public ResponseEntity createTopic( @Valid final TopicMultilingualDTO topicMultilingualDTO) { log.info("Creating topic by user {} ", authenticatedUser.getUsername()); @@ -38,7 +38,7 @@ public ResponseEntity createTopic( } @Override - @PreAuthorize("hasAuthority('topic-admin')") + @PreAuthorize("hasAuthority('AUTHORIZATION_UPDATE_TOPIC')") public ResponseEntity updateTopic( final Long id, @Valid final TopicMultilingualDTO topicMultilingualDTO) { log.info("Updating topic with id {} by user {} ", id, authenticatedUser.getUsername()); @@ -48,7 +48,7 @@ public ResponseEntity updateTopic( } @Override - @PreAuthorize("hasAuthority('topic-admin')") + @PreAuthorize("hasAuthority('AUTHORIZATION_GET_ALL_TOPICS_WITH_TRANSLATION')") public ResponseEntity> getAllTopicsWithTranslation() { final var topics = topicServiceFacade.getAllTopicsMultilingual(); return !CollectionUtils.isEmpty(topics) @@ -57,7 +57,7 @@ public ResponseEntity> getAllTopicsWithTranslation() } @Override - @PreAuthorize("hasAuthority('topic-admin')") + @PreAuthorize("hasAuthority('AUTHORIZATION_GET_TOPICS_TRANSLATION_BY_ID')") public ResponseEntity getTopicWithTranslationById(final Long id) { return new ResponseEntity<>(topicServiceFacade.getTopicMultilingualById(id), HttpStatus.OK); } diff --git a/src/main/java/de/caritas/cob/consultingtypeservice/config/SecurityConfig.java b/src/main/java/de/caritas/cob/consultingtypeservice/config/SecurityConfig.java index eddef6b8..7ae5e266 100644 --- a/src/main/java/de/caritas/cob/consultingtypeservice/config/SecurityConfig.java +++ b/src/main/java/de/caritas/cob/consultingtypeservice/config/SecurityConfig.java @@ -1,5 +1,6 @@ package de.caritas.cob.consultingtypeservice.config; +import de.caritas.cob.consultingtypeservice.api.auth.RoleAuthorizationAuthorityMapper; import de.caritas.cob.consultingtypeservice.filter.HttpTenantFilter; import de.caritas.cob.consultingtypeservice.filter.StatelessCsrfFilter; import javax.annotation.Nullable; @@ -16,7 +17,6 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; @@ -117,9 +117,16 @@ protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { } @Autowired - public void configureGlobal(final AuthenticationManagerBuilder auth) { + public void configureGlobal(final AuthenticationManagerBuilder auth, + RoleAuthorizationAuthorityMapper authorityMapper) { final KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); - keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); + keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(authorityMapper); auth.authenticationProvider(keycloakAuthenticationProvider); } + + protected KeycloakAuthenticationProvider keycloakAuthenticationProvider() { + var provider = new KeycloakAuthenticationProvider(); + provider.setGrantedAuthoritiesMapper(new RoleAuthorizationAuthorityMapper()); + return provider; + } } diff --git a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/ApplicationSettingsControllerIT.java b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/ApplicationSettingsControllerIT.java index b3f7a009..ad978521 100644 --- a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/ApplicationSettingsControllerIT.java +++ b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/ApplicationSettingsControllerIT.java @@ -1,6 +1,8 @@ package de.caritas.cob.consultingtypeservice.api.controller; +import static de.caritas.cob.consultingtypeservice.api.auth.UserRole.TENANT_ADMIN; +import static de.caritas.cob.consultingtypeservice.api.auth.UserRole.TOPIC_ADMIN; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.springframework.http.MediaType.APPLICATION_JSON; @@ -19,6 +21,8 @@ import de.caritas.cob.consultingtypeservice.api.repository.ApplicationSettingsRepository; import de.caritas.cob.consultingtypeservice.api.tenant.TenantContext; import de.caritas.cob.consultingtypeservice.api.util.JsonConverter; +import java.util.Map; +import javax.servlet.http.Cookie; import org.assertj.core.util.Lists; import org.assertj.core.util.Maps; import org.assertj.core.util.Sets; @@ -41,9 +45,6 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import javax.servlet.http.Cookie; -import java.util.Map; - @SpringBootTest(classes = ConsultingTypeServiceApplication.class) @TestPropertySource(properties = "spring.profiles.active=testing") @TestPropertySource(properties = "feature.multitenancy.with.single.domain.enabled=true") @@ -104,7 +105,8 @@ void patchApplicationSettings_Should_ReturnUpdatedApplicationSettings_When_Patch throws Exception { // given giveApplicationSettingEntityWithDynamicReleaseToggles(); - final Authentication authentication = givenMockAuthentication(UserRole.TENANT_ADMIN); + AuthenticationMockBuilder builder = new AuthenticationMockBuilder(); + Authentication authentication = builder.withUserRole(TENANT_ADMIN.getValue()).build(); ApplicationSettingsPatchDTO patchDTO = new ApplicationSettingsPatchDTO(); patchDTO.setLegalContentChangesBySingleTenantAdminsAllowed( new ApplicationSettingsDTOMultitenancyWithSingleDomainEnabled().value(false) @@ -120,31 +122,33 @@ void patchApplicationSettings_Should_ReturnUpdatedApplicationSettings_When_Patch .contentType(javax.ws.rs.core.MediaType.APPLICATION_JSON) .content(jsonRequest) .contentType(javax.ws.rs.core.MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.multitenancyWithSingleDomainEnabled.value").value(true)) - .andExpect(jsonPath("$.multitenancyWithSingleDomainEnabled.readOnly").value(true)) - .andExpect(jsonPath("$.multitenancyEnabled.value").value(false)) - .andExpect(jsonPath("$.multitenancyEnabled.readOnly").value(true)) - .andExpect(jsonPath("$.useTenantService.value").value(true)) - .andExpect(jsonPath("$.useTenantService.readOnly").value(false)) - .andExpect(jsonPath("$.enableWalkthrough.value").value(false)) - .andExpect(jsonPath("$.enableWalkthrough.readOnly").value(false)) - .andExpect(jsonPath("$.disableVideoAppointments.value").value(true)) - .andExpect(jsonPath("$.disableVideoAppointments.readOnly").value(false)) - .andExpect(jsonPath("$.mainTenantSubdomainForSingleDomainMultitenancy.value").value("app2")) - .andExpect(jsonPath("$.mainTenantSubdomainForSingleDomainMultitenancy.readOnly").value(false)) - .andExpect(jsonPath("$.budibaseAuthClientId.value").value("budibaseAuthClientId")) - .andExpect(jsonPath("$.budibaseAuthClientId.readOnly").value(false)) - .andExpect(jsonPath("$.calcomUrl.value").value("calcomUrl")) - .andExpect(jsonPath("$.calcomUrl.readOnly").value(false)) - .andExpect(jsonPath("$.budibaseUrl.value").value("budibaseUrl")) - .andExpect(jsonPath("$.budibaseUrl.readOnly").value(false)) - .andExpect(jsonPath("$.calendarAppUrl.value").value("calendarAppUrl")) - .andExpect(jsonPath("$.calendarAppUrl.readOnly").value(false)) - .andExpect(jsonPath("$.useOverviewPage.value").value(false)) - .andExpect(jsonPath("$.useOverviewPage.readOnly").value(false)) - .andExpect(jsonPath("$.legalContentChangesBySingleTenantAdminsAllowed.value").value(false)) - .andExpect(jsonPath("$.legalContentChangesBySingleTenantAdminsAllowed.readOnly").value(false)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.multitenancyWithSingleDomainEnabled.value").value(true)) + .andExpect(jsonPath("$.multitenancyWithSingleDomainEnabled.readOnly").value(true)) + .andExpect(jsonPath("$.multitenancyEnabled.value").value(false)) + .andExpect(jsonPath("$.multitenancyEnabled.readOnly").value(true)) + .andExpect(jsonPath("$.useTenantService.value").value(true)) + .andExpect(jsonPath("$.useTenantService.readOnly").value(false)) + .andExpect(jsonPath("$.enableWalkthrough.value").value(false)) + .andExpect(jsonPath("$.enableWalkthrough.readOnly").value(false)) + .andExpect(jsonPath("$.disableVideoAppointments.value").value(true)) + .andExpect(jsonPath("$.disableVideoAppointments.readOnly").value(false)) + .andExpect(jsonPath("$.mainTenantSubdomainForSingleDomainMultitenancy.value").value("app2")) + .andExpect( + jsonPath("$.mainTenantSubdomainForSingleDomainMultitenancy.readOnly").value(false)) + .andExpect(jsonPath("$.budibaseAuthClientId.value").value("budibaseAuthClientId")) + .andExpect(jsonPath("$.budibaseAuthClientId.readOnly").value(false)) + .andExpect(jsonPath("$.calcomUrl.value").value("calcomUrl")) + .andExpect(jsonPath("$.calcomUrl.readOnly").value(false)) + .andExpect(jsonPath("$.budibaseUrl.value").value("budibaseUrl")) + .andExpect(jsonPath("$.budibaseUrl.readOnly").value(false)) + .andExpect(jsonPath("$.calendarAppUrl.value").value("calendarAppUrl")) + .andExpect(jsonPath("$.calendarAppUrl.readOnly").value(false)) + .andExpect(jsonPath("$.useOverviewPage.value").value(false)) + .andExpect(jsonPath("$.useOverviewPage.readOnly").value(false)) + .andExpect(jsonPath("$.legalContentChangesBySingleTenantAdminsAllowed.value").value(false)) + .andExpect( + jsonPath("$.legalContentChangesBySingleTenantAdminsAllowed.readOnly").value(false)) .andExpect(jsonPath("$.releaseToggles.featureToggleTenantCreationEnabled").value(true)); // clean up @@ -173,18 +177,21 @@ private void resetSettingsToPreviousState(Authentication authentication) throws @Test void patchApplicationSettings_Should_ReturnForbidden_When_UserNameDoesNotHavePermissionToPatchSettings() throws Exception { - final Authentication authentication = givenMockAuthentication(UserRole.TOPIC_ADMIN); + AuthenticationMockBuilder builder = new AuthenticationMockBuilder(); + ApplicationSettingsPatchDTO patchDTO = new ApplicationSettingsPatchDTO(); - patchDTO.setLegalContentChangesBySingleTenantAdminsAllowed(new ApplicationSettingsDTOMultitenancyWithSingleDomainEnabled().value(false).readOnly(true)); + patchDTO.setLegalContentChangesBySingleTenantAdminsAllowed( + new ApplicationSettingsDTOMultitenancyWithSingleDomainEnabled().value(false) + .readOnly(true)); String jsonRequest = JsonConverter.convertToJson(patchDTO); mockMvc.perform(patch("/settingsadmin") - .with(authentication(authentication)) - .header("csrfHeader", "csrfToken") - .cookie(new Cookie("csrfCookie", "csrfToken")) - .contentType(javax.ws.rs.core.MediaType.APPLICATION_JSON) - .content(jsonRequest) - .contentType(javax.ws.rs.core.MediaType.APPLICATION_JSON)) - .andExpect(status().isForbidden()); + .with(authentication(builder.withUserRole(TOPIC_ADMIN.getValue()).build())) + .header("csrfHeader", "csrfToken") + .cookie(new Cookie("csrfCookie", "csrfToken")) + .contentType(javax.ws.rs.core.MediaType.APPLICATION_JSON) + .content(jsonRequest) + .contentType(javax.ws.rs.core.MediaType.APPLICATION_JSON)) + .andExpect(status().isForbidden()); } private void giveApplicationSettingEntityWithDynamicReleaseToggles() { @@ -195,17 +202,15 @@ private void giveApplicationSettingEntityWithDynamicReleaseToggles() { } private Authentication givenMockAuthentication(final UserRole authority) { - final var securityContext = mock( - RefreshableKeycloakSecurityContext.class); + final var securityContext = mock(RefreshableKeycloakSecurityContext.class); when(securityContext.getTokenString()).thenReturn("tokenString"); final var token = mock(AccessToken.class, Mockito.RETURNS_DEEP_STUBS); when(securityContext.getToken()).thenReturn(token); givenOtherClaimsAreDefinedForToken(token); final KeycloakAccount mockAccount = new SimpleKeycloakAccount(() -> "user", Sets.newHashSet(), - securityContext); - final Authentication authentication = new KeycloakAuthenticationToken(mockAccount, true, - Lists.newArrayList((GrantedAuthority) () -> authority.getValue())); - return authentication; + securityContext); + return new KeycloakAuthenticationToken(mockAccount, true, + Lists.newArrayList((GrantedAuthority) authority::getValue)); } private void givenOtherClaimsAreDefinedForToken(final AccessToken token) { diff --git a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/AuthenticationMockBuilder.java b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/AuthenticationMockBuilder.java index b2253435..2a618038 100644 --- a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/AuthenticationMockBuilder.java +++ b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/AuthenticationMockBuilder.java @@ -1,6 +1,7 @@ package de.caritas.cob.consultingtypeservice.api.controller; import com.google.common.collect.Lists; +import de.caritas.cob.consultingtypeservice.api.auth.RoleAuthorizationAuthorityMapper; import java.util.Collection; import org.keycloak.KeycloakPrincipal; import org.keycloak.KeycloakSecurityContext; @@ -10,16 +11,11 @@ public class AuthenticationMockBuilder { - private String authority; + private String userRole; private String tenantId; - AuthenticationMockBuilder withAuthority(String authority) { - this.authority = authority; - return this; - } - - AuthenticationMockBuilder withTenantIdAttribute(String tenantId) { - this.tenantId = tenantId; + AuthenticationMockBuilder withUserRole(String userRole) { + this.userRole = userRole; return this; } @@ -27,7 +23,8 @@ public Authentication build() { return new Authentication() { @Override public Collection getAuthorities() { - return Lists.newArrayList((GrantedAuthority) () -> authority); + return new RoleAuthorizationAuthorityMapper() + .mapAuthorities(Lists.newArrayList(() -> userRole)); } @Override diff --git a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/ConsultingTypeControllerE2EIT.java b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/ConsultingTypeControllerE2EIT.java index d07c989c..90b40989 100644 --- a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/ConsultingTypeControllerE2EIT.java +++ b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/ConsultingTypeControllerE2EIT.java @@ -1,7 +1,9 @@ package de.caritas.cob.consultingtypeservice.api.controller; +import static de.caritas.cob.consultingtypeservice.api.auth.UserRole.TENANT_ADMIN; import static de.caritas.cob.consultingtypeservice.testHelper.PathConstants.ROOT_PATH; import static net.javacrumbs.jsonunit.spring.JsonUnitResultMatchers.json; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -48,10 +50,11 @@ public class ConsultingTypeControllerE2EIT { @Test - @WithMockUser(authorities = {"tenant-admin"}) public void createConsultingType_Should_returnOk_When_requiredConsultingTypeDTOIsGiven() throws Exception { // given + AuthenticationMockBuilder builder = new AuthenticationMockBuilder(); + ConsultingTypeDTO consultingTypeDTO = easyRandom.nextObject(ConsultingTypeDTO.class) .tenantId(4) @@ -65,6 +68,7 @@ public void createConsultingType_Should_returnOk_When_requiredConsultingTypeDTOI this.mvc .perform( post(ROOT_PATH) + .with(authentication(builder.withUserRole(TENANT_ADMIN.getValue()).build())) .cookie(CSRF_COOKIE) .header(CSRF_HEADER, CSRF_VALUE) .contentType(MediaType.APPLICATION_JSON) diff --git a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicAdminControllerIT.java b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicAdminControllerIT.java index c31b592f..ac632e26 100644 --- a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicAdminControllerIT.java +++ b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicAdminControllerIT.java @@ -1,5 +1,6 @@ package de.caritas.cob.consultingtypeservice.api.controller; +import static de.caritas.cob.consultingtypeservice.api.auth.UserRole.TOPIC_ADMIN; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasSize; @@ -22,7 +23,6 @@ import de.caritas.cob.consultingtypeservice.api.util.MultilingualTopicTestDataBuilder; import de.caritas.cob.consultingtypeservice.testHelper.TopicPathConstants; import java.util.Map; -import org.assertj.core.util.Lists; import org.assertj.core.util.Maps; import org.assertj.core.util.Sets; import org.jeasy.random.EasyRandom; @@ -39,7 +39,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @@ -71,9 +70,10 @@ void createTopic_Should_returnStatusBadRequest_When_calledWithInvalidCreateParam final TopicMultilingualDTO topicDTO = easyRandom.nextObject(TopicMultilingualDTO.class); topicDTO.setStatus("invalid status"); final String payload = JsonConverter.convertToJson(topicDTO); - final Authentication authentication = givenMockAuthentication(UserRole.TOPIC_ADMIN); + AuthenticationMockBuilder builder = new AuthenticationMockBuilder(); + mockMvc.perform(post(TopicPathConstants.ADMIN_ROOT_PATH) - .with(authentication(authentication)) + .with(authentication(builder.withUserRole(TOPIC_ADMIN.getValue()).build())) .contentType(APPLICATION_JSON) .content(payload) .contentType(APPLICATION_JSON)) @@ -115,7 +115,7 @@ void createTopic_Should_returnBadRequest_When_calledWithValidCreateParamsAndVali final String payload = JsonConverter.convertToJson(topicDTO); final AuthenticationMockBuilder builder = new AuthenticationMockBuilder(); mockMvc.perform(post(TopicPathConstants.ADMIN_ROOT_PATH) - .with(authentication(builder.withAuthority(UserRole.TOPIC_ADMIN.getValue()).build())) + .with(authentication(builder.withUserRole(TOPIC_ADMIN.getValue()).build())) .contentType(APPLICATION_JSON) .content(payload) .contentType(APPLICATION_JSON)) @@ -143,7 +143,7 @@ void createTopic_Should_returnForbidden_When_calledWithValidCreateParamsButWitho final String payload = JsonConverter.convertToJson(topicDTO); final AuthenticationMockBuilder builder = new AuthenticationMockBuilder(); mockMvc.perform(post(TopicPathConstants.ADMIN_ROOT_PATH) - .with(authentication(builder.withAuthority("another-authority").build())) + .with(authentication(builder.withUserRole("another-authority").build())) .content(payload) .contentType(APPLICATION_JSON)) .andExpect(status().isForbidden()); @@ -187,7 +187,7 @@ void getAllTopicsWithTranslation_Should_ReturnTopicsList_When_UserIsAuthenticate mockMvc.perform( get(TopicPathConstants.ADMIN_PATH_GET_TOPIC_LIST) .with( - authentication(builder.withAuthority(UserRole.TOPIC_ADMIN.getValue()).build())) + authentication(builder.withUserRole(TOPIC_ADMIN.getValue()).build())) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$", hasSize(greaterThan(1)))) @@ -205,7 +205,7 @@ void getTopicWithTranslationById_Should_ReturnTopic_When_UserIsAuthenticated() mockMvc.perform( get(String.format(TopicPathConstants.ADMIN_PATH_GET_TOPIC_BY_ID, 1)) .with( - authentication(builder.withAuthority(UserRole.TOPIC_ADMIN.getValue()).build())) + authentication(builder.withUserRole(TOPIC_ADMIN.getValue()).build())) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.id").value(1)) @@ -224,7 +224,7 @@ void getTopicList_Should_ReturnForbidden_When_UserIsNotAuthenticated() .andExpect(status().isForbidden()); } - private Authentication givenMockAuthentication(final UserRole authority) { + private Authentication givenMockAuthentication(final UserRole userRole) { final var securityContext = mock( RefreshableKeycloakSecurityContext.class); when(securityContext.getTokenString()).thenReturn("tokenString"); @@ -233,9 +233,11 @@ private Authentication givenMockAuthentication(final UserRole authority) { givenOtherClaimsAreDefinedForToken(token); final KeycloakAccount mockAccount = new SimpleKeycloakAccount(() -> "user", Sets.newHashSet(), securityContext); - final Authentication authentication = new KeycloakAuthenticationToken(mockAccount, true, - Lists.newArrayList((GrantedAuthority) () -> authority.getValue())); - return authentication; + + Authentication authentication = new AuthenticationMockBuilder().withUserRole( + userRole.getValue()).build(); + return new KeycloakAuthenticationToken(mockAccount, true, + authentication.getAuthorities()); } private void givenOtherClaimsAreDefinedForToken(final AccessToken token) { diff --git a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicControllerIT.java b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicControllerIT.java index 425256e7..728cda71 100644 --- a/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicControllerIT.java +++ b/src/test/java/de/caritas/cob/consultingtypeservice/api/controller/TopicControllerIT.java @@ -51,7 +51,7 @@ void getTopicList_Should_ReturnTopicsList_When_UserIsAuthenticated() mockMvc.perform( get(TopicPathConstants.PATH_GET_TOPIC_LIST) .with( - authentication(builder.withAuthority(UserRole.TOPIC_ADMIN.getValue()).build())) + authentication(builder.withUserRole(UserRole.TOPIC_ADMIN.getValue()).build())) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$", hasSize(greaterThan(1))))