diff --git a/common/src/main/java/de/ozgcloud/eingang/common/formdata/ServiceKonto.java b/common/src/main/java/de/ozgcloud/eingang/common/formdata/ServiceKonto.java index ab2f7588d424a1358a4d8bcd01d360e705917e86..3603b84361aee6103e5956c3e69091349fc783ef 100644 --- a/common/src/main/java/de/ozgcloud/eingang/common/formdata/ServiceKonto.java +++ b/common/src/main/java/de/ozgcloud/eingang/common/formdata/ServiceKonto.java @@ -1,9 +1,14 @@ package de.ozgcloud.eingang.common.formdata; +import java.util.EnumSet; import java.util.List; +import org.apache.commons.lang3.StringUtils; + +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; +import lombok.RequiredArgsConstructor; import lombok.Singular; @Getter @@ -22,4 +27,23 @@ public class ServiceKonto { private String version; private PostfachAddressIdentifier identifier; } + + @RequiredArgsConstructor(access = AccessLevel.PRIVATE) + public enum TrustLevel { + + LEVEL_1("STORK-QAA-Level-1"), + LEVEL_2("STORK-QAA-Level-2"), + LEVEL_3("STORK-QAA-Level-3"), + LEVEL_4("STORK-QAA-Level-4"); + + private final String value; + + public static boolean hasValue(String trustLevelValue) { + if (StringUtils.isBlank(trustLevelValue)) { + return false; + } + return EnumSet.allOf(TrustLevel.class).stream().map(trustLevel -> trustLevel.value).anyMatch(trustLevelValue::equalsIgnoreCase); + } + } + } \ No newline at end of file diff --git a/common/src/test/java/de/ozgcloud/eingang/common/formdata/TrustLevelTest.java b/common/src/test/java/de/ozgcloud/eingang/common/formdata/TrustLevelTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e5aeaeee64d28e71c8bc23b539b9350dcee6f759 --- /dev/null +++ b/common/src/test/java/de/ozgcloud/eingang/common/formdata/TrustLevelTest.java @@ -0,0 +1,32 @@ +package de.ozgcloud.eingang.common.formdata; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; + +import de.ozgcloud.eingang.common.formdata.ServiceKonto.TrustLevel; + +class TrustLevelTest { + + @DisplayName("should return true when") + @ParameterizedTest(name = "trust level is {0}") + @ValueSource(strings = {"STORK-QAA-Level-1", "STORK-QAA-Level-2", "STORK-QAA-Level-3", "STORK-QAA-Level-4"}) + void shouldReturnTrue(String trustLevel) { + var isValid = TrustLevel.hasValue(trustLevel); + + assertThat(isValid).isTrue(); + } + + @DisplayName("should return false when") + @ParameterizedTest(name = "trust level is \"{0}\"") + @NullAndEmptySource + @ValueSource(strings = {"STORK-QAA-Level-0", "unexpected"}) + void shouldReturnFalse(String trustLevel) { + var isValid = TrustLevel.hasValue(trustLevel); + + assertThat(isValid).isFalse(); + } +} \ No newline at end of file diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactory.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactory.java index 4c16e1473625ace69c74a8ee064973fcb035f346..1494a485d2b6a1a09f4c20485deda58d5e31840a 100644 --- a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactory.java +++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactory.java @@ -5,18 +5,17 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.Set; import org.apache.commons.collections.MapUtils; -import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import de.ozgcloud.eingang.common.errorhandling.UnexpectedTrustLevelException; import de.ozgcloud.eingang.common.formdata.FormData; import de.ozgcloud.eingang.common.formdata.PostfachAddressIdentifier; import de.ozgcloud.eingang.common.formdata.ServiceKonto; -import de.ozgcloud.eingang.common.formdata.StringBasedIdentifier; import de.ozgcloud.eingang.common.formdata.ServiceKonto.PostfachAddress; +import de.ozgcloud.eingang.common.formdata.ServiceKonto.TrustLevel; +import de.ozgcloud.eingang.common.formdata.StringBasedIdentifier; import lombok.extern.log4j.Log4j2; @Component @@ -30,9 +29,6 @@ public class ServiceKontoFactory { public static final String KEY_BAYERN_ID_POSTFACH_ID = "u:saml_legacypostkorbhandle"; public static final String KEY_BAYERN_ID_TRUST_LEVEL = "u:saml_eid_citizen_qaa_level"; - static final Set<String> BAYERN_ID_EXPECTED_TRUST_LEVELS = Set.of("STORK-QAA-Level-1", "STORK-QAA-Level-2", "STORK-QAA-Level-3", - "STORK-QAA-Level-4"); - public static final String REST_RESPONSE_NAME = "rest_response_name"; public static final String REST_RESPONSE_NAME_MEMBER_SCOPE = "memberscope"; public static final String REST_RESPONSE_NAME_MEMBER_SCOPE_MAILBOX_TYPE = "mailboxtype"; @@ -126,17 +122,13 @@ public class ServiceKontoFactory { String getTrustLevel(Map<String, Object> formDataHeader) { var trustLevel = MapUtils.getString(formDataHeader, KEY_BAYERN_ID_TRUST_LEVEL); - if (isValidTrustLevel(trustLevel)) { + if (TrustLevel.hasValue(trustLevel)) { return trustLevel; } throw new UnexpectedTrustLevelException( "TrustLevel has an unexpected value '%s'. BayernID user account is not connected".formatted(trustLevel)); } - boolean isValidTrustLevel(String trustLevel) { - return StringUtils.isNoneBlank(trustLevel) && BAYERN_ID_EXPECTED_TRUST_LEVELS.contains(trustLevel); - } - private PostfachAddressIdentifier buildIdentifier(String postfachId) { return StringBasedIdentifier.builder().postfachId(postfachId).build(); } diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactoryTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactoryTest.java index c650274f1a75a03f9268c099ac67a9cb8fc7b2e5..c4bb1b0f9a4067771b26cea24d5dbfcd203fde9e 100644 --- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactoryTest.java +++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactoryTest.java @@ -12,9 +12,6 @@ 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.NullAndEmptySource; -import org.junit.jupiter.params.provider.ValueSource; import org.mockito.InjectMocks; import org.mockito.Spy; @@ -23,6 +20,7 @@ import de.ozgcloud.eingang.common.formdata.FormData; import de.ozgcloud.eingang.common.formdata.FormDataUtils; import de.ozgcloud.eingang.common.formdata.PostfachAddressTestFactory; import de.ozgcloud.eingang.common.formdata.ServiceKonto; +import de.ozgcloud.eingang.common.formdata.ServiceKonto.TrustLevel; import de.ozgcloud.eingang.common.formdata.StringBasedIdentifier; import de.ozgcloud.eingang.common.formdata.ServiceKonto.PostfachAddress; import de.ozgcloud.eingang.semantik.enginebased.afm.AfmHeaderTestFactory; @@ -31,7 +29,7 @@ class ServiceKontoFactoryTest { @Spy @InjectMocks - private ServiceKontoFactory helper; + private ServiceKontoFactory factory; @DisplayName("OSI service konto") @Nested @@ -47,7 +45,7 @@ class ServiceKontoFactoryTest { @BeforeEach void mockBuildPostfachAddresses() { - doReturn(List.of(POSTFACH_ADDRESS)).when(helper).buildPostfachAddresses(any(), any()); + doReturn(List.of(POSTFACH_ADDRESS)).when(factory).buildPostfachAddresses(any(), any()); } @Test @@ -69,12 +67,12 @@ class ServiceKontoFactoryTest { void shouldBuildPostfachAddresses() { getServiceKonto(FORM_DATA); - verify(helper).buildPostfachAddresses(any(), any()); + verify(factory).buildPostfachAddresses(any(), any()); } } private ServiceKonto getServiceKonto(FormData formData) { - return helper.buildOsiServiceKonto(AfmHeaderTestFactory.POSTFACH_NAME_ID, formData); + return factory.buildOsiServiceKonto(AfmHeaderTestFactory.POSTFACH_NAME_ID, formData); } @DisplayName("postfach addresses") @@ -89,7 +87,7 @@ class ServiceKontoFactoryTest { void shouldCallBuildAddresses() { getPostfachAddresses(); - verify(helper).buildOsiPostfachV1Address(any(), anyInt()); + verify(factory).buildOsiPostfachV1Address(any(), anyInt()); } @Test @@ -120,7 +118,7 @@ class ServiceKontoFactoryTest { void shouldBuildDefault() { getPostfachAddresses(); - verify(helper).buildDefault(AfmHeaderTestFactory.POSTFACH_NAME_ID); + verify(factory).buildDefault(AfmHeaderTestFactory.POSTFACH_NAME_ID); } @Test @@ -143,7 +141,7 @@ class ServiceKontoFactoryTest { } private ServiceKonto buildServiceKonto(FormData formData) { - return helper.buildOsiServiceKonto(AfmHeaderTestFactory.POSTFACH_NAME_ID, formData); + return factory.buildOsiServiceKonto(AfmHeaderTestFactory.POSTFACH_NAME_ID, formData); } } } @@ -162,7 +160,7 @@ class ServiceKontoFactoryTest { @DisplayName("should return empty when headers map is null") @Test void shouldReturnEmptyWhenNull() { - var serviceKonto = helper.createBayernIdServiceKonto(null); + var serviceKonto = factory.createBayernIdServiceKonto(null); assertThat(serviceKonto).isEmpty(); } @@ -170,24 +168,24 @@ class ServiceKontoFactoryTest { @DisplayName("should return empty when postfach id is missing") @Test void shouldReturnEmptyWhenPostfachIdIsMissing() { - var serviceKonto = helper.createBayernIdServiceKonto(Map.of()); + var serviceKonto = factory.createBayernIdServiceKonto(Map.of()); assertThat(serviceKonto).isEmpty(); } @Test void shouldCallBuildBayernIdServiceKonto() { - helper.createBayernIdServiceKonto(formDataHeaders); + factory.createBayernIdServiceKonto(formDataHeaders); - verify(helper).buildBayernIdServiceKonto(formDataHeaders); + verify(factory).buildBayernIdServiceKonto(formDataHeaders); } @Test void shouldReturnServiceKonto() { var expectedServiceKonto = ServiceKonto.builder().build(); - doReturn(expectedServiceKonto).when(helper).buildBayernIdServiceKonto(any()); + doReturn(expectedServiceKonto).when(factory).buildBayernIdServiceKonto(any()); - var serviceKonto = helper.createBayernIdServiceKonto(formDataHeaders); + var serviceKonto = factory.createBayernIdServiceKonto(formDataHeaders); assertThat(serviceKonto).contains(expectedServiceKonto); } @@ -195,9 +193,9 @@ class ServiceKontoFactoryTest { @DisplayName("should return empty when trust level has unexpected value") @Test void shouldReturnEmptyWhenTrustLevelCorrupted() { - doThrow(UnexpectedTrustLevelException.class).when(helper).buildBayernIdServiceKonto(any()); + doThrow(UnexpectedTrustLevelException.class).when(factory).buildBayernIdServiceKonto(any()); - var serviceKonto = helper.createBayernIdServiceKonto(formDataHeaders); + var serviceKonto = factory.createBayernIdServiceKonto(formDataHeaders); assertThat(serviceKonto).isEmpty(); } @@ -216,7 +214,7 @@ class ServiceKontoFactoryTest { @BeforeEach void init() { - doReturn(TRUST_LEVEL).when(helper).getTrustLevel(any()); + doReturn(TRUST_LEVEL).when(factory).getTrustLevel(any()); } @Test @@ -230,12 +228,12 @@ class ServiceKontoFactoryTest { void shouldCallBuildPostfachAddress() { buildBayernIdServiceKonto(); - verify(helper).buildPostfachAddress(POSTFACH_ID); + verify(factory).buildPostfachAddress(POSTFACH_ID); } @Test void shouldSetPostfachAddress() { - doReturn(POSTFACH_ADDRESS).when(helper).buildPostfachAddress(any()); + doReturn(POSTFACH_ADDRESS).when(factory).buildPostfachAddress(any()); var serviceKonto = buildBayernIdServiceKonto(); @@ -246,7 +244,7 @@ class ServiceKontoFactoryTest { void shouldCallGetTrustLevel() { buildBayernIdServiceKonto(); - verify(helper).getTrustLevel(formDataHeaders); + verify(factory).getTrustLevel(formDataHeaders); } @Test @@ -257,7 +255,7 @@ class ServiceKontoFactoryTest { } ServiceKonto buildBayernIdServiceKonto() { - return helper.buildBayernIdServiceKonto(formDataHeaders); + return factory.buildBayernIdServiceKonto(formDataHeaders); } } @@ -270,46 +268,28 @@ class ServiceKontoFactoryTest { @Test void shouldCallValidateTrustLevel() { - helper.getTrustLevel(formDataHeaders); + try (var trustLevelMock = mockStatic(TrustLevel.class)) { + trustLevelMock.when(() -> TrustLevel.hasValue(any())).thenReturn(true); + + factory.getTrustLevel(formDataHeaders); + + trustLevelMock.verify(() -> TrustLevel.hasValue(TRUST_LEVEL)); + } - verify(helper).isValidTrustLevel(TRUST_LEVEL); } @Test void shouldReturnTrustLevel() { - var trustLevel = helper.getTrustLevel(formDataHeaders); + var trustLevel = factory.getTrustLevel(formDataHeaders); assertThat(trustLevel).isEqualTo(TRUST_LEVEL); } @Test void shouldThrowExceptionWhenTrustLevelIsInvalid() { - doReturn(false).when(helper).isValidTrustLevel(any()); - - assertThrows(UnexpectedTrustLevelException.class, () -> helper.getTrustLevel(formDataHeaders)); - } - } - - @Nested - class TestValidateTrustLevel { - - @DisplayName("should return true when") - @ParameterizedTest(name = "trust level is {0}") - @ValueSource(strings = {"STORK-QAA-Level-1", "STORK-QAA-Level-2", "STORK-QAA-Level-3", "STORK-QAA-Level-4"}) - void shouldReturnTrue(String trustLevel) { - var isValid = helper.isValidTrustLevel(trustLevel); - - assertThat(isValid).isTrue(); - } - - @DisplayName("should return false when") - @ParameterizedTest(name = "trust level is \"{0}\"") - @NullAndEmptySource - @ValueSource(strings = {"STORK-QAA-Level-0", "unexpected"}) - void shouldReturnFalse(String trustLevel) { - var isValid = helper.isValidTrustLevel(trustLevel); + var formDataHeaders = Map.<String, Object>of(ServiceKontoFactory.KEY_BAYERN_ID_TRUST_LEVEL, "unexpected"); - assertThat(isValid).isFalse(); + assertThrows(UnexpectedTrustLevelException.class, () -> factory.getTrustLevel(formDataHeaders)); } }