From 8c08120d543f4eba2b1d1480d6649f13c46e9ef0 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Mon, 7 Feb 2022 10:37:42 +0100 Subject: feature(ernp): add person into ERnP of mathing ends with no result --- .../auth/eidas/v2/clients/ernp/ErnpRestClient.java | 301 ++++++++++++--------- .../auth/eidas/v2/clients/ernp/IErnpClient.java | 12 + .../auth/eidas/v2/ernp/DummyErnpClient.java | 5 + .../eidas/v2/tasks/CreateNewErnpEntryTask.java | 58 ++-- .../test/clients/ErnpRestClientProductionTest.java | 87 ++++++ .../v2/test/tasks/CreateNewErnpEntryTaskTest.java | 198 ++++++++++++++ 6 files changed, 517 insertions(+), 144 deletions(-) create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ErnpRestClientProductionTest.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateNewErnpEntryTaskTest.java (limited to 'eidas_modules/authmodule-eIDAS-v2') diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java index 2eaece1d..58b3ca45 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java @@ -41,11 +41,14 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.api.DefaultApi; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.invoker.ApiClient; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.AendernResponse; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.AnlegenResponse; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.Eidas; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.PartialDate; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.Person; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.PersonAendern; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.PersonAnlegen; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.PersonSuchen; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.Personendaten; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.SuchEidas; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.Suchdaten; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.SuchenResponse; @@ -100,7 +103,8 @@ public class ErnpRestClient implements IErnpClient { private static final String PROCESS_KITT_GENERAL = "KITT general-processing"; private static final String PROCESS_KITT_IDENITIES_GET = "KITT get-latest-version"; private static final String PROCESS_KITT_IDENITIES_UPDATE = "KITT update dataset"; - + private static final String PROCESS_ADD_IDENITY = "Add new person"; + private static final String FRIENDLYNAME_HTTP_CLIENT = "ERnP Client"; // HTTP header-names from ERnP response @@ -272,141 +276,41 @@ public class ErnpRestClient implements IErnpClient { } } - private ErnpRegisterResult updatePersonInErnp(Person ernpPersonToKitt, - Collection eidasDocumentToAdd, String citizenCountryCode) - throws ServiceFault { + @Override + public ErnpRegisterResult add(SimpleEidasData eidData) throws EidasSAuthenticationException { // build generic request metadata - final GenericRequestParams generic = buildGenericRequestParameters("stepKittUpdate"); + final GenericRequestParams generic = buildGenericRequestParameters("stepNew"); // build update request - PersonAendern ernpReq = new PersonAendern(); - ernpReq.setBegruendung(PROCESS_KITT_IDENITIES_UPDATE); - - // set reference elements for person update - ernpReq.setEntityId(ernpPersonToKitt.getEntityId()); - ernpReq.setVersion(ernpPersonToKitt.getVersion()); - - // add new eIDAS attributes - eidasDocumentToAdd.stream().forEach(el -> ernpReq.getAnlegen().addEidasItem(el)); - - // TODO: should we update MDS also in that step? - + PersonAnlegen ernpReq = new PersonAnlegen(); + ernpReq.setBegruendung(PROCESS_ADD_IDENITY); + + // inject person data + Personendaten person = new Personendaten(); + person.setFamilienname(eidData.getFamilyName()); + person.setVorname(eidData.getGivenName()); + person.setGeburtsdatum(buildErnpBirthday(eidData.getDateOfBirth())); + ernpReq.setPersonendaten(person); - // request ZMR - log.trace("Requesting ERnP for '{}' operation", PROCESS_KITT_IDENITIES_UPDATE); - AendernResponse ernpResp = ernpClient.aendern(generic.getClientBehkz(), generic.clientName, + buildNewEidasDocumens(ernpReq, eidData); + + // request ERnP + log.trace("Requesting ERnP for '{}' operation", PROCESS_ADD_IDENITY); + AnlegenResponse ernpResp = ernpClient.anlegen(generic.getClientBehkz(), generic.clientName, generic.getClientRequestTime(), generic.getClientRequestId(), ernpReq); - log.trace("Receive response from ERnP for '{}' operation", PROCESS_KITT_IDENITIES_UPDATE); + log.trace("Receive response from ERnP for '{}' operation", PROCESS_ADD_IDENITY); return new ErnpRegisterResult(Arrays.asList( - mapErnpResponseToRegisterResult(ernpResp.getPerson(), citizenCountryCode))); - - } - - private Collection selectEidasDocumentsToAdd( - Person ernpPersonToKitt, SimpleEidasData eidData) { - - //TODO: maybe we should re-factor SimpleEidasData to a generic data-model to facilitate arbitrary eIDAS attributes - Set result = new HashSet<>(); - addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(), - Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym(), true); - addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(), - Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth(), false); - addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(), - Constants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName(), false); - - return result; + mapErnpResponseToRegisterResult(ernpResp.getPerson(), eidData.getCitizenCountryCode()))); } - private void addEidasDocumentIfNotAvailable(Set result, - Person ernpPersonToKitt, String citizenCountryCode, - String attrName, String attrValue, boolean allowMoreThanOneEntry) { - - if (StringUtils.isEmpty(attrValue)) { - log.trace("No eIDAS document: {}. Nothing todo for KITT process ... ", attrName); - return; - - } - - // check if eIDAS attribute is already includes an eIDAS-Document - boolean alreadyExist = ernpPersonToKitt.getEidas().stream() - .filter(el -> el.getWert().equals(attrValue) - && el.getArt().equals(attrName) - && el.getStaatscode2().equals(citizenCountryCode)) - .findAny() - .isPresent(); - - if (!alreadyExist) { - // check eIDAS documents already contains a document with this pair of country-code and attribute-name - Optional oneDocWithNameExists = ernpPersonToKitt.getEidas().stream() - .filter(el -> el.getStaatscode2().equals(citizenCountryCode) - && el.getArt().equals(attrName)) - .findAny(); - - if (!allowMoreThanOneEntry && oneDocWithNameExists.isPresent() - && !oneDocWithNameExists.get().getWert().equals(attrValue)) { - log.warn("eIDAS document: {} already exists for country: {} but attribute-value does not match. " - + "Skip update process because no multi-value allowed for this ... ", - attrName, citizenCountryCode); - - } else { - - Eidas eidasDocToAdd = new Eidas(); - eidasDocToAdd.setStaatscode2(citizenCountryCode); - eidasDocToAdd.setArt(attrName); - eidasDocToAdd.setWert(attrValue); - log.info("Add eIDAS document: {} for country: {} to ERnP person", attrName, citizenCountryCode); - result.add(eidasDocToAdd); - - } - - } else { - log.debug("eIDAS document: {} already exists for country: {}. Skip update process for this ... ", - attrName, citizenCountryCode); - - } - } - - private Person searchPersonForUpdate(RegisterResult registerResult) throws WorkflowException { - // build generic request metadata - final GenericRequestParams generic = buildGenericRequestParameters("stepKittSearch"); - - // build search request - final Suchdaten searchInfos = new Suchdaten(); - searchInfos.setFamilienname(registerResult.getFamilyName()); - searchInfos.setVorname(registerResult.getGivenName()); - searchInfos.setGeburtsdatum(buildErnpBirthday(registerResult.getDateOfBirth())); - - final PersonSuchen personSuchen = new PersonSuchen(); - personSuchen.setSuchoptionen(generateSearchParameters()); - personSuchen.setBegruendung(PROCESS_KITT_IDENITIES_GET); - personSuchen.setSuchdaten(searchInfos); - - // request ERnP - log.trace("Requesting ERnP for '{}' operation", PROCESS_KITT_IDENITIES_GET); - final SuchenResponse resp = ernpClient.suchen(generic.getClientBehkz(), generic.clientName, - generic.getClientRequestTime(), generic.getClientRequestId(), personSuchen); - - // perform shot validation of ERnP response - if (resp.getPerson() == null || resp.getPerson().size() != 1) { - log.error("ERnP result contains NO 'Person' or 'Person' is empty"); - throw new WorkflowException(PROCESS_KITT_IDENITIES_GET, - "Find NO data-set with already matchted eID during ERnP KITT process"); - - } else { - log.debug("Find person for '{}' operation", PROCESS_KITT_IDENITIES_GET); - return resp.getPerson().get(0); - - } - } - @Override public ErnpRegisterResult searchWithResidenceData(String givenName, String familyName, String dateOfBirth, String zipcode, String city, String street) { return new ErnpRegisterResult(Collections.emptyList()); } - + @PostConstruct private void initialize() throws EaafException { // validate additional Ernp communication parameters @@ -545,6 +449,161 @@ public class ErnpRestClient implements IErnpClient { } + private ErnpRegisterResult updatePersonInErnp(Person ernpPersonToKitt, + Collection eidasDocumentToAdd, String citizenCountryCode) + throws ServiceFault { + // build generic request metadata + final GenericRequestParams generic = buildGenericRequestParameters("stepKittUpdate"); + + // build update request + PersonAendern ernpReq = new PersonAendern(); + ernpReq.setBegruendung(PROCESS_KITT_IDENITIES_UPDATE); + + // set reference elements for person update + ernpReq.setEntityId(ernpPersonToKitt.getEntityId()); + ernpReq.setVersion(ernpPersonToKitt.getVersion()); + + // add new eIDAS attributes + eidasDocumentToAdd.stream().forEach(el -> ernpReq.getAnlegen().addEidasItem(el)); + + // TODO: should we update MDS also in that step? + + + // request ERnP + log.trace("Requesting ERnP for '{}' operation", PROCESS_KITT_IDENITIES_UPDATE); + AendernResponse ernpResp = ernpClient.aendern(generic.getClientBehkz(), generic.clientName, + generic.getClientRequestTime(), generic.getClientRequestId(), ernpReq); + log.trace("Receive response from ERnP for '{}' operation", PROCESS_KITT_IDENITIES_UPDATE); + + return new ErnpRegisterResult(Arrays.asList( + mapErnpResponseToRegisterResult(ernpResp.getPerson(), citizenCountryCode))); + + } + + private Collection selectEidasDocumentsToAdd( + Person ernpPersonToKitt, SimpleEidasData eidData) { + + //TODO: maybe we should re-factor SimpleEidasData to a generic data-model to facilitate arbitrary eIDAS attributes + Set result = new HashSet<>(); + addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(), + Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym(), true); + addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(), + Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth(), false); + addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(), + Constants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName(), false); + + return result; + + } + + private void addEidasDocumentIfNotAvailable(Set result, + Person ernpPersonToKitt, String citizenCountryCode, + String attrName, String attrValue, boolean allowMoreThanOneEntry) { + + if (StringUtils.isEmpty(attrValue)) { + log.trace("No eIDAS document: {}. Nothing todo for KITT process ... ", attrName); + return; + + } + + // check if eIDAS attribute is already includes an eIDAS-Document + boolean alreadyExist = ernpPersonToKitt.getEidas().stream() + .filter(el -> el.getWert().equals(attrValue) + && el.getArt().equals(attrName) + && el.getStaatscode2().equals(citizenCountryCode)) + .findAny() + .isPresent(); + + if (!alreadyExist) { + // check eIDAS documents already contains a document with this pair of country-code and attribute-name + Optional oneDocWithNameExists = ernpPersonToKitt.getEidas().stream() + .filter(el -> el.getStaatscode2().equals(citizenCountryCode) + && el.getArt().equals(attrName)) + .findAny(); + + if (!allowMoreThanOneEntry && oneDocWithNameExists.isPresent() + && !oneDocWithNameExists.get().getWert().equals(attrValue)) { + log.warn("eIDAS document: {} already exists for country: {} but attribute-value does not match. " + + "Skip update process because no multi-value allowed for this ... ", + attrName, citizenCountryCode); + + } else { + + Eidas eidasDocToAdd = new Eidas(); + eidasDocToAdd.setStaatscode2(citizenCountryCode); + eidasDocToAdd.setArt(attrName); + eidasDocToAdd.setWert(attrValue); + log.info("Add eIDAS document: {} for country: {} to ERnP person", attrName, citizenCountryCode); + result.add(eidasDocToAdd); + + } + + } else { + log.debug("eIDAS document: {} already exists for country: {}. Skip update process for this ... ", + attrName, citizenCountryCode); + + } + } + + private Person searchPersonForUpdate(RegisterResult registerResult) throws WorkflowException { + // build generic request metadata + final GenericRequestParams generic = buildGenericRequestParameters("stepKittSearch"); + + // build search request + final Suchdaten searchInfos = new Suchdaten(); + searchInfos.setFamilienname(registerResult.getFamilyName()); + searchInfos.setVorname(registerResult.getGivenName()); + searchInfos.setGeburtsdatum(buildErnpBirthday(registerResult.getDateOfBirth())); + + final PersonSuchen personSuchen = new PersonSuchen(); + personSuchen.setSuchoptionen(generateSearchParameters()); + personSuchen.setBegruendung(PROCESS_KITT_IDENITIES_GET); + personSuchen.setSuchdaten(searchInfos); + + // request ERnP + log.trace("Requesting ERnP for '{}' operation", PROCESS_KITT_IDENITIES_GET); + final SuchenResponse resp = ernpClient.suchen(generic.getClientBehkz(), generic.clientName, + generic.getClientRequestTime(), generic.getClientRequestId(), personSuchen); + + // perform shot validation of ERnP response + if (resp.getPerson() == null || resp.getPerson().size() != 1) { + log.error("ERnP result contains NO 'Person' or 'Person' is empty"); + throw new WorkflowException(PROCESS_KITT_IDENITIES_GET, + "Find NO data-set with already matchted eID during ERnP KITT process"); + + } else { + log.debug("Find person for '{}' operation", PROCESS_KITT_IDENITIES_GET); + return resp.getPerson().get(0); + + } + } + + private void buildNewEidasDocumens(PersonAnlegen ernpReq, SimpleEidasData eidData) { + ernpReq.addEidasItem(buildNewEidasDocument(eidData.getCitizenCountryCode(), + Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym())); + + if (StringUtils.isNotEmpty(eidData.getPlaceOfBirth())) { + ernpReq.addEidasItem(buildNewEidasDocument(eidData.getCitizenCountryCode(), + Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth())); + + } + + if (StringUtils.isNotEmpty(eidData.getBirthName())) { + ernpReq.addEidasItem(buildNewEidasDocument(eidData.getCitizenCountryCode(), + Constants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName())); + + } + } + + private Eidas buildNewEidasDocument(String citizenCountryCode, String eidasAttrName, + String eidasAddrValue) { + Eidas el = new Eidas(); + el.setArt(eidasAttrName); + el.setWert(eidasAddrValue); + el.setStaatscode2(citizenCountryCode); + return el; + } + /** * Map an AT specific Date String 'yyyy-MM-dd' to ERnP birthday representation. * diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java index 4c8bcd3e..7a957531 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java @@ -84,6 +84,18 @@ public interface IErnpClient { ErnpRegisterResult update(RegisterResult registerResult, SimpleEidasData eidData) throws EidasSAuthenticationException; + + /** + * Add new entry into ERnP by using identity from this eIDAS authentication. + * + * @param eidData eIDAS eID information from current authentication process + * @return Update result but never null + * @throws EidasSAuthenticationException In case of a communication error + */ + @Nonnull + ErnpRegisterResult add(SimpleEidasData eidData) throws EidasSAuthenticationException; + + /** * Search person based on address information. * diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/DummyErnpClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/DummyErnpClient.java index 52703232..dabb73dc 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/DummyErnpClient.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/DummyErnpClient.java @@ -73,4 +73,9 @@ public class DummyErnpClient implements IErnpClient { } + @Override + public ErnpRegisterResult add(SimpleEidasData eidData) throws EidasSAuthenticationException { + return buildEmptyResult(); + } + } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateNewErnpEntryTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateNewErnpEntryTask.java index 6fc6d499..b63b0ca0 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateNewErnpEntryTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateNewErnpEntryTask.java @@ -26,9 +26,16 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.ErnpRestClient; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.ErnpRestClient.ErnpRegisterResult; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.MatchedPersonResult; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.WorkflowException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils; 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.idp.auth.modules.AbstractAuthServletTask; @@ -46,6 +53,7 @@ import lombok.extern.slf4j.Slf4j; *
  • TODO MDS, BPK of new entry
  • * * + * @author tlenz * @author amarsalek * @author ckollmann */ @@ -53,36 +61,40 @@ import lombok.extern.slf4j.Slf4j; @Component("CreateNewErnbEntryTask") public class CreateNewErnpEntryTask extends AbstractAuthServletTask { - //private final SzrClient szrClient; + private final ErnpRestClient ernpClient; - ///** - // * Constructor. - // * @param szrClient SZR client for creating a new ERnP entry - // */ - //public CreateNewErnpEntryTask(SzrClient szrClient) { - // this.szrClient = szrClient; - //} + /** + * Constructor. + * @param szrClient SZR client for creating a new ERnP entry + */ + public CreateNewErnpEntryTask(@Autowired ErnpRestClient client) { + this.ernpClient = client; + } @Override public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) throws TaskExecutionException { try { - //SimpleEidasData simpleEidasData = MatchingTaskUtils.getInitialEidasData(pendingReq); - - // insert person into ERnP - //TODO: should we insert it directly into ERnP? - //TODO: has to updated to new eIDAS document model in ERnP - //String vsz = szrClient.createNewErnpEntry(simpleEidasData); - - // finish matching process, because new user-entry uniquly matches - //log.info("User successfully registerred into ERnP and matching tasks are finished "); - //MatchingTaskUtils.storeFinalMatchingResult(pendingReq, - // MatchedPersonResult.builder() - // .vsz(vsz) - // .build()); - - log.warn("Skipping new insert ERnP task, because it's currently unknown who we should it"); + SimpleEidasData simpleEidasData = MatchingTaskUtils.getInitialEidasData(pendingReq); + if (simpleEidasData == null) { + throw new WorkflowException("step09", "No initial eIDAS authn data", true); + + } + //add person into ERnP + ErnpRegisterResult resp = ernpClient.add(simpleEidasData); + if (resp.getPersonResult().size() != 1) { + log.error("Receive {} from ERnP during 'add person' step", + resp.getPersonResult().isEmpty() ? "no result" : "more-than-one result"); + throw new WorkflowException("step09", "Add person into ERnP failed", true); + + } + + // finish matching process, because new user-entry uniquly matches + log.info("User successfully registerred into ERnP and matching tasks are finished "); + MatchingTaskUtils.storeFinalMatchingResult(pendingReq, + MatchedPersonResult.generateFormMatchingResult( + resp.getPersonResult().get(0), simpleEidasData.getCitizenCountryCode())); } catch (final Exception e) { log.error("Initial search FAILED.", e); diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ErnpRestClientProductionTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ErnpRestClientProductionTest.java new file mode 100644 index 00000000..6ebe4c8a --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ErnpRestClientProductionTest.java @@ -0,0 +1,87 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.clients; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.IfProfileValue; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.ErnpRestClient.ErnpRegisterResult; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.IErnpClient; +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.exception.EidasSAuthenticationException; +import lombok.SneakyThrows; + +@IfProfileValue(name = "spring.profiles.active", value = "devEnvironment") +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { + "/SpringTest-context_tasks_test.xml", + "/SpringTest-context_basic_realConfig.xml"}) +@TestPropertySource(locations = { + //"classpath:/application.properties", + "file:/home/tlenz/Projekte/config/ms_connector/default_config.properties", + }) +public class ErnpRestClientProductionTest { + + @Autowired IErnpClient client; + + @Test + @SneakyThrows + public void searchWithPersonalIdentifierServerError() { + final String personalIdentifierFirst = "7cEYWithDEElementsasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit"; + final String cc = "DE"; + final SimpleEidasData eidasDataFirst = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName("XXXvon Brandenburg") + .givenName("XXXClaus - Maria") + .dateOfBirth("1994-12-31") + .personalIdentifier(cc + "/AT/" + personalIdentifierFirst) + .pseudonym(personalIdentifierFirst) + .build(); + + // execute operation + EidasSAuthenticationException error = assertThrows("wrong Exception", EidasSAuthenticationException.class, + () -> client.searchWithPersonIdentifier( + eidasDataFirst.getPseudonym(), eidasDataFirst.getCitizenCountryCode())); + + assertEquals("wrong errorCode", "module.eidasauth.matching.11", error.getErrorId()); + + } + + @Test + @SneakyThrows + public void searchWithPersonalIdentifierSuccess() { + final String personalIdentifierFirst = "7cEYWithDEElementsasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit"; + final String cc = "DE"; + final SimpleEidasData eidasDataFirst = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName("XXXvon Brandenburg") + .givenName("XXXClaus - Maria") + .dateOfBirth("1994-12-31") + .personalIdentifier(cc + "/AT/" + personalIdentifierFirst) + .pseudonym(personalIdentifierFirst) + .build(); + + // execute operation + ErnpRegisterResult resp = client.searchWithPersonIdentifier( + eidasDataFirst.getPseudonym(), eidasDataFirst.getCitizenCountryCode()); + + // validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + + RegisterResult persInfo = resp.getPersonResult().get(0); + assertEquals("wrong familyname", "XXXSZR", persInfo.getFamilyName()); + + + } + + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateNewErnpEntryTaskTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateNewErnpEntryTaskTest.java new file mode 100644 index 00000000..985a5e14 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateNewErnpEntryTaskTest.java @@ -0,0 +1,198 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.tasks; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; + +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang3.RandomStringUtils; +import org.jetbrains.annotations.NotNull; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.ErnpRestClient; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.ErnpRestClient.ErnpRegisterResult; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.MatchedPersonResult; +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.exception.WorkflowException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.CreateNewErnpEntryTask; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils; +import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; +import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; +import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; +import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl; +import at.gv.egiz.eaaf.core.impl.idp.process.ExecutionContextImpl; +import lombok.SneakyThrows; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { + "/SpringTest-context_tasks_test.xml", + "/SpringTest-context_basic_mapConfig.xml" +}) +@DirtiesContext(classMode = ClassMode.BEFORE_CLASS) +public class CreateNewErnpEntryTaskTest { + + CreateNewErnpEntryTask task; + + @Mock ErnpRestClient ernpClient; + + final ExecutionContext executionContext = new ExecutionContextImpl(); + private TestRequestImpl pendingReq; + + /** + * jUnit test set-up. + */ + @Before + public void setUp() throws URISyntaxException, EaafStorageException { + task = new CreateNewErnpEntryTask(ernpClient); + + MockHttpServletRequest httpReq = new MockHttpServletRequest("POST", "https://localhost/authhandler"); + MockHttpServletResponse httpResp = new MockHttpServletResponse(); + RequestContextHolder.resetRequestAttributes(); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); + + pendingReq = new TestRequestImpl(); + pendingReq.setPendingReqId(RandomStringUtils.randomAlphanumeric(10)); + + } + + + @Test + @SneakyThrows + public void missingEidasData() { + Mockito.when(ernpClient.add(any())) + .thenThrow(new IllegalStateException("add ERnP entry should not be neccessary")); + + TaskExecutionException error = assertThrows("wrong exception", TaskExecutionException.class, + () -> task.execute(pendingReq, executionContext)); + + assertEquals("wrong pendingRequestId", pendingReq.getPendingRequestId(), error.getPendingRequestID()); + assertTrue("Wrong exception", (error.getOriginalException() instanceof WorkflowException)); + assertTrue("Wrong flag 'manualFixNeeded'", + ((WorkflowException) error.getOriginalException()).isRequiresManualFix()); + + } + + @Test + @SneakyThrows + public void noErnpResponse() { + SimpleEidasData input = buildInputData(); + Mockito.when(ernpClient.add(input)) + .thenReturn(ernpRegisterResult(Arrays.asList())); + + TaskExecutionException error = assertThrows("wrong exception", TaskExecutionException.class, + () -> task.execute(pendingReq, executionContext)); + + assertEquals("wrong pendingRequestId", pendingReq.getPendingRequestId(), error.getPendingRequestID()); + assertTrue("Wrong exception", (error.getOriginalException() instanceof WorkflowException)); + assertTrue("Wrong flag 'manualFixNeeded'", + ((WorkflowException) error.getOriginalException()).isRequiresManualFix()); + + } + + @Test + @SneakyThrows + public void moreThanOneErnpResponse() { + String bpk = RandomStringUtils.randomAlphabetic(5); + SimpleEidasData input = buildInputData(); + Mockito.when(ernpClient.add(input)) + .thenReturn(ernpRegisterResult(Arrays.asList(buildErnpResultEntry(input, bpk), buildRandomResultEntry()))); + + TaskExecutionException error = assertThrows("wrong exception", TaskExecutionException.class, + () -> task.execute(pendingReq, executionContext)); + + assertEquals("wrong pendingRequestId", pendingReq.getPendingRequestId(), error.getPendingRequestID()); + assertTrue("Wrong exception", (error.getOriginalException() instanceof WorkflowException)); + assertTrue("Wrong flag 'manualFixNeeded'", + ((WorkflowException) error.getOriginalException()).isRequiresManualFix()); + + } + + @Test + @SneakyThrows + public void insertErnpSuccess() { + String bpk = RandomStringUtils.randomAlphabetic(5); + SimpleEidasData input = buildInputData(); + Mockito.when(ernpClient.add(input)) + .thenReturn(ernpRegisterResult(Arrays.asList(buildErnpResultEntry(input, bpk)))); + + // perform test + task.execute(pendingReq, executionContext); + + // validate state + MatchedPersonResult result = MatchingTaskUtils.getFinalMatchingResult(pendingReq); + assertNotNull("no matching result", result); + assertEquals("familyname", input.getFamilyName(), result.getFamilyName()); + assertEquals("givenyname", input.getGivenName(), result.getGivenName()); + assertEquals("dateOfBirth", input.getDateOfBirth(), result.getDateOfBirth()); + assertEquals("bpk", bpk, result.getBpk()); + assertEquals("countryCode", input.getCitizenCountryCode(), result.getCountryCode()); + + } + + + @NotNull + private ErnpRegisterResult ernpRegisterResult(List registerResult) { + return new ErnpRegisterResult(registerResult); + + } + + private RegisterResult buildErnpResultEntry(SimpleEidasData input, String bpk) { + return buildErnpResultEntry(input.getFamilyName(), input.getGivenName(), input.getDateOfBirth(), bpk); + + } + + private RegisterResult buildRandomResultEntry() { + return buildErnpResultEntry(RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5), + RandomStringUtils.randomAlphabetic(5), RandomStringUtils.randomAlphabetic(5)); + + } + + private RegisterResult buildErnpResultEntry(String familyName, String givenName, String birthday, String bpk) { + return RegisterResult.builder() + .bpk(bpk) + .dateOfBirth(birthday) + .givenName(givenName) + .familyName(familyName) + .build(); + + } + + private SimpleEidasData buildInputData() throws EaafStorageException { + String cc = RandomStringUtils.randomAlphabetic(5).toUpperCase(); + String pseudonym = RandomStringUtils.randomAlphabetic(5); + String familyName = RandomStringUtils.randomAlphabetic(5); + String givenName = RandomStringUtils.randomAlphabetic(5); + String birthday = RandomStringUtils.randomNumeric(4) + "-" + + RandomStringUtils.randomNumeric(2) + "-" + RandomStringUtils.randomNumeric(2); + + SimpleEidasData input = SimpleEidasData.builder() + .familyName(familyName) + .givenName(givenName) + .dateOfBirth(birthday) + .personalIdentifier(cc + "/AT/" + pseudonym) + .pseudonym(pseudonym) + .citizenCountryCode(cc) + .build(); + MatchingTaskUtils.storeInitialEidasData(pendingReq, input); + return input; + + } +} -- cgit v1.2.3