diff options
Diffstat (limited to 'modules/core_common_webapp')
6 files changed, 492 insertions, 48 deletions
| diff --git a/modules/core_common_webapp/pom.xml b/modules/core_common_webapp/pom.xml index 7184f843..2c6c4b5c 100644 --- a/modules/core_common_webapp/pom.xml +++ b/modules/core_common_webapp/pom.xml @@ -60,9 +60,25 @@        <scope>test</scope>      </dependency>      <dependency> -      <groupId>org.springframework.boot</groupId> -      <artifactId>spring-boot-starter-test</artifactId> +      <groupId>org.powermock</groupId> +      <artifactId>powermock-module-junit4</artifactId> +      <scope>test</scope> +    </dependency> +    <dependency> +      <groupId>org.powermock</groupId> +      <artifactId>powermock-api-mockito2</artifactId>        <scope>test</scope> +    </dependency> +    <dependency> +      <groupId>com.squareup.okhttp3</groupId> +      <artifactId>mockwebserver</artifactId> +      <scope>test</scope> +    </dependency>   +    <dependency> +      <groupId>at.asitplus.eidas.ms_specific</groupId> +      <artifactId>core_common_lib</artifactId> +      <scope>test</scope> +      <type>test-jar</type>      </dependency>          <dependency>        <groupId>at.gv.egiz.eaaf</groupId> @@ -92,14 +108,7 @@        <artifactId>eaaf_module_pvp2_idp</artifactId>        <scope>test</scope>        <type>test-jar</type> -    </dependency> -    <dependency> -      <groupId>com.squareup.okhttp3</groupId> -      <artifactId>mockwebserver</artifactId> -      <scope>test</scope>      </dependency>     -     -        </dependencies>    <build> diff --git a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/builder/AuthenticationDataBuilder.java b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/builder/AuthenticationDataBuilder.java index 181d5735..5a8992b5 100644 --- a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/builder/AuthenticationDataBuilder.java +++ b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/builder/AuthenticationDataBuilder.java @@ -24,75 +24,92 @@  package at.asitplus.eidas.specific.core.builder;  import java.time.Instant; - -import org.springframework.stereotype.Service; +import java.util.Optional; +import java.util.Set;  import at.asitplus.eidas.specific.core.MsEidasNodeConstants; +import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;  import at.gv.egiz.eaaf.core.api.IRequest;  import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions; +import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions;  import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions.EidIdentityStatusLevelValues;  import at.gv.egiz.eaaf.core.api.idp.IAuthData;  import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;  import at.gv.egiz.eaaf.core.api.idp.auth.data.IAuthProcessDataContainer; +import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;  import at.gv.egiz.eaaf.core.exceptions.EaafBuilderException;  import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;  import at.gv.egiz.eaaf.core.impl.data.Pair; +import at.gv.egiz.eaaf.core.impl.data.Triple;  import at.gv.egiz.eaaf.core.impl.idp.AuthenticationData;  import at.gv.egiz.eaaf.core.impl.idp.EidAuthenticationData;  import at.gv.egiz.eaaf.core.impl.idp.auth.builder.AbstractAuthenticationDataBuilder;  import at.gv.egiz.eaaf.core.impl.idp.auth.data.EidAuthProcessDataWrapper;  import lombok.extern.slf4j.Slf4j; -@Service("AuthenticationDataBuilder")  @Slf4j  public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder { +  private static final String ERROR_B11 = "builder.11"; +    @Override -  protected IAuthData buildDeprecatedAuthData(IRequest pendingReq) throws EaafException {         +  protected IAuthData buildDeprecatedAuthData(IRequest pendingReq) throws EaafException {      final EidAuthProcessDataWrapper authProcessData = -        pendingReq.getSessionData(EidAuthProcessDataWrapper.class);     -    EidAuthenticationData authData = new EidAuthenticationData(); -     -    //set basis infos +        pendingReq.getSessionData(EidAuthProcessDataWrapper.class); +    final EidAuthenticationData authData = new EidAuthenticationData(); + +    // set basis infos      super.generateDeprecatedBasicAuthData(authData, pendingReq, authProcessData); -     +      // set specific informations      authData.setSsoSessionValidTo(          Instant.now().plusSeconds(MsEidasNodeConstants.DEFAULT_PVP_ASSERTION_VALIDITY * 60)); -         -     -    authData.setEidStatus(authProcessData.isTestIdentity()  -        ? EidIdentityStatusLevelValues.TESTIDENTITY : EidIdentityStatusLevelValues.IDENTITY); -     +    authData.setEidStatus(authProcessData.isTestIdentity() +        ? EidIdentityStatusLevelValues.TESTIDENTITY +        : EidIdentityStatusLevelValues.IDENTITY); +      return authData;    }    @Override -  protected void buildServiceSpecificAuthenticationData(IAuthData authData, IRequest pendingReq)  +  protected void buildServiceSpecificAuthenticationData(IAuthData authData, IRequest pendingReq)        throws EaafException {      if (authData instanceof EidAuthenticationData) { -      ((EidAuthenticationData)authData).setGenericData( -          ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_NAME,  +      ((EidAuthenticationData) authData).setGenericData( +          ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_NAME,            pendingReq.getUniquePiiTransactionIdentifier());        log.trace("Inject piiTransactionId: {} into AuthData", pendingReq.getUniquePiiTransactionIdentifier()); -     +        // set specific informations -      ((EidAuthenticationData)authData).setSsoSessionValidTo( +      ((EidAuthenticationData) authData).setSsoSessionValidTo(            Instant.now().plusSeconds(MsEidasNodeConstants.DEFAULT_PVP_ASSERTION_VALIDITY * 60)); -      //set E-ID status-level +      // set E-ID status-level        final EidAuthProcessDataWrapper authProcessData = -          pendingReq.getSessionData(EidAuthProcessDataWrapper.class);         -      ((EidAuthenticationData)authData).setEidStatus(authProcessData.isTestIdentity()  -          ? EidIdentityStatusLevelValues.TESTIDENTITY : EidIdentityStatusLevelValues.IDENTITY); -       +          pendingReq.getSessionData(EidAuthProcessDataWrapper.class); +      ((EidAuthenticationData) authData).setEidStatus(authProcessData.isTestIdentity() +          ? EidIdentityStatusLevelValues.TESTIDENTITY +          : EidIdentityStatusLevelValues.IDENTITY); + +      // forward all requested IDA attributes into authData +      forwardAllRequestedIdaAttributes(authProcessData, (EidAuthenticationData) authData, +          pendingReq.getServiceProviderConfiguration(ServiceProviderConfiguration.class) +              .getRequestedAttributes()); + +      // build specific bPK attribute +      buildNatPersonInfos((EidAuthenticationData) authData, authProcessData); + +      // handle mandate informations +      buildMandateInformation((EidAuthenticationData) authData, authProcessData); +      } else { -      throw new RuntimeException("Can not inject PiiTransactionId because AuthData is of unknown type: "  +      throw new RuntimeException("Can not inject PiiTransactionId because AuthData is of unknown type: "            + authData.getClass().getName()); -       +      } -         +    }    @Override @@ -121,4 +138,120 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder    } +  protected String customizeLegalPersonSourcePin(String sourcePin, String sourcePinType) { +    log.trace("Use legal-person sourcePin as it is"); +    return sourcePin; + +  } + +  protected String customizeBpkAttribute(String pvpBpkAttrValue) { +    log.trace("Use natural-person bPK as it is"); +    return pvpBpkAttrValue; + +  } + +  private void forwardAllRequestedIdaAttributes(EidAuthProcessDataWrapper authProcessData, +      EidAuthenticationData authData, Set<String> requestedIdaAttributes) { +    if (requestedIdaAttributes != null && !requestedIdaAttributes.isEmpty()) { +      log.trace("Forwarding IDA requested attributes ... "); +      authProcessData.getGenericSessionDataStream() +          .filter(el -> requestedIdaAttributes.contains(el.getKey())) +          .forEach(el -> { +            try { +              authData.setGenericData(el.getKey(), el.getValue()); + +            } catch (final EaafStorageException e) { +              log.error("Can not store attribute: {} into session.", el.getKey(), e); +              throw new RuntimeException(e); + +            } +          }); +    } else { +      log.trace("No IDA requested attributes to forwarding. Nothing todo"); + +    } +  } + +  private void buildMandateInformation(EidAuthenticationData authData, +      EidAuthProcessDataWrapper authProcessData) throws EaafAuthenticationException, EaafBuilderException, +      EaafStorageException { +    authData.setUseMandate(authProcessData.isMandateUsed()); +    if (authProcessData.isMandateUsed()) { +      log.debug("Build mandate-releated authentication data ... "); +      if (authProcessData.isForeigner()) { +        buildMandateInformationForEidasIncoming(); + +      } else { +        buildMandateInformationForEidasOutgoing(authData, authProcessData); + +      } +    } +  } + +  private void buildMandateInformationForEidasIncoming() { +    log.debug("Find eIDAS incoming process. Generated mandate-information for ID-Austria system ... "); + +    // TODO: implement IDA specific processing of foreign mandate + +  } + +  private void buildNatPersonInfos(EidAuthenticationData authData, +      EidAuthProcessDataWrapper authProcessData) throws EaafStorageException { +    // clean-up BPK attribute and forward it as new property +    authData.setGenericData(PvpAttributeDefinitions.BPK_NAME, +        customizeBpkAttribute(authProcessData.getGenericDataFromSession( +            PvpAttributeDefinitions.BPK_NAME, String.class))); + +  } + +  private void buildMandateInformationForEidasOutgoing(EidAuthenticationData authData, +      EidAuthProcessDataWrapper authProcessData) throws EaafAuthenticationException, EaafBuilderException, +      EaafStorageException { +    log.debug("Find eIDAS outgoing process. Generated mandate-information for other country ... "); +    if (authProcessData.getGenericDataFromSession( +        PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME) != null) { +      final Optional<Triple<String, String, Boolean>> missingAttribute = +          MsEidasNodeConstants.DEFAULT_REQUIRED_MANDATE_NAT_PVP_ATTRIBUTES.stream() +              .filter(el -> authProcessData.getGenericDataFromSession(el.getFirst()) == null) +              .findFirst(); +      if (missingAttribute.isPresent()) { +        log.error("ID-Austria response contains not all attributes for nat. person mandator. Missing: {}", +            missingAttribute.get().getFirst()); +        throw new EaafAuthenticationException(ERROR_B11, new Object[] { "Nat. person mandate" }); + +      } else { +        log.trace("Find nat. person mandate. Mandate can be used as it is "); +        authData.setGenericData(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, +            customizeBpkAttribute(authProcessData.getGenericDataFromSession( +                PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, String.class))); + +      } + +    } else { +      final Optional<Triple<String, String, Boolean>> missingAttribute = +          MsEidasNodeConstants.DEFAULT_REQUIRED_MANDATE_JUR_PVP_ATTRIBUTES.stream() +              .filter(el -> authProcessData.getGenericDataFromSession(el.getFirst()) == null) +              .findFirst(); +      if (missingAttribute.isPresent()) { +        log.error("ID-Austria response contains not all attributes for legal. person mandator. Missing: {}", +            missingAttribute.get().getFirst()); +        throw new EaafAuthenticationException(ERROR_B11, new Object[] { "Legal. person mandate" }); + +      } else { +        log.trace( +            "Find jur. person mandate. Generate eIDAS identifier from legal-person sourcePin and type ... "); +        final String sourcePin = authProcessData.getGenericDataFromSession( +            PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, String.class); +        final String sourcePinType = authProcessData.getGenericDataFromSession( +            PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME, String.class); + +        // customize attribute-value for source-pin +        final String sourcePinToUse = customizeLegalPersonSourcePin(sourcePin, sourcePinType); +        log.debug("Use legal-person eIDAS identifer: {} from baseId: {} and baseIdType: {}", +            sourcePinToUse, sourcePin, sourcePinType); +        authData.setGenericData(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, sourcePinToUse); + +      } +    } +  }  } diff --git a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/provider/StatusMessageProvider.java b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/provider/StatusMessageProvider.java index 416a4cb5..3f4b9537 100644 --- a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/provider/StatusMessageProvider.java +++ b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/provider/StatusMessageProvider.java @@ -44,6 +44,7 @@ import lombok.extern.slf4j.Slf4j;  @Slf4j  public class StatusMessageProvider implements IStatusMessenger, MessageSourceAware { +    private static final String ERROR_MESSAGES_UNAVAILABLE =        "Error messages can NOT be load from application. Only errorCode: {0} is availabe";    private static final String ERROR_NO_MESSAGE = "No errormesseage for error with number.={0}"; @@ -56,14 +57,15 @@ public class StatusMessageProvider implements IStatusMessenger, MessageSourceAwa    private static final String MSG_WARN_NO_SOURCE = "MessageCode: {} is NOT SET for locale: {}";    private static final String MSG_INFO = "Use locale: {} as default"; -  private MessageSource messageSource; -      // external error codes    private static final String DEFAULT_EXTERNALERROR_RESOURCES = "properties/external_statuscodes_map";    private static final Locale DEFAULT_EXTERNALERROR_LOCALES = new Locale("en", "GB");    private ResourceBundle externalError = null; +  //internal messanges +  private MessageSource messageSource; +    @Override    public String getMessageWithoutDefault(final String messageId, final Object[] parameters) {      if (messageSource == null) { @@ -86,6 +88,7 @@ public class StatusMessageProvider implements IStatusMessenger, MessageSourceAwa          } +        } catch (final MissingResourceException e2) {          log.warn("No message source", e2); @@ -101,6 +104,7 @@ public class StatusMessageProvider implements IStatusMessenger, MessageSourceAwa      if (messageSource == null) {        return MessageFormat.format(ERROR_MESSAGES_UNAVAILABLE, new Object[]{messageId}); +      } else {        try {          final Locale locale = LocaleContextHolder.getLocale(); @@ -124,7 +128,7 @@ public class StatusMessageProvider implements IStatusMessenger, MessageSourceAwa        }      }    } - +      @Override    public String getResponseErrorCode(Throwable throwable) {      if (throwable instanceof EaafException) { diff --git a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java index 5a59a4e0..44547d95 100644 --- a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java +++ b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java @@ -63,7 +63,7 @@ public class EidasCacheTransactionStoreDecorator implements ITransactionStorage,        } -    } catch (final EaafException e) { +    } catch (final Exception e) {        log.warn("Montioring: Can not read/write to storage.", e);        return Health.down().down(e).build(); diff --git a/modules/core_common_webapp/src/main/resources/specific_eIDAS_core.beans.xml b/modules/core_common_webapp/src/main/resources/specific_eIDAS_core.beans.xml index ee67d712..af3594a5 100644 --- a/modules/core_common_webapp/src/main/resources/specific_eIDAS_core.beans.xml +++ b/modules/core_common_webapp/src/main/resources/specific_eIDAS_core.beans.xml @@ -23,9 +23,6 @@    <bean id="AuthenticationManager"          class="at.asitplus.eidas.specific.core.auth.AuthenticationManager" /> -  <bean id="AuthenticationDataBuilder" -        class="at.asitplus.eidas.specific.core.builder.AuthenticationDataBuilder" /> -    <bean id="eaafProtocolAuthenticationService"          class="at.gv.egiz.eaaf.core.impl.idp.auth.services.ProtocolAuthenticationService">      <property name="guiBuilder" ref="mvcGUIBuilderImpl" /> diff --git a/modules/core_common_webapp/src/test/java/at/asitplus/eidas/specific/core/test/utils/AuthenticationDataBuilderTest.java b/modules/core_common_webapp/src/test/java/at/asitplus/eidas/specific/core/test/utils/AuthenticationDataBuilderTest.java index 12936a59..8b2eebd4 100644 --- a/modules/core_common_webapp/src/test/java/at/asitplus/eidas/specific/core/test/utils/AuthenticationDataBuilderTest.java +++ b/modules/core_common_webapp/src/test/java/at/asitplus/eidas/specific/core/test/utils/AuthenticationDataBuilderTest.java @@ -1,6 +1,9 @@  package at.asitplus.eidas.specific.core.test.utils;  import static at.asitplus.eidas.specific.core.MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue;  import java.io.IOException;  import java.security.PublicKey; @@ -30,8 +33,11 @@ import org.springframework.web.context.request.RequestContextHolder;  import org.springframework.web.context.request.ServletRequestAttributes;  import org.w3c.dom.Element; +import com.google.common.collect.Sets; +  import at.asitplus.eidas.specific.core.MsEidasNodeConstants;  import at.asitplus.eidas.specific.core.builder.AuthenticationDataBuilder; +import at.asitplus.eidas.specific.core.config.ServiceProviderConfiguration;  import at.gv.egiz.eaaf.core.api.data.EaafConfigConstants;  import at.gv.egiz.eaaf.core.api.data.EaafConstants;  import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions; @@ -49,9 +55,9 @@ import at.gv.egiz.eaaf.core.impl.idp.EidAuthenticationData;  import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper;  import at.gv.egiz.eaaf.core.impl.idp.auth.data.EidAuthProcessDataWrapper;  import at.gv.egiz.eaaf.core.impl.idp.auth.data.SimpleIdentityLinkAssertionParser; -import at.gv.egiz.eaaf.core.impl.idp.module.test.DummySpConfiguration;  import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl;  import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xInitializer; +import lombok.SneakyThrows;  import net.shibboleth.utilities.java.support.component.ComponentInitializationException;  @RunWith(SpringJUnit4ClassRunner.class) @@ -71,7 +77,8 @@ public class AuthenticationDataBuilderTest {    private MockHttpServletResponse httpResp;    private TestRequestImpl pendingReq; -  private DummySpConfiguration oaParam; +  private Map<String, String> spConfig; +  private ServiceProviderConfiguration oaParam;    private String eidasBind;    private String authBlock; @@ -86,18 +93,20 @@ public class AuthenticationDataBuilderTest {    }    @Before +  @SneakyThrows    public void initialize() throws EaafStorageException {      httpReq = new MockHttpServletRequest("POST", "https://localhost/ms_connector");      httpResp = new MockHttpServletResponse();      RequestContextHolder.resetRequestAttributes();      RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); -    final Map<String, String> spConfig = new HashMap<>(); +    spConfig = new HashMap<>();      spConfig.put(EaafConfigConstants.SERVICE_UNIQUEIDENTIFIER, "testSp");      spConfig.put("target", "urn:publicid:gv.at:cdid+XX");      spConfig.put(PROP_CONFIG_SP_NEW_EID_MODE, "true"); -    oaParam = new DummySpConfiguration(spConfig, basicConfig); - +    oaParam = new ServiceProviderConfiguration(spConfig, basicConfig); +    oaParam.setBpkTargetIdentifier("urn:publicid:gv.at:cdid+XX"); +          pendingReq = new TestRequestImpl();      pendingReq.setAuthUrl("https://localhost/ms_connector");      pendingReq.setPendingReqId(RandomStringUtils.randomAlphanumeric(10)); @@ -120,6 +129,260 @@ public class AuthenticationDataBuilderTest {    }    @Test +  public void eidasProxyModeWithJurMandate() throws EaafAuthenticationException, EaafStorageException { +    // initialize state     +    injectRepresentativeInfosIntoSession(); +     +    String commonMandate = RandomStringUtils.randomAlphabetic(10); +     +    // set constant country-code and sourcePin to check hashed eIDAS identifier +    String sourcePinMandate = "asfdsadfsadfsafsdafsadfasr";        +    spConfig.put("target", EaafConstants.URN_PREFIX_EIDAS + "AT+EE"); +     +    // set nat. person mandate information +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, commonMandate); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, sourcePinMandate); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME,  +            EaafConstants.URN_PREFIX_BASEID + "+XFN");             +     +    oaParam.setRequestedAttributes(Sets.newHashSet( +        PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME,  +        PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME,  +        PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME)); +     +    // execute test +    IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq); + +     +    // validate state +    Assert.assertNotNull("AuthData null", authData);     +    assertTrue("mandate flag", ((EidAuthenticationData)authData).isUseMandate()); +     +    //check mandate informations +    checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_LEG_PER_FULL_NAME_NAME, commonMandate); +    checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, sourcePinMandate); +         +  } +   +  @Test +  public void eidasProxyModeWithJurMandateMissingAttribute() throws EaafAuthenticationException, EaafStorageException { +    // initialize state     +    injectRepresentativeInfosIntoSession(); +     +    // set constant country-code and sourcePin to check hashed eIDAS identifier +    String sourcePinMandate = "asfdsadfsadfsafsdafsadfasr";        +    spConfig.put("target", EaafConstants.URN_PREFIX_EIDAS + "AT+EE"); +     +    // set nat. person mandate information +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_NAME, sourcePinMandate); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_LEG_PER_SOURCE_PIN_TYPE_NAME,  +            EaafConstants.URN_PREFIX_BASEID + "+XFN");             +     +    // execute test +    // execute test +    EaafAuthenticationException error = assertThrows(EaafAuthenticationException.class,  +        () -> authenticationDataBuilder.buildAuthenticationData(pendingReq)); +    Assert.assertEquals("wrong errorId", "builder.11", error.getErrorId()); +         +  } +   +  @Test +  public void eidasProxyModeWithNatMandate() throws EaafAuthenticationException, EaafStorageException { +    // initialize state     +    injectRepresentativeInfosIntoSession(); +     +    String givenNameMandate = RandomStringUtils.randomAlphabetic(10); +    String familyNameMandate = RandomStringUtils.randomAlphabetic(10); +    String dateOfBirthMandate = "1957-09-15"; +    String bpkMandate = RandomStringUtils.randomAlphanumeric(10); +         +    // set nat. person mandate information +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, dateOfBirthMandate); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, "AT+XX:" + bpkMandate); +             +    oaParam.setRequestedAttributes(Sets.newHashSet( +        PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME,  +        PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME,  +        PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, +        PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME)); +     +    // execute test +    IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq); + +     +    // validate state +    Assert.assertNotNull("AuthData null", authData);     +    assertTrue("mandate flag", ((EidAuthenticationData)authData).isUseMandate()); +     +    //check mandate informations +    checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate); +    checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate); +    checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, "1957-09-15"); +    checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, "AT+XX:" + bpkMandate); +         +  } +   +  @Test +  public void eidasProxyModeWithNatMandateWrongBpkFormat() throws EaafAuthenticationException, EaafStorageException { +    // initialize state +    injectRepresentativeInfosIntoSession(); +     +    String givenNameMandate = RandomStringUtils.randomAlphabetic(10); +    String familyNameMandate = RandomStringUtils.randomAlphabetic(10); +    String dateOfBirthMandate = "1957-09-15"; +    String bpkMandate = RandomStringUtils.randomAlphanumeric(10); +         +    // set nat. person mandate information +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, dateOfBirthMandate); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, bpkMandate); + +    oaParam.setRequestedAttributes(Sets.newHashSet( +        PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME,  +        PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME,  +        PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, +        PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME)); +     +    // execute test +    IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq); + +     +    // validate state +    Assert.assertNotNull("AuthData null", authData);     +    assertTrue("mandate flag", ((EidAuthenticationData)authData).isUseMandate()); +     +    //check mandate informations +    checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_GIVEN_NAME_NAME, givenNameMandate); +    checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate); +    checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, "1957-09-15"); +    checkGenericAttribute(authData, PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, bpkMandate); +         +  } +   +  @Test +  public void eidasProxyModeWithNatMandateMissingAttribute() throws EaafAuthenticationException, EaafStorageException { +    // initialize state +    injectRepresentativeInfosIntoSession(); +     +    String familyNameMandate = RandomStringUtils.randomAlphabetic(10); +    String dateOfBirthMandate = "1957-09-15"; +    String bpkMandate = RandomStringUtils.randomAlphanumeric(10); +         +    // set nat. person mandate information +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setUseMandates(true); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_FAMILY_NAME_NAME, familyNameMandate); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BIRTHDATE_NAME, dateOfBirthMandate); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.MANDATE_NAT_PER_BPK_NAME, bpkMandate); +     +    // execute test +    EaafAuthenticationException error = assertThrows(EaafAuthenticationException.class,  +        () -> authenticationDataBuilder.buildAuthenticationData(pendingReq)); +    Assert.assertEquals("wrong errorId", "builder.11", error.getErrorId()); +         +  } + +   +   +  @Test +  @SneakyThrows +  public void eidasProxyMode() throws EaafAuthenticationException { +    // initialize state +    pendingReq = new TestRequestImpl(); +    pendingReq.setAuthUrl("https://localhost/ms_connector"); +    pendingReq.setPendingReqId(RandomStringUtils.randomAlphanumeric(10)); +    pendingReq.setPiiTransactionId(RandomStringUtils.randomAlphanumeric(10)); +    pendingReq.setSpConfig(oaParam); +    boolean isTestIdentity = RandomUtils.nextBoolean(); +     +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setEidProcess(true); +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setForeigner(false); + +    String bpk = RandomStringUtils.randomAlphanumeric(10); +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession( +        PvpAttributeDefinitions.BPK_NAME, "eidas+AT+XX:" + bpk); +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession( +        PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max"); +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession( +        PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann"); +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession( +        PvpAttributeDefinitions.BIRTHDATE_NAME, "1940-01-01"); +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession( +        PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, +        "http://eidas.europa.eu/LoA/high"); +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession( +         PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, +         RandomStringUtils.randomAlphabetic(2)); +         +    String randAttr = RandomStringUtils.randomAlphabetic(10); +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession( +        randAttr, RandomStringUtils.randomAlphabetic(10)); + +    oaParam.setRequestedAttributes(Sets.newHashSet(randAttr, +        PvpAttributeDefinitions.BPK_NAME, +        PvpAttributeDefinitions.GIVEN_NAME_NAME,  +        PvpAttributeDefinitions.PRINCIPAL_NAME_NAME,  +        PvpAttributeDefinitions.BIRTHDATE_NAME, +        PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME, +        PvpAttributeDefinitions.EID_ISSUING_NATION_NAME)); +     +     +    // execute +    IAuthData authData = authenticationDataBuilder.buildAuthenticationData(pendingReq); + +    // validate state +    Assert.assertNotNull("AuthData null", authData); +    Assert.assertNull("authBlock null", authData.getGenericData(MsEidasNodeConstants.AUTH_DATA_SZR_AUTHBLOCK, String.class)); +    Assert.assertNull("eidasBind null", authData.getGenericData(MsEidasNodeConstants.AUTH_DATA_EIDAS_BIND, String.class)); +    Assert.assertNotNull("LoA null", authData.getEidasQaaLevel()); +         +    Assert.assertEquals("FamilyName", "Mustermann", authData.getFamilyName()); +    Assert.assertEquals("GivenName", "Max", authData.getGivenName()); +    Assert.assertEquals("DateOfBirth", "1940-01-01", authData.getDateOfBirth()); +     +    Assert.assertEquals("LoA", "http://eidas.europa.eu/LoA/high", authData.getEidasQaaLevel()); +    Assert.assertEquals("EID-ISSUING-NATION", +        pendingReq.getSessionData(AuthProcessDataWrapper.class).getGenericDataFromSession( +            PvpAttributeDefinitions.EID_ISSUING_NATION_NAME), +        authData.getCiticenCountryCode()); +     +    checkGenericAttribute(authData, PvpAttributeDefinitions.BPK_NAME, "eidas+AT+XX:" + bpk); +    checkGenericAttribute(authData, PvpAttributeDefinitions.GIVEN_NAME_NAME, "Max"); +    checkGenericAttribute(authData, PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, "Mustermann"); +    checkGenericAttribute(authData, PvpAttributeDefinitions.BIRTHDATE_NAME, "1940-01-01"); +     +    Assert.assertEquals("random optional attr.", +        pendingReq.getSessionData(AuthProcessDataWrapper.class).getGenericDataFromSession( +            randAttr), +        authData.getGenericData(randAttr, String.class)); +     +  } +   +   +   +  @Test    public void eidMode() throws EaafAuthenticationException {      // initialize state      boolean isTestIdentity = RandomUtils.nextBoolean(); @@ -207,10 +470,48 @@ public class AuthenticationDataBuilderTest {          authData.getBpk());      Assert.assertEquals("bPKType", EaafConstants.URN_PREFIX_CDID + "XX", authData.getBpkType());      Assert.assertNotNull("IDL", authData.getIdentityLink()); +        +  } + +  private void injectRepresentativeInfosIntoSession() throws EaafStorageException { +    boolean isTestIdentity = RandomUtils.nextBoolean(); +    pendingReq.getSessionData(EidAuthProcessDataWrapper.class).setTestIdentity(isTestIdentity); +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setEidProcess(true); +    String givenName = RandomStringUtils.randomAlphabetic(10); +    String familyName = RandomStringUtils.randomAlphabetic(10); +    String dateOfBirth = "1956-12-08"; +    String bpk = RandomStringUtils.randomAlphanumeric(10); +    String cc = pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .getGenericDataFromSession(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, String.class); +    String spC = RandomStringUtils.randomAlphabetic(2).toUpperCase(); +    spConfig.put("target", EaafConstants.URN_PREFIX_EIDAS + cc + "+" + spC); +     +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setEidProcess(true); +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setForeigner(false); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.GIVEN_NAME_NAME, givenName); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.PRINCIPAL_NAME_NAME, familyName); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.BIRTHDATE_NAME, dateOfBirth); +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +        .setGenericDataToSession(PvpAttributeDefinitions.BPK_NAME, bpk); +     +    //set LoA level attribute instead of explicit session-data +    pendingReq.getSessionData(AuthProcessDataWrapper.class) +    .setGenericDataToSession(PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME,  +        pendingReq.getSessionData(AuthProcessDataWrapper.class).getQaaLevel()); +    pendingReq.getSessionData(AuthProcessDataWrapper.class).setQaaLevel(null);    } +   +  private void checkGenericAttribute(IAuthData authData, String attrName, String expected) { +    assertEquals("Wrong: " + attrName, expected, authData.getGenericData(attrName, String.class)); +     +   } +      private IIdentityLink buildDummyIdl() {      return new IIdentityLink() { | 
