diff options
Diffstat (limited to 'eidas_modules')
14 files changed, 569 insertions, 161 deletions
| diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/InitialSearchResult.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/InitialSearchResult.java deleted file mode 100644 index 8fe69414..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/InitialSearchResult.java +++ /dev/null @@ -1,12 +0,0 @@ -package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao; - -public class InitialSearchResult { - -  int resultsZmr; -  int resultsErnb; - -  public int getResultCount() { -    return resultsErnb + resultsZmr; -  } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/MergedRegisterSearchResult.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/MergedRegisterSearchResult.java new file mode 100644 index 00000000..bc5b358d --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/MergedRegisterSearchResult.java @@ -0,0 +1,16 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao; + +import lombok.Data; + +import java.util.ArrayList; + +@Data public class MergedRegisterSearchResult { + +  ArrayList<RegisterResult> resultsZmr = new ArrayList<>(); +  ArrayList<RegisterResult> resultsErnb = new ArrayList<>(); + +  public int getResultCount() { +    return resultsZmr.size() + resultsErnb.size(); +  } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/RegisterResult.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/RegisterResult.java new file mode 100644 index 00000000..9509e7de --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/RegisterResult.java @@ -0,0 +1,59 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao; + +import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType; +import lombok.Data; + +@Data public class RegisterResult { + +  // MDS +  private String pseudonym = null; +  private String givenName = null; +  private String familyName = null; +  private String dateOfBirth = null; + +  // additional attributes +  private String placeOfBirth = null; +  private String birthName = null; +  private String taxNumber = null; +  private PostalAddressType address = null; + +  /** +   * Register search result. +   * @param pseudonym The pseudonym +   * @param givenName The givenName +   * @param familyName The familyName +   * @param dateOfBirth The dateOfBirth +   * @param placeOfBirth The placeOfBirth +   */ +  public RegisterResult(String pseudonym, String givenName, String familyName, String dateOfBirth, +                        String placeOfBirth) { +    this.pseudonym = pseudonym; +    this.givenName = givenName; +    this.familyName = familyName; +    this.dateOfBirth = dateOfBirth; +    this.placeOfBirth = placeOfBirth; +  } + +  /** +   * Register search result. +   * @param pseudonym The pseudonym +   * @param givenName The givenName +   * @param familyName The familyName +   * @param dateOfBirth The dateOfBirth +   * @param placeOfBirth The placeOfBirth +   * @param birthName The birthName +   * @param taxNumber The taxNumber +   * @param address The address +   */ +  public RegisterResult(String pseudonym, String givenName, String familyName, String dateOfBirth, +                        String placeOfBirth, String birthName, String taxNumber, PostalAddressType address) { +    this.pseudonym = pseudonym; +    this.givenName = givenName; +    this.familyName = familyName; +    this.dateOfBirth = dateOfBirth; +    this.placeOfBirth = placeOfBirth; +    this.birthName = birthName; +    this.taxNumber = taxNumber; +    this.address = address; +  } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleEidasData.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleEidasData.java new file mode 100644 index 00000000..0b116bfb --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleEidasData.java @@ -0,0 +1,52 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + +package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao; + +import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType; +import lombok.Data; +import org.joda.time.DateTime; + +import java.text.SimpleDateFormat; + +@Data public class SimpleEidasData { + +  private String citizenCountryCode = null; + +  // MDS +  private String pseudonym = null; +  private String givenName = null; +  private String familyName = null; +  private DateTime dateOfBirth = null; + +  // additional attributes +  private String placeOfBirth = null; +  private String birthName = null; +  private PostalAddressType address = null; +  private String taxNumber; + +  public String getFormatedDateOfBirth() { +    return new SimpleDateFormat("yyyy-MM-dd").format(dateOfBirth.toDate()); +  } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/DummyErnbClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/DummyErnbClient.java new file mode 100644 index 00000000..8b2379bf --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/DummyErnbClient.java @@ -0,0 +1,49 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.ernb; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; + +@Service("ErnbClientForeIDAS") +public class DummyErnbClient implements IErnbClient { + +  @Override +  public ArrayList<RegisterResult> searchWithPersonIdentifer(String personIdentifer) { +    switch (personIdentifer) { +      case "a12345": +      case "a12345-": +        return result1(); +      case "a123456": +        return result2(); +      default: +        return resultEmpty(); +    } +  } + +  @Override +  public ArrayList<RegisterResult> searchWithMds(String givenName, String familyName, String dateOfBirth) { +    return resultEmpty();//TODO will I only receive matches where all three values match perfectly? +  } + +  private ArrayList<RegisterResult> resultEmpty() { +    return new ArrayList<RegisterResult>();//Nobody found +  } + +  private ArrayList<RegisterResult> result1() { +    ArrayList<RegisterResult> results = new ArrayList<>(); +    RegisterResult result1 = new RegisterResult("a12345", "Tom", "Mustermann", "1950-01-01", "Wien"); +    results.add(result1); +    RegisterResult result2 = new RegisterResult("a12345-", "Tom", "Mustermann", "1950-01-01", "Wien"); +    results.add(result2); +    return results; +  } + +  private ArrayList<RegisterResult> result2() { +    ArrayList<RegisterResult> results = new ArrayList<>(); +    RegisterResult result = new RegisterResult("a123456", "Max", "Mustermann", "2000-01-01", "Wien"); +    results.add(result); +    return results; +  } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/IErnbClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/IErnbClient.java new file mode 100644 index 00000000..4873b939 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/IErnbClient.java @@ -0,0 +1,12 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.ernb; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult; + +import java.util.ArrayList; + +public interface IErnbClient { + +  ArrayList<RegisterResult> searchWithPersonIdentifer(String personIdentifer); + +  ArrayList<RegisterResult> searchWithMds(String givenName, String familyName, String dateOfBirth); +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ManualFixNecessaryException.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ManualFixNecessaryException.java index f3916ed6..c22e8135 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ManualFixNecessaryException.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ManualFixNecessaryException.java @@ -23,18 +23,16 @@  package at.asitplus.eidas.specific.modules.auth.eidas.v2.exception; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;  public class ManualFixNecessaryException extends EidasSAuthenticationException {    private static final long serialVersionUID = 1L;    public ManualFixNecessaryException(String personIdentifier) {      super("eidas.00", new Object[] { personIdentifier });//TODO "eidas.00" -    } -  public ManualFixNecessaryException(ErnbEidData eidData) { - +  public ManualFixNecessaryException(SimpleEidasData eidData) {      super("eidas.00", new Object[] { eidData.getPseudonym() });//TODO "eidas.00"   => what info to pass???    }  } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java index fe839c37..e3c1e00f 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java @@ -23,18 +23,6 @@  package at.asitplus.eidas.specific.modules.auth.eidas.v2.handler; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import com.google.common.collect.ImmutableSortedSet; -  import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException; @@ -46,12 +34,21 @@ import at.gv.egiz.eaaf.core.api.IRequest;  import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;  import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;  import at.gv.egiz.eaaf.core.impl.data.Triple; +import com.google.common.collect.ImmutableSortedSet;  import edu.umd.cs.findbugs.annotations.NonNull;  import eu.eidas.auth.commons.attribute.AttributeDefinition;  import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;  import eu.eidas.auth.commons.light.impl.LightRequest.Builder;  import eu.eidas.auth.commons.protocol.eidas.SpType; -import eu.eidas.auth.commons.protocol.eidas.impl.PostalAddress; +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern;  public abstract class AbstractEidProcessor implements INationalEidProcessor {    private static final Logger log = LoggerFactory.getLogger(AbstractEidProcessor.class); @@ -66,7 +63,6 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {      buildProviderNameAttribute(pendingReq, authnRequestBuilder);      buildRequestedAttributes(authnRequestBuilder); -    }    @Override @@ -91,13 +87,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {      result.setAddress(processAddress(eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTADDRESS)));      return result; -    } -   +    /**     * Get a Map of country-specific requested attributes. -   *  +   *     * @return     */    @NonNull @@ -105,7 +100,7 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {    /**     * Post-Process the eIDAS CurrentAddress attribute. -   *  +   *     * @param currentAddressObj eIDAS current address information     * @return current address or null if no attribute is available     * @throws EidPostProcessingException if post-processing fails @@ -113,34 +108,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {     */    protected PostalAddressType processAddress(Object currentAddressObj) throws EidPostProcessingException,        EidasAttributeException { - -    if (currentAddressObj != null) { -      if (currentAddressObj instanceof PostalAddress) { -        final PostalAddressType result = new PostalAddressType(); -        result.setPostalCode(((PostalAddress) currentAddressObj).getPostCode()); -        result.setMunicipality(((PostalAddress) currentAddressObj).getPostName()); - -        // TODO: add more mappings -         -        return result; - -      } else { -        log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_CURRENTADDRESS + " is of WRONG type"); -        throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTADDRESS); - -      } - -    } else { -      log.debug("NO '" + Constants.eIDAS_ATTR_CURRENTADDRESS + "' attribute. Post-Processing skipped ... "); -    } - -    return null; - +    return EidasResponseUtils.processAddress(currentAddressObj);    }    /**     * Post-Process the eIDAS BirthName attribute. -   *  +   *     * @param birthNameObj eIDAS birthname information     * @return birthName or null if no attribute is available     * @throws EidPostProcessingException if post-processing fails @@ -148,27 +121,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {     */    protected String processBirthName(Object birthNameObj) throws EidPostProcessingException,        EidasAttributeException { -    if (birthNameObj != null) { -      if (birthNameObj instanceof String) { -        return (String) birthNameObj; - -      } else { -        log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_BIRTHNAME + " is of WRONG type"); -        throw new EidasAttributeException(Constants.eIDAS_ATTR_BIRTHNAME); - -      } - -    } else { -      log.debug("NO '" + Constants.eIDAS_ATTR_BIRTHNAME + "' attribute. Post-Processing skipped ... "); -    } - -    return null; - +    return EidasResponseUtils.processBirthName(birthNameObj);    }    /**     * Post-Process the eIDAS PlaceOfBirth attribute. -   *  +   *     * @param placeOfBirthObj eIDAS Place-of-Birth information     * @return place of Birth or null if no attribute is available     * @throws EidPostProcessingException if post-processing fails @@ -176,27 +134,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {     */    protected String processPlaceOfBirth(Object placeOfBirthObj) throws EidPostProcessingException,        EidasAttributeException { -    if (placeOfBirthObj != null) { -      if (placeOfBirthObj instanceof String) { -        return (String) placeOfBirthObj; - -      } else { -        log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_PLACEOFBIRTH + " is of WRONG type"); -        throw new EidasAttributeException(Constants.eIDAS_ATTR_PLACEOFBIRTH); - -      } - -    } else { -      log.debug("NO '" + Constants.eIDAS_ATTR_PLACEOFBIRTH + "' attribute. Post-Processing skipped ... "); -    } - -    return null; - +    return EidasResponseUtils.processPlaceOfBirth(placeOfBirthObj);    }    /**     * Post-Process the eIDAS DateOfBirth attribute. -   *  +   *     * @param dateOfBirthObj eIDAS date-of-birth attribute information     * @return formated user's date-of-birth     * @throws EidasAttributeException    if NO attribute is available @@ -204,17 +147,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {     */    protected DateTime processDateOfBirth(Object dateOfBirthObj) throws EidPostProcessingException,        EidasAttributeException { -    if (dateOfBirthObj == null || !(dateOfBirthObj instanceof DateTime)) { -      throw new EidasAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH); -    } - -    return (DateTime) dateOfBirthObj; - +    return EidasResponseUtils.processDateOfBirth(dateOfBirthObj);    }    /**     * Post-Process the eIDAS GivenName attribute. -   *  +   *     * @param givenNameObj eIDAS givenName attribute information     * @return formated user's givenname     * @throws EidasAttributeException    if NO attribute is available @@ -222,17 +160,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {     */    protected String processGivenName(Object givenNameObj) throws EidPostProcessingException,        EidasAttributeException { -    if (givenNameObj == null || !(givenNameObj instanceof String)) { -      throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME); -    } - -    return (String) givenNameObj; - +    return EidasResponseUtils.processGivenName(givenNameObj);    }    /**     * Post-Process the eIDAS FamilyName attribute. -   *  +   *     * @param familyNameObj eIDAS familyName attribute information     * @return formated user's familyname     * @throws EidasAttributeException    if NO attribute is available @@ -240,17 +173,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {     */    protected String processFamilyName(Object familyNameObj) throws EidPostProcessingException,        EidasAttributeException { -    if (familyNameObj == null || !(familyNameObj instanceof String)) { -      throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTFAMILYNAME); -    } - -    return (String) familyNameObj; - +    return EidasResponseUtils.processFamilyName(familyNameObj);    }    /**     * Post-Process the eIDAS pseudonym to ERnB unique identifier. -   *  +   *     * @param personalIdObj eIDAS PersonalIdentifierAttribute     * @return Unique personal identifier without country-code information     * @throws EidasAttributeException    if NO attribute is available @@ -258,15 +186,7 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {     */    protected String processPseudonym(Object personalIdObj) throws EidPostProcessingException,        EidasAttributeException { -    if (personalIdObj == null || !(personalIdObj instanceof String)) { -      throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); -    } - -    final Triple<String, String, String> eIdentifier = -        EidasResponseUtils.parseEidasPersonalIdentifier((String) personalIdObj); - -    return eIdentifier.getThird(); - +    return EidasResponseUtils.processPseudonym(personalIdObj);    }    private void buildRequestedAttributes(Builder authnRequestBuilder) { @@ -332,8 +252,8 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {          final String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class);          if (StringUtils.isNotEmpty(providerName)              && basicConfig.getBasicConfigurationBoolean( -                Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME, -                false)) { +            Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME, +            false)) {            authnRequestBuilder.providerName(providerName);          } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/ICountrySpecificDetailSearchProcessor.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/ICountrySpecificDetailSearchProcessor.java index c35f6e16..13d9117d 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/ICountrySpecificDetailSearchProcessor.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/ICountrySpecificDetailSearchProcessor.java @@ -24,7 +24,7 @@  package at.asitplus.eidas.specific.modules.auth.eidas.v2.handler;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.CountrySpecificDetailSearchResult; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;  public interface ICountrySpecificDetailSearchProcessor { @@ -52,7 +52,7 @@ public interface ICountrySpecificDetailSearchProcessor {     * @param eidData eID data     * @return true if this implementation can handle the country, otherwise false     */ -  boolean canHandle(String countryCode, ErnbEidData eidData); +  boolean canHandle(String countryCode, SimpleEidasData eidData); -  CountrySpecificDetailSearchResult search(ErnbEidData eidData); +  CountrySpecificDetailSearchResult search(SimpleEidasData eidData);  } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java index d9f70a81..6f4cfefc 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java @@ -25,14 +25,19 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.CountrySpecificDetailSearchResult; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.InitialSearchResult; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.MergedRegisterSearchResult; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.ernb.IErnbClient; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.ManualFixNecessaryException;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.ICountrySpecificDetailSearchProcessor; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.ICcSpecificEidProcessingService;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.EidasResponseUtils; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr.IZmrClient;  import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;  import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; +import at.gv.egiz.eaaf.core.impl.data.Triple;  import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper;  import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;  import com.google.common.collect.ImmutableMap; @@ -75,13 +80,19 @@ public class InitialSearchTask extends AbstractAuthServletTask {    //  private IConfiguration basicConfig;    //  @Autowired    //  private SzrClient szrClient; -  @Autowired -  private ICcSpecificEidProcessingService eidPostProcessor; +  //  @Autowired +  //  private ICcSpecificEidProcessingService eidPostProcessor;    //  private static final String EID_STATUS = "urn:eidgvat:eid.status.eidas";    @Autowired    private ApplicationContext context; +  @Autowired +  private IErnbClient ernbClient; + +  @Autowired +  private IZmrClient zmrClient; +    @PostConstruct    private void initialize() {      log.debug("Initialize country specific detail search services ... "); @@ -127,36 +138,82 @@ public class InitialSearchTask extends AbstractAuthServletTask {            eidasResponse.getAttributes().getAttributeMap());        // post-process eIDAS attributes -      final ErnbEidData eidData = eidPostProcessor.postProcess(simpleAttrMap); - -      String personIdentifier = eidData.getPseudonym(); - -      //search in register(step 2) -      InitialSearchResult result = searchInZmrAndErnp(personIdentifier); -      switch (result.getResultCount()) { -        case 0: -          step5(result, eidData); -          break; -        case 1: -          step3(result, eidData); -          break; -        default://should not happen -          throw new TaskExecutionException(pendingReq, "Initial search - Kitt Process necessary.", -              new ManualFixNecessaryException(personIdentifier)); -      } +      final SimpleEidasData eidData = convertSimpleMapToSimpleData(simpleAttrMap); +      step2(eidData);      } catch (final Exception e) {        log.error("Initial search FAILED.", e);        throw new TaskExecutionException(pendingReq, "Initial search FAILED.", e);      }    } -  private void step3(InitialSearchResult result, ErnbEidData eidData) { +  private void step2(SimpleEidasData eidData) throws TaskExecutionException { +    String personIdentifier = eidData.getPseudonym(); +    //search in register(step 2) +    MergedRegisterSearchResult result = searchInZmrAndErnp(personIdentifier); +    switch (result.getResultCount()) { +      case 0: +        step5(result, eidData); +        break; +      case 1: +        step3(result, eidData); +        break; +      default://should not happen +        throw new TaskExecutionException(pendingReq, "Initial search - Kitt Process necessary.", +            new ManualFixNecessaryException(personIdentifier)); +    } +  } + +  private SimpleEidasData convertSimpleMapToSimpleData(Map<String, Object> eidasAttrMap) +      throws EidasAttributeException, EidPostProcessingException { +    SimpleEidasData simpleEidasData = new SimpleEidasData(); + +    final Object eIdentifierObj = eidasAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); +    final Triple<String, String, String> eIdentifier = +        EidasResponseUtils.parseEidasPersonalIdentifier((String) eIdentifierObj); +    simpleEidasData.setCitizenCountryCode(eIdentifier.getFirst()); + +    // MDS attributes +    simpleEidasData.setPseudonym(EidasResponseUtils.processPseudonym( +        eidasAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER))); +    simpleEidasData.setFamilyName(EidasResponseUtils.processFamilyName( +        eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTFAMILYNAME))); +    simpleEidasData.setGivenName(EidasResponseUtils.processGivenName( +        eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTGIVENNAME))); +    simpleEidasData.setDateOfBirth(EidasResponseUtils.processDateOfBirth( +        eidasAttrMap.get(Constants.eIDAS_ATTR_DATEOFBIRTH))); + +    // additional attributes +    simpleEidasData.setPlaceOfBirth(EidasResponseUtils.processPlaceOfBirth( +        eidasAttrMap.get(Constants.eIDAS_ATTR_PLACEOFBIRTH))); +    simpleEidasData.setBirthName(EidasResponseUtils.processBirthName( +        eidasAttrMap.get(Constants.eIDAS_ATTR_BIRTHNAME))); +    simpleEidasData.setAddress(EidasResponseUtils.processAddress( +        eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTADDRESS))); + +    //TODO other additional attributes +    return simpleEidasData; +  } + +  private void step3(MergedRegisterSearchResult result, SimpleEidasData eidData) {      //check if data from eidas authentication matches with data from register -    //TODO +    log.debug("Compare " + result + " with " + eidData); +    //TODO check if data matches +    boolean match = true; +    if (match) { +      return; +    } else { +      step4(result, eidData); +    }    } -  private void step5(InitialSearchResult result, ErnbEidData eidData) throws TaskExecutionException { +  private void step4(MergedRegisterSearchResult result, SimpleEidasData eidData) { +    log.debug("Update " + result + " with " + eidData); +    //TODO +  } + +  private void step5(MergedRegisterSearchResult result, SimpleEidasData eidData) +      throws TaskExecutionException {      String citizenCountry = eidData.getCitizenCountryCode();      ICountrySpecificDetailSearchProcessor foundHandler = null;      for (final ICountrySpecificDetailSearchProcessor el : handlers) { @@ -178,7 +235,8 @@ public class InitialSearchTask extends AbstractAuthServletTask {    }    private void step6(ICountrySpecificDetailSearchProcessor countrySpecificDetailSearchProcessor, -                     InitialSearchResult initialSearchResult, ErnbEidData eidData) throws TaskExecutionException { +                     MergedRegisterSearchResult initialSearchResult, SimpleEidasData eidData) +      throws TaskExecutionException {      //6 country specific search      CountrySpecificDetailSearchResult countrySpecificDetailSearchResult =          countrySpecificDetailSearchProcessor.search(eidData); @@ -196,19 +254,40 @@ public class InitialSearchTask extends AbstractAuthServletTask {      }    } -  private void step7a(InitialSearchResult initialSearchResult, -                      CountrySpecificDetailSearchResult countrySpecificDetailSearchResult, ErnbEidData eidData) { +  private void step7a(MergedRegisterSearchResult initialSearchResult, +                      CountrySpecificDetailSearchResult countrySpecificDetailSearchResult, SimpleEidasData eidData) {      //TODO automerge - +    log.debug("Automerge " + initialSearchResult + " with " + eidData + " " + countrySpecificDetailSearchResult);    } -  private void step8(InitialSearchResult initialSearchResult, ErnbEidData eidData) { -    //TODO MDS Suche +  private void step8(MergedRegisterSearchResult initialSearchResult, SimpleEidasData eidData) { +    MergedRegisterSearchResult mdsSearchResult = new MergedRegisterSearchResult(); + +    ArrayList<RegisterResult> resultsZmr = +        zmrClient.searchWithMds(eidData.getGivenName(), eidData.getFamilyName(), eidData.getFormatedDateOfBirth()); +    mdsSearchResult.setResultsZmr(resultsZmr); + +    ArrayList<RegisterResult> resultsErnb = +        ernbClient.searchWithMds(eidData.getGivenName(), eidData.getFamilyName(), eidData.getFormatedDateOfBirth()); +    mdsSearchResult.setResultsErnb(resultsErnb); + +    log.debug("Automerge " + initialSearchResult + " with " + eidData + " " + mdsSearchResult); +    //TODO +    } -  private InitialSearchResult searchInZmrAndErnp(String personIdentifier) { -    //search TODO -    return new InitialSearchResult();//TODO +  private MergedRegisterSearchResult searchInZmrAndErnp(String personIdentifier) { +    MergedRegisterSearchResult initialSearchResult = new MergedRegisterSearchResult(); + +    ArrayList<RegisterResult> resultsZmr = +        zmrClient.searchWithPersonIdentifer(personIdentifier); +    initialSearchResult.setResultsZmr(resultsZmr); + +    ArrayList<RegisterResult> resultsErnb = +        ernbClient.searchWithPersonIdentifer(personIdentifier); +    initialSearchResult.setResultsErnb(resultsErnb); + +    return initialSearchResult;    }    private Map<String, Object> convertEidasAttrToSimpleMap( diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java index ebd2ae78..c68a602b 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java @@ -30,6 +30,9 @@ import java.util.regex.Pattern;  import javax.annotation.Nullable; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException; +import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType;  import org.apache.commons.lang3.StringUtils;  import org.joda.time.DateTime;  import org.slf4j.Logger; @@ -169,4 +172,169 @@ public class EidasResponseUtils {    } +  /** +   * Post-Process the eIDAS CurrentAddress attribute. +   * +   * @param currentAddressObj eIDAS current address information +   * @return current address or null if no attribute is available +   * @throws EidPostProcessingException if post-processing fails +   * @throws EidasAttributeException    if eIDAS attribute is of a wrong type +   */ +  public static PostalAddressType processAddress(Object currentAddressObj) throws EidPostProcessingException, +      EidasAttributeException { + +    if (currentAddressObj != null) { +      if (currentAddressObj instanceof PostalAddress) { +        final PostalAddressType result = new PostalAddressType(); +        result.setPostalCode(((PostalAddress) currentAddressObj).getPostCode()); +        result.setMunicipality(((PostalAddress) currentAddressObj).getPostName()); + +        // TODO: add more mappings + +        return result; + +      } else { +        log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_CURRENTADDRESS + " is of WRONG type"); +        throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTADDRESS); + +      } + +    } else { +      log.debug("NO '" + Constants.eIDAS_ATTR_CURRENTADDRESS + "' attribute. Post-Processing skipped ... "); +    } + +    return null; + +  } + +  /** +   * Post-Process the eIDAS BirthName attribute. +   * +   * @param birthNameObj eIDAS birthname information +   * @return birthName or null if no attribute is available +   * @throws EidPostProcessingException if post-processing fails +   * @throws EidasAttributeException    if eIDAS attribute is of a wrong type +   */ +  public static String processBirthName(Object birthNameObj) throws EidPostProcessingException, +      EidasAttributeException { +    if (birthNameObj != null) { +      if (birthNameObj instanceof String) { +        return (String) birthNameObj; + +      } else { +        log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_BIRTHNAME + " is of WRONG type"); +        throw new EidasAttributeException(Constants.eIDAS_ATTR_BIRTHNAME); + +      } + +    } else { +      log.debug("NO '" + Constants.eIDAS_ATTR_BIRTHNAME + "' attribute. Post-Processing skipped ... "); +    } + +    return null; + +  } + +  /** +   * Post-Process the eIDAS PlaceOfBirth attribute. +   * +   * @param placeOfBirthObj eIDAS Place-of-Birth information +   * @return place of Birth or null if no attribute is available +   * @throws EidPostProcessingException if post-processing fails +   * @throws EidasAttributeException    if eIDAS attribute is of a wrong type +   */ +  public static String processPlaceOfBirth(Object placeOfBirthObj) throws EidPostProcessingException, +      EidasAttributeException { +    if (placeOfBirthObj != null) { +      if (placeOfBirthObj instanceof String) { +        return (String) placeOfBirthObj; + +      } else { +        log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_PLACEOFBIRTH + " is of WRONG type"); +        throw new EidasAttributeException(Constants.eIDAS_ATTR_PLACEOFBIRTH); + +      } + +    } else { +      log.debug("NO '" + Constants.eIDAS_ATTR_PLACEOFBIRTH + "' attribute. Post-Processing skipped ... "); +    } + +    return null; + +  } + +  /** +   * Post-Process the eIDAS DateOfBirth attribute. +   * +   * @param dateOfBirthObj eIDAS date-of-birth attribute information +   * @return formated user's date-of-birth +   * @throws EidasAttributeException    if NO attribute is available +   * @throws EidPostProcessingException if post-processing fails +   */ +  public static DateTime processDateOfBirth(Object dateOfBirthObj) throws EidPostProcessingException, +      EidasAttributeException { +    if (dateOfBirthObj == null || !(dateOfBirthObj instanceof DateTime)) { +      throw new EidasAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH); +    } + +    return (DateTime) dateOfBirthObj; + +  } + +  /** +   * Post-Process the eIDAS GivenName attribute. +   * +   * @param givenNameObj eIDAS givenName attribute information +   * @return formated user's givenname +   * @throws EidasAttributeException    if NO attribute is available +   * @throws EidPostProcessingException if post-processing fails +   */ +  public static String processGivenName(Object givenNameObj) throws EidPostProcessingException, +      EidasAttributeException { +    if (givenNameObj == null || !(givenNameObj instanceof String)) { +      throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME); +    } + +    return (String) givenNameObj; + +  } + +  /** +   * Post-Process the eIDAS FamilyName attribute. +   * +   * @param familyNameObj eIDAS familyName attribute information +   * @return formated user's familyname +   * @throws EidasAttributeException    if NO attribute is available +   * @throws EidPostProcessingException if post-processing fails +   */ +  public static String processFamilyName(Object familyNameObj) throws EidPostProcessingException, +      EidasAttributeException { +    if (familyNameObj == null || !(familyNameObj instanceof String)) { +      throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTFAMILYNAME); +    } + +    return (String) familyNameObj; + +  } + +  /** +   * Post-Process the eIDAS pseudonym to ERnB unique identifier. +   * +   * @param personalIdObj eIDAS PersonalIdentifierAttribute +   * @return Unique personal identifier without country-code information +   * @throws EidasAttributeException    if NO attribute is available +   * @throws EidPostProcessingException if post-processing fails +   */ +  public static String processPseudonym(Object personalIdObj) throws EidPostProcessingException, +      EidasAttributeException { +    if (personalIdObj == null || !(personalIdObj instanceof String)) { +      throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); +    } + +    final Triple<String, String, String> eIdentifier = +        EidasResponseUtils.parseEidasPersonalIdentifier((String) personalIdObj); + +    return eIdentifier.getThird(); + +  }  } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/DummyZmrClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/DummyZmrClient.java new file mode 100644 index 00000000..9a7cc9b3 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/DummyZmrClient.java @@ -0,0 +1,49 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; + +@Service("ZmrClientForeIDAS") +public class DummyZmrClient implements IZmrClient { + +  @Override +  public ArrayList<RegisterResult> searchWithPersonIdentifer(String personIdentifer) { +    switch (personIdentifer) { +      case "a12345": +      case "a12345-": +        return result1(); +      case "a123456": +        return result2(); +      default: +        return resultEmpty(); +    } +  } + +  @Override +  public ArrayList<RegisterResult> searchWithMds(String givenName, String familyName, String dateOfBirth) { +    return resultEmpty();//TODO will I only receive matches where all three values match perfectly? +  } + +  private ArrayList<RegisterResult> resultEmpty() { +    return new ArrayList<RegisterResult>();//Nobody found +  } + +  private ArrayList<RegisterResult> result1() { +    ArrayList<RegisterResult> results = new ArrayList<>(); +    RegisterResult result1 = new RegisterResult("12345", "Tom", "Mustermann", "1950-01-01", "Wien"); +    results.add(result1); +    RegisterResult result2 = new RegisterResult("12345-", "Tom", "Mustermann", "1950-01-01", "Wien"); +    results.add(result2); +    return results; +  } + +  private ArrayList<RegisterResult> result2() { +    ArrayList<RegisterResult> results = new ArrayList<>(); +    RegisterResult result = new RegisterResult("123456", "Max", "Mustermann", "2000-01-01", "Wien"); +    results.add(result); +    return results; +  } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/IZmrClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/IZmrClient.java new file mode 100644 index 00000000..1f7e4949 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/IZmrClient.java @@ -0,0 +1,12 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult; + +import java.util.ArrayList; + +public interface IZmrClient { + +  ArrayList<RegisterResult> searchWithPersonIdentifer(String personIdentifer); + +  ArrayList<RegisterResult> searchWithMds(String givenName, String familyName, String dateOfBirth); +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml index 9c28bf07..0f6277c0 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml @@ -17,6 +17,12 @@    <bean id="SZRClientForeIDAS"      class="at.asitplus.eidas.specific.modules.auth.eidas.v2.szr.SzrClient" /> +  <bean id="ErnbClientForeIDAS" +        class="at.asitplus.eidas.specific.modules.auth.eidas.v2.ernb.DummyErnbClient" /> + +  <bean id="ZmrClientForeIDAS" +        class="at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr.DummyZmrClient" /> +    <bean id="specificConnectorAttributesFile"      class="java.lang.String">      <constructor-arg value="eidas-attributes.xml" /> | 
