diff --git a/src/main/java/de/ozgcloud/admin/RootModelAssembler.java b/src/main/java/de/ozgcloud/admin/RootModelAssembler.java index 9dc67f2473913fb27836036b62abb8339266cdd4..4feced27c6e16b2ecfc4837c17adf9a8e3468bbe 100644 --- a/src/main/java/de/ozgcloud/admin/RootModelAssembler.java +++ b/src/main/java/de/ozgcloud/admin/RootModelAssembler.java @@ -33,8 +33,6 @@ import org.springframework.hateoas.server.RepresentationModelAssembler; import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder; import org.springframework.stereotype.Component; -import de.ozgcloud.admin.common.user.CurrentUserService; -import de.ozgcloud.admin.common.user.UserRole; import lombok.RequiredArgsConstructor; @Component @@ -44,8 +42,6 @@ public class RootModelAssembler implements RepresentationModelAssembler<Root, En private final RepositoryRestProperties restProperties; - private final CurrentUserService currentUserService; - @Override public EntityModel<Root> toModel(Root root) { List<Link> links = buildRootModelLinks(); @@ -56,10 +52,7 @@ public class RootModelAssembler implements RepresentationModelAssembler<Root, En List<Link> links = new ArrayList<>(); var rootLinkBuilder = WebMvcLinkBuilder.linkTo(RootController.class); links.add(rootLinkBuilder.withSelfRel()); - - if (currentUserService.hasRole(UserRole.ADMIN_ADMIN)) { - links.add(buildConfigLink()); - } + links.add(buildConfigLink()); return links; } diff --git a/src/main/java/de/ozgcloud/admin/common/DtoService.java b/src/main/java/de/ozgcloud/admin/common/DtoService.java index 171d5ad4bbbeb49eda1fc481fd7dab2d68484e28..7feaa87325896549ea0052c06d936c59452a6c51 100644 --- a/src/main/java/de/ozgcloud/admin/common/DtoService.java +++ b/src/main/java/de/ozgcloud/admin/common/DtoService.java @@ -23,17 +23,10 @@ */ package de.ozgcloud.admin.common; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - import org.springframework.stereotype.Service; @Service -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) public @interface DtoService { - String value(); + String[] value(); } diff --git a/src/main/java/de/ozgcloud/admin/reporting/AggregationMapping.java b/src/main/java/de/ozgcloud/admin/reporting/AggregationMapping.java index f3469758c2d1702b744abd39fa5b7204108f10c3..dba1cf9fbab44be2716928751783371b192bbcd5 100644 --- a/src/main/java/de/ozgcloud/admin/reporting/AggregationMapping.java +++ b/src/main/java/de/ozgcloud/admin/reporting/AggregationMapping.java @@ -42,7 +42,7 @@ import lombok.ToString; import lombok.extern.jackson.Jacksonized; @Document("settings") -@TypeAlias("aggregationMapping") +@TypeAlias("AggregationMapping") @Jacksonized @Builder @Getter diff --git a/src/main/java/de/ozgcloud/admin/reporting/AggregationMappingRepository.java b/src/main/java/de/ozgcloud/admin/reporting/AggregationMappingRepository.java index 4de72d0347445e53101bcb76b9a1ab755958918a..249aa175f5c7a313ba1e69dd178926fd29c8f2a0 100644 --- a/src/main/java/de/ozgcloud/admin/reporting/AggregationMappingRepository.java +++ b/src/main/java/de/ozgcloud/admin/reporting/AggregationMappingRepository.java @@ -34,6 +34,6 @@ import org.springframework.security.access.annotation.Secured; @RepositoryRestResource interface AggregationMappingRepository extends MongoRepository<AggregationMapping, String> { @Override - @Query("{'_class': 'aggregationMapping'}") + @Query("{'_class': 'AggregationMapping'}") List<AggregationMapping> findAll(); } diff --git a/src/main/java/de/ozgcloud/admin/setting/SettingEnvironmentRepository.java b/src/main/java/de/ozgcloud/admin/setting/SettingEnvironmentRepository.java index dfe17a508e03e1a2fab7b31945dd05701c2fb51c..a6e74eac7d909eeefc363eebb43cb5cf078e49e5 100644 --- a/src/main/java/de/ozgcloud/admin/setting/SettingEnvironmentRepository.java +++ b/src/main/java/de/ozgcloud/admin/setting/SettingEnvironmentRepository.java @@ -56,14 +56,14 @@ public class SettingEnvironmentRepository implements EnvironmentRepository { Optional<ApplicationSettingDTO> findAnwendungSettingDTO(String application) { switch (application) { - case ALFA: - return Optional.of(settingService.getAlfaSettingDTO()); - case VORGANG_MANAGER: - return Optional.of(settingService.getVorgangManagerSettingDTO()); - case AGGREGATION_MANAGER: - return Optional.of(settingService.getAggregationManagerSettingDto()); - default: - return Optional.empty(); + case ALFA: + return Optional.of(settingService.getAlfaSettingDTO()); + case VORGANG_MANAGER: + return Optional.of(settingService.getVorgangManagerSettingDTO()); + case AGGREGATION_MANAGER: + return Optional.of(settingService.getAggregationManagerSettingDto()); + default: + return Optional.empty(); } } diff --git a/src/main/java/de/ozgcloud/admin/setting/SettingRepository.java b/src/main/java/de/ozgcloud/admin/setting/SettingRepository.java index 5180dea45a85d6007717a4e2a3d64cbb6ad7c6d9..1cfb2957c475cab3d49346738f0aa331f0428e9f 100644 --- a/src/main/java/de/ozgcloud/admin/setting/SettingRepository.java +++ b/src/main/java/de/ozgcloud/admin/setting/SettingRepository.java @@ -27,7 +27,9 @@ import java.util.Optional; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.rest.core.annotation.RepositoryRestResource; +import org.springframework.security.access.annotation.Secured; +@Secured("ROLE_ADMIN_ADMIN") @RepositoryRestResource(collectionResourceRel = SettingConstants.REL, path = SettingConstants.PATH) interface SettingRepository extends MongoRepository<Setting, String> { diff --git a/src/main/java/de/ozgcloud/admin/setting/SettingService.java b/src/main/java/de/ozgcloud/admin/setting/SettingService.java index ef6a78f31301e24fc225ce6e7f12d84772d71e1c..aa9c8e2d7eea1a4eadf373331b4c369578968218 100644 --- a/src/main/java/de/ozgcloud/admin/setting/SettingService.java +++ b/src/main/java/de/ozgcloud/admin/setting/SettingService.java @@ -25,16 +25,21 @@ package de.ozgcloud.admin.setting; import static de.ozgcloud.admin.setting.SettingConstants.*; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import java.util.stream.Stream; import jakarta.annotation.PostConstruct; +import org.apache.commons.lang3.tuple.Pair; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.stereotype.Service; +import static java.util.stream.Collectors.*; + import de.ozgcloud.admin.common.DtoService; import de.ozgcloud.admin.common.SettingDtoService; import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheitSettings; @@ -57,13 +62,14 @@ class SettingService { @PostConstruct void initDtoServices() { this.dtoServiceByManager = beanFactory.getBeansWithAnnotation(DtoService.class).values().stream() - .map(dtoService -> (SettingDtoService) dtoService) - .collect(Collectors.groupingBy(dtoService -> getManagerForService(dtoService))); + .map(SettingDtoService.class::cast) + .flatMap(this::getManagerForService) + .collect(Collectors.groupingBy(Pair::getKey, mapping(Pair::getValue, toList()))); } - private String getManagerForService(SettingDtoService dtoService) { + private Stream<Pair<String, SettingDtoService>> getManagerForService(SettingDtoService dtoService) { var annotation = dtoService.getClass().getDeclaredAnnotation(DtoService.class); - return annotation.value(); + return Arrays.stream(annotation.value()).map(manager -> Pair.of(manager, dtoService)); } public AlfaSettingDTO getAlfaSettingDTO() { @@ -87,17 +93,6 @@ class SettingService { .build(); } - public ApplicationSettingDTO getAggregationManagerSettingDto() { - return MapBasedApplicationSettingDto.builder() - .settings(getDtoService(AGGREGATION_MANAGER).stream() - .collect(Collectors.toMap(SettingDtoService::getSettingKeyName, SettingDtoService::getDataTransferObject))) - .build(); - } - - private List<SettingDtoService> getDtoService(String managerName) { - return dtoServiceByManager.getOrDefault(managerName, Collections.emptyList()); - } - PostfachSettingBody getSettingWithPostfachFromDb() { return repository.findOneByName(POSTFACH_SETTING_ITEM_NAME) .map(Setting::getSettingBody) @@ -111,4 +106,19 @@ class SettingService { OrganisationsEinheitWithSettings::settings)); } + public ApplicationSettingDTO getAggregationManagerSettingDto() { + return MapBasedApplicationSettingDto.builder() + .settings(buildSettingsMap(AGGREGATION_MANAGER)) + .build(); + } + + private Map<String, Object> buildSettingsMap(String managerName) { + return getDtoService(managerName).stream() + .collect(Collectors.toMap(SettingDtoService::getSettingKeyName, SettingDtoService::getDataTransferObject)); + } + + private List<SettingDtoService> getDtoService(String managerName) { + return dtoServiceByManager.getOrDefault(managerName, Collections.emptyList()); + } + } diff --git a/src/test/java/de/ozgcloud/admin/OzgCloudDelegatingResourceMetadataTest.java b/src/test/java/de/ozgcloud/admin/OzgCloudDelegatingResourceMetadataTest.java index 149b600f9dd83e9bb2bb3b1e0488ef72c143e9fa..12253c9025542a549059c4979f7cbc458c151c36 100644 --- a/src/test/java/de/ozgcloud/admin/OzgCloudDelegatingResourceMetadataTest.java +++ b/src/test/java/de/ozgcloud/admin/OzgCloudDelegatingResourceMetadataTest.java @@ -14,6 +14,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; +import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.repository.support.Repositories; import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.security.authorization.AuthorizationDecision; @@ -38,10 +39,6 @@ class OzgCloudDelegatingResourceMetadataTest { @Nested class TestIsExported { - void initDefaults() { - doReturn(true).when(delegatingResourceMetadata).isAccessPermitted(any()); - } - @Test void shouldReturnTrue() { when(metadata.isExported()).thenReturn(true); @@ -79,11 +76,13 @@ class OzgCloudDelegatingResourceMetadataTest { @Mock private AuthorizationDecision decision; + private final MethodInvocation invocation = Mockito.mock(MethodInvocation.class); + @BeforeEach void initMock() { when(repositories.getRepositoryFor(any())).thenReturn(Optional.of(repository)); - doReturn(Mockito.mock(MethodInvocation.class)).when(delegatingResourceMetadata).getFindAllInvocation(any()); + doReturn(invocation).when(delegatingResourceMetadata).getFindAllInvocation(any()); } @BeforeEach @@ -93,6 +92,13 @@ class OzgCloudDelegatingResourceMetadataTest { ReflectionTestUtils.setField(delegatingResourceMetadata, "authManager", authManager); } + @Test + void shouldCallDecisionManager() { + delegatingResourceMetadata.isAccessPermitted(Object.class); + + verify(decision).isGranted(); + } + @Test void shouldReturnTrueIfGranted() { when(decision.isGranted()).thenReturn(true); @@ -111,6 +117,13 @@ class OzgCloudDelegatingResourceMetadataTest { assertThat(result).isFalse(); } + @Test + void shouldCallAuthManager() { + delegatingResourceMetadata.isAccessPermitted(Object.class); + + verify(authManager).check(any(), eq(invocation)); + } + @Test void shouldReturnTrueIfNotSecured() { when(authManager.check(any(), any())).thenReturn(null); @@ -123,9 +136,16 @@ class OzgCloudDelegatingResourceMetadataTest { @Nested class TestGetFindAllInvocation { + + @Mock + private MongoRepository<String, Object> repository; + @Test void shouldReturnMethod() { + var method = delegatingResourceMetadata.getFindAllInvocation(repository); + assertThat(method).isNotNull() + .extracting(invocation -> invocation.getMethod().getName()).isEqualTo("findAll"); } } diff --git a/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java b/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java index 0427eb6fbed96cef7143a875cb42d6510654c6ce..5c4ed0d6bc38bf1c40399d0fad93cc488644b05d 100644 --- a/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java +++ b/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java @@ -39,9 +39,6 @@ import org.mockito.Spy; import org.springframework.boot.autoconfigure.data.rest.RepositoryRestProperties; import org.springframework.hateoas.Link; -import de.ozgcloud.admin.common.user.CurrentUserService; -import de.ozgcloud.admin.common.user.UserRole; - class RootModelAssemblerTest { private static final String BASE_PATH = "/api/base"; @@ -51,15 +48,12 @@ class RootModelAssemblerTest { @Mock private RepositoryRestProperties restProperties; - @Mock - private CurrentUserService currentUserService; @DisplayName("Entity Model") @Nested class TestEntityModel { @BeforeEach void beforeEach() { - Mockito.when(currentUserService.hasRole(UserRole.ADMIN_ADMIN)).thenReturn(true); Mockito.when(restProperties.getBasePath()).thenReturn(BASE_PATH); } @@ -92,7 +86,6 @@ class RootModelAssemblerTest { @Test void shouldHaveHrefToBasePathIfAuthorized() { Mockito.when(restProperties.getBasePath()).thenReturn(BASE_PATH); - Mockito.when(currentUserService.hasRole(UserRole.ADMIN_ADMIN)).thenReturn(true); List<Link> links = modelAssembler.buildRootModelLinks(); @@ -101,15 +94,6 @@ class RootModelAssemblerTest { Link.of(BASE_PATH, REL_CONFIGURATION)); } - @Test - void shouldNotHaveHrefToBasePathIfUnauthorized() { - Mockito.when(currentUserService.hasRole(UserRole.ADMIN_ADMIN)).thenReturn(false); - - List<Link> links = modelAssembler.buildRootModelLinks(); - - assertThat(links).containsExactly( - Link.of(RootController.PATH)); - } } } \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingDtoTestFactory.java b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingDtoTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..f0c601d43a316e0456cd6b73acd012535d1d6033 --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingDtoTestFactory.java @@ -0,0 +1,22 @@ +package de.ozgcloud.admin.reporting; + +import static de.ozgcloud.admin.reporting.AggregationMappingTestFactory.*; + +import de.ozgcloud.admin.reporting.ReportingAggregationManagerSettingDto.AggregationMappingDto; +import de.ozgcloud.admin.reporting.ReportingAggregationManagerSettingDto.FieldMappingDto; +import de.ozgcloud.admin.reporting.ReportingAggregationManagerSettingDto.FormIdentifierDto; + +public class AggregationMappingDtoTestFactory { + + public static final FormIdentifierDto FORM_IDENTIFIER = FormIdentifierDto.builder().formId(FORM_ID).formEngineName(FORM_ENGINE_NAME).build(); + + public static AggregationMappingDto create() { + return createBuilder().build(); + } + + public static AggregationMappingDto.AggregationMappingDtoBuilder createBuilder() { + return AggregationMappingDto.builder() + .formIdentifier(FORM_IDENTIFIER) + .fieldMapping(FieldMappingDto.builder().sourcePath(SOURCE_PATH).targetPath(TARGET_PATH).build()); + } +} diff --git a/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingMapperTest.java b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6f98c2ede8306f10acc1d5fd7e75c7da9b0662cd --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingMapperTest.java @@ -0,0 +1,26 @@ +package de.ozgcloud.admin.reporting; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; + +class AggregationMappingMapperTest { + + @InjectMocks + private AggregationMappingMapper mapper = Mappers.getMapper(AggregationMappingMapper.class); + + @Nested + class TestToMapping { + + @Test + void shouldMapToDto() { + var dto = mapper.toMapping(AggregationMappingTestFactory.create()); + + assertThat(dto).usingRecursiveComparison().isEqualTo(AggregationMappingDtoTestFactory.create()); + } + } + +} diff --git a/src/test/java/de/ozgcloud/admin/reporting/ReportingSettingRepositoryITCase.java b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingRepositoryITCase.java similarity index 84% rename from src/test/java/de/ozgcloud/admin/reporting/ReportingSettingRepositoryITCase.java rename to src/test/java/de/ozgcloud/admin/reporting/AggregationMappingRepositoryITCase.java index 1b47da2c89b1828ddadeb480759f70efce9a4b9d..a92bcc6b3e210f27a066f54f3dc28db551f45086 100644 --- a/src/test/java/de/ozgcloud/admin/reporting/ReportingSettingRepositoryITCase.java +++ b/src/test/java/de/ozgcloud/admin/reporting/AggregationMappingRepositoryITCase.java @@ -29,6 +29,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.security.authorization.AuthorizationDeniedException; import org.springframework.security.test.context.support.WithMockUser; import de.ozgcloud.admin.common.user.UserRole; @@ -36,7 +37,7 @@ import de.ozgcloud.admin.setting.SettingTestFactory; import de.ozgcloud.common.test.DataITCase; @DataITCase -class ReportingSettingRepositoryITCase { +class AggregationMappingRepositoryITCase { @Autowired private AggregationMappingRepository repository; @@ -60,4 +61,12 @@ class ReportingSettingRepositoryITCase { assertThat(result).hasSize(1); } + @Test + @WithMockUser + void shouldThrowExceptionOnMissingRole() { + operations.save(AggregationMappingTestFactory.create()); + + assertThatThrownBy(() -> repository.findAll()).isInstanceOf(AuthorizationDeniedException.class); + } + } diff --git a/src/test/java/de/ozgcloud/admin/reporting/ReportingSettingDtoTestFactory.java b/src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationMAnagerSettingDtoTestFactory.java similarity index 63% rename from src/test/java/de/ozgcloud/admin/reporting/ReportingSettingDtoTestFactory.java rename to src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationMAnagerSettingDtoTestFactory.java index 255febc4cb7555ddafe13cef9c30552d7c11a1aa..27dc2735fa90521e76642ad8eda61e74c308db75 100644 --- a/src/test/java/de/ozgcloud/admin/reporting/ReportingSettingDtoTestFactory.java +++ b/src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationMAnagerSettingDtoTestFactory.java @@ -23,15 +23,7 @@ */ package de.ozgcloud.admin.reporting; -import static de.ozgcloud.admin.reporting.AggregationMappingTestFactory.*; - -import de.ozgcloud.admin.reporting.ReportingAggregationManagerSettingDto.AggregationMappingDto; -import de.ozgcloud.admin.reporting.ReportingAggregationManagerSettingDto.FieldMappingDto; -import de.ozgcloud.admin.reporting.ReportingAggregationManagerSettingDto.FormIdentifierDto; - -class ReportingSettingDtoTestFactory { - - public static final FormIdentifierDto FORM_IDENTIFIER = FormIdentifierDto.builder().formId(FORM_ID).formEngineName(FORM_ENGINE_NAME).build(); +class ReportingAggregationMAnagerSettingDtoTestFactory { public static ReportingAggregationManagerSettingDto create() { return createBuilder().build(); @@ -39,10 +31,7 @@ class ReportingSettingDtoTestFactory { public static ReportingAggregationManagerSettingDto.ReportingAggregationManagerSettingDtoBuilder createBuilder() { return ReportingAggregationManagerSettingDto.builder() - .aggregationMapping(AggregationMappingDto.builder() - .formIdentifier(FORM_IDENTIFIER) - .fieldMapping(FieldMappingDto.builder().sourcePath(SOURCE_PATH).targetPath(TARGET_PATH).build()) - .build()); + .aggregationMapping(AggregationMappingDtoTestFactory.create()); } } diff --git a/src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDtoServiceTest.java b/src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDtoServiceTest.java index 8551bdabd9a7f2e79242c10218bb2f0fc8f21546..dc5c554d9765b0390e5510f5efe99645c4152637 100644 --- a/src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDtoServiceTest.java +++ b/src/test/java/de/ozgcloud/admin/reporting/ReportingAggregationManagerSettingDtoServiceTest.java @@ -24,29 +24,83 @@ package de.ozgcloud.admin.reporting; import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; +import java.util.List; import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.mapstruct.factory.Mappers; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.InjectMocks; +import org.mockito.Mock; import org.mockito.Spy; class ReportingAggregationManagerSettingDtoServiceTest { + @Spy @InjectMocks private ReportingAggregationManagerSettingDtoService service; - @Spy - private AggregationMappingMapper mapper = Mappers.getMapper(AggregationMappingMapper.class); + + @Mock + private AggregationMappingMapper mapper; + @Mock + private AggregationMappingRepository repository; @Nested class TestMapToDto { + + @BeforeEach + void setupMapperMock() { + when(mapper.toMapping(any())).thenReturn(AggregationMappingDtoTestFactory.create()); + } + @Test - void shouldCreateDto() { + void shouldCallMapper() { + var mapping = AggregationMappingTestFactory.create(); + service.mapToDto(Stream.of(mapping)); + + verify(mapper).toMapping(mapping); + } + + @Test + void shouldBuildDto() { var dto = service.mapToDto(Stream.of(AggregationMappingTestFactory.create())); - assertThat(dto).usingRecursiveComparison().isEqualTo(ReportingSettingDtoTestFactory.create()); + assertThat(dto).usingRecursiveComparison().isEqualTo(ReportingAggregationMAnagerSettingDtoTestFactory.create()); + } + } + + @Nested + class TestGetDataTransferObject { + + @Captor + private ArgumentCaptor<Stream<AggregationMapping>> streamCaptor; + + @BeforeEach + void disableMapToDtoFunction() { + doReturn(ReportingAggregationMAnagerSettingDtoTestFactory.create()).when(service).mapToDto(any()); + } + + @Test + void shouldCallRepository() { + service.getDataTransferObject(); + + verify(repository).findAll(); + } + + @Test + void shouldCallMapToDto() { + AggregationMapping mapping = AggregationMappingTestFactory.create(); + when(repository.findAll()).thenReturn(List.of(mapping)); + + service.getDataTransferObject(); + + verify(service).mapToDto(streamCaptor.capture()); + assertThat(streamCaptor.getValue()).contains(mapping); } } diff --git a/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationTest.java b/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationTest.java index 9e03568d021fb77b90c64e4b9e4c1154c4fea4c8..c84999918e651d428abdb93d54e6dff5f0c7eb35 100644 --- a/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationTest.java +++ b/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationTest.java @@ -23,11 +23,33 @@ */ package de.ozgcloud.admin.security; +import static de.ozgcloud.admin.security.SecurityConfiguration.*; +import static java.util.Collections.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.core.oidc.StandardClaimNames; +import org.springframework.security.oauth2.jwt.Jwt; + +import com.thedeanda.lorem.LoremIpsum; import de.ozgcloud.admin.environment.OAuth2Properties; @@ -45,111 +67,115 @@ class SecurityConfigurationTest { class TestJwtAuthenticationConverter { private final String roleString = "ROLE_Test"; - /* - * @BeforeEach void mock() { doReturn(Set.of(new - * SimpleGrantedAuthority(roleString))).when(securityConfiguration). - * convertJwtToGrantedAuthorities(any()); } - * - * @DisplayName("should use preferred_username") - * - * @Test void shouldUsePreferredUsername() { var preferredName = - * LoremIpsum.getInstance().getName(); var jwtWithPreferredName = - * JwtTestFactory.createBuilder() .claim(StandardClaimNames.PREFERRED_USERNAME, - * preferredName) .build(); - * - * var jwtAuthenticationConverter = - * securityConfiguration.jwtAuthenticationConverter(); - * - * var abstractAuthenticationToken = - * jwtAuthenticationConverter.convert(jwtWithPreferredName); - * assertThat(abstractAuthenticationToken.getName()).isEqualTo(preferredName); } - * - * @DisplayName("should use granted authorities converter") - * - * @Test void shouldUseGrantedAuthoritiesConverter() { var jwtWithRoles = - * JwtTestFactory.create(); - * - * var jwtAuthenticationConverter = - * securityConfiguration.jwtAuthenticationConverter(); - * - * var abstractAuthenticationToken = - * jwtAuthenticationConverter.convert(jwtWithRoles); var securityRoleStrings = - * abstractAuthenticationToken.getAuthorities().stream().map(GrantedAuthority:: - * getAuthority).toList(); - * - * assertThat(securityRoleStrings).isEqualTo(List.of(roleString)); } } - * - * @DisplayName("convert jwt to granted authorities") - * - * @Nested class TestConvertJwtToGrantedAuthorities { - * - * private List<String> expectedSecurityRoleStrings; - * - * @BeforeEach void mock() { var keycloakRoles = List.of(ROLE_1, - * JwtTestFactory.ROLE_2, JwtTestFactory.ROLE_3); expectedSecurityRoleStrings = - * keycloakRoles.stream().map(role -> SIMPLE_GRANT_AUTHORITY_PREFIX + - * role).toList(); - * doReturn(keycloakRoles).when(securityConfiguration).getRolesFromJwt(any()); } - * - * @DisplayName("should call get keycloak roles from jwt") - * - * @Test void shouldCallGetKeycloakRolesFromJwt() { var jwt = - * JwtTestFactory.create(); - * - * securityConfiguration.convertJwtToGrantedAuthorities(jwt); - * - * verify(securityConfiguration).getRolesFromJwt(jwt); } - * - * @DisplayName("should return granted authorities with ROLE_ prefix") - * - * @Test void shouldReturnGrantedAuthoritiesWithRolePrefix() { var jwt = - * JwtTestFactory.create(); - * - * var grantedAuthorities = - * securityConfiguration.convertJwtToGrantedAuthorities(jwt); - * - * var securityRoles = grantedAuthorities .stream() - * .map(GrantedAuthority::getAuthority).toList(); - * assertThat(securityRoles).containsAll(expectedSecurityRoleStrings); } } - * - * @DisplayName("get roles from jwt") - * - * @Nested class TestGetRolesFromJwt { - * - * @BeforeEach void mock() { - * lenient().when(oAuth2Properties.getResource()).thenReturn(JwtTestFactory. - * AUTH_RESOURCE); } - * - * @DisplayName("should return empty list if resource_access.admin.roles path is missing" - * ) - * - * @ParameterizedTest - * - * @MethodSource("getIncompleteJwt") void - * shouldReturnEmptyListIfResourceAccessAdminRolesPathIsMissing(Jwt - * incompleteJwt) { var roleStrings = - * securityConfiguration.getRolesFromJwt(incompleteJwt); - * - * assertThat(roleStrings).isEmpty(); } - * - * private static Stream<Arguments> getIncompleteJwt() { return - * Stream.of(JwtTestFactory.create(), - * JwtTestFactory.createBuilder().claim(RESOURCE_ACCESS_KEY, Map.of()).build(), - * JwtTestFactory.createBuilder().claim(RESOURCE_ACCESS_KEY, Map.of("admin", - * Map.of())).build(), JwtTestFactory.createWithRoles(emptyList()).build()) - * .map(Arguments::of); } - * - * @DisplayName("should return resource_access.admin.roles list") - * - * @Test void shouldReturnResourceAccessAdminRolesList() { var expectedRoles = - * List.of(ROLE_1, JwtTestFactory.ROLE_2, JwtTestFactory.ROLE_3); var - * jwtWithRoles = JwtTestFactory.createWithRoles(expectedRoles).build(); - * - * var roleStrings = securityConfiguration.getRolesFromJwt(jwtWithRoles); - * - * assertThat(roleStrings).isEqualTo(expectedRoles); } - * - * } - */ + + @BeforeEach + void mock() { + doReturn(Set.of(new SimpleGrantedAuthority(roleString))).when(securityConfiguration).convertJwtToGrantedAuthorities(any()); + } + + @DisplayName("should use preferred_username") + @Test + void shouldUsePreferredUsername() { + var preferredName = LoremIpsum.getInstance().getName(); + var jwtWithPreferredName = JwtTestFactory.createBuilder().claim(StandardClaimNames.PREFERRED_USERNAME, + preferredName).build(); + + var jwtAuthenticationConverter = securityConfiguration.jwtAuthenticationConverter(); + + var abstractAuthenticationToken = jwtAuthenticationConverter.convert(jwtWithPreferredName); + assertThat(abstractAuthenticationToken.getName()).isEqualTo(preferredName); + } + + @DisplayName("should use granted authorities converter") + @Test + void shouldUseGrantedAuthoritiesConverter() { + var jwtWithRoles = JwtTestFactory.create(); + + var jwtAuthenticationConverter = securityConfiguration.jwtAuthenticationConverter(); + + var abstractAuthenticationToken = jwtAuthenticationConverter.convert(jwtWithRoles); + var securityRoleStrings = abstractAuthenticationToken.getAuthorities().stream().map(GrantedAuthority::getAuthority).toList(); + + assertThat(securityRoleStrings).isEqualTo(List.of(roleString)); + } } + + @DisplayName("convert jwt to granted authorities") + @Nested + class TestConvertJwtToGrantedAuthorities { + + private List<String> expectedSecurityRoleStrings; + + @BeforeEach + void mock() { + var keycloakRoles = List.of(JwtTestFactory.ROLE_1, + JwtTestFactory.ROLE_2, JwtTestFactory.ROLE_3); + expectedSecurityRoleStrings = keycloakRoles.stream().map(role -> SIMPLE_GRANT_AUTHORITY_PREFIX + + role).toList(); + doReturn(keycloakRoles).when(securityConfiguration).getRolesFromJwt(any()); + } + + @DisplayName("should call get keycloak roles from jwt") + @Test + void shouldCallGetKeycloakRolesFromJwt() { + var jwt = JwtTestFactory.create(); + + securityConfiguration.convertJwtToGrantedAuthorities(jwt); + + verify(securityConfiguration).getRolesFromJwt(jwt); + } + + @DisplayName("should return granted authorities with ROLE_ prefix") + @Test + void shouldReturnGrantedAuthoritiesWithRolePrefix() { + var jwt = JwtTestFactory.create(); + + var grantedAuthorities = securityConfiguration.convertJwtToGrantedAuthorities(jwt); + + var securityRoles = grantedAuthorities.stream() + .map(GrantedAuthority::getAuthority).toList(); + assertThat(securityRoles).containsAll(expectedSecurityRoleStrings); + } + } + + @DisplayName("get roles from jwt") + + @Nested + class TestGetRolesFromJwt { + + @BeforeEach + void mock() { + lenient().when(oAuth2Properties.getResource()).thenReturn(JwtTestFactory.AUTH_RESOURCE); + } + + @DisplayName("should return empty list if resource_access.admin.roles path is missing") + @ParameterizedTest + @MethodSource("getIncompleteJwt") + void shouldReturnEmptyListIfResourceAccessAdminRolesPathIsMissing(Jwt incompleteJwt) { + var roleStrings = securityConfiguration.getRolesFromJwt(incompleteJwt); + + assertThat(roleStrings).isEmpty(); + } + + private static Stream<Arguments> getIncompleteJwt() { + return Stream.of(JwtTestFactory.create(), + JwtTestFactory.createBuilder().claim(RESOURCE_ACCESS_KEY, Map.of()).build(), + JwtTestFactory.createBuilder().claim(RESOURCE_ACCESS_KEY, Map.of("admin", Map.of())).build(), + JwtTestFactory.createWithRoles(emptyList()).build()) + .map(Arguments::of); + } + + @DisplayName("should return resource_access.admin.roles list") + @Test + void shouldReturnResourceAccessAdminRolesList() { + var expectedRoles = List.of(JwtTestFactory.ROLE_1, JwtTestFactory.ROLE_2, JwtTestFactory.ROLE_3); + var jwtWithRoles = JwtTestFactory.createWithRoles(expectedRoles).build(); + + var roleStrings = securityConfiguration.getRolesFromJwt(jwtWithRoles); + + assertThat(roleStrings).isEqualTo(expectedRoles); + } + + } + } diff --git a/src/test/java/de/ozgcloud/admin/setting/SettingEnvironmentITCase.java b/src/test/java/de/ozgcloud/admin/setting/SettingEnvironmentITCase.java index c50d09934b9cfd835215a4589a0c70000fdc9419..4fe44a5e5de623e8c08dfd39cb6073058c497ed5 100644 --- a/src/test/java/de/ozgcloud/admin/setting/SettingEnvironmentITCase.java +++ b/src/test/java/de/ozgcloud/admin/setting/SettingEnvironmentITCase.java @@ -38,6 +38,7 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; +import de.ozgcloud.admin.common.user.UserRole; import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheit; import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheitTestFactory; import de.ozgcloud.admin.setting.postfach.PostfachSettingBodyTestFactory; @@ -46,7 +47,7 @@ import lombok.SneakyThrows; @DataITCase @AutoConfigureMockMvc -@WithMockUser +@WithMockUser(roles = UserRole.ADMIN_ADMIN) class SettingEnvironmentITCase { @Autowired diff --git a/src/test/java/de/ozgcloud/admin/setting/SettingRepositoryITCase.java b/src/test/java/de/ozgcloud/admin/setting/SettingRepositoryITCase.java index 3fb17b47e79176424afab28bcc63cf082a17ade2..649efee530e07449fe35fcae3a4138bf2ab74f22 100644 --- a/src/test/java/de/ozgcloud/admin/setting/SettingRepositoryITCase.java +++ b/src/test/java/de/ozgcloud/admin/setting/SettingRepositoryITCase.java @@ -29,17 +29,22 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.security.test.context.support.WithMockUser; +import de.ozgcloud.admin.common.user.UserRole; import de.ozgcloud.common.test.DataITCase; @DataITCase +@WithMockUser(roles = UserRole.ADMIN_ADMIN) class SettingRepositoryITCase { + + private static final String SETTING_NAME = "Name"; + @Autowired private MongoOperations mongoOperations; @Autowired private SettingRepository repository; - private final static String SETTING_NAME = "Name"; private Setting setting = SettingTestFactory.createBuilder() .name(SETTING_NAME) .build();