diff options
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2')
71 files changed, 8113 insertions, 852 deletions
diff --git a/eidas_modules/authmodule-eIDAS-v2/pom.xml b/eidas_modules/authmodule-eIDAS-v2/pom.xml index 5a24b67f..5f7edef0 100644 --- a/eidas_modules/authmodule-eIDAS-v2/pom.xml +++ b/eidas_modules/authmodule-eIDAS-v2/pom.xml @@ -137,14 +137,21 @@ <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency> - <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> - <version>2.11.2</version> - <scope>compile</scope> </dependency> <dependency> + <groupId>org.openapitools</groupId> + <artifactId>jackson-databind-nullable</artifactId> + </dependency> + + <dependency> + <groupId>io.swagger.parser.v3</groupId> + <artifactId>swagger-parser</artifactId> + </dependency> + + <dependency> <groupId>org.bitbucket.b_c</groupId> <artifactId>jose4j</artifactId> </dependency> @@ -229,6 +236,9 @@ <resource> <directory>target/generated-sources/cxf</directory> </resource> + <resource> + <directory>target/generated-sources/swagger</directory> + </resource> </resources> <plugins> @@ -262,7 +272,7 @@ </dependencies> <executions> <execution> - <id>generate-sources</id> + <id>generate-sources-soap</id> <phase>generate-sources</phase> <configuration> <sourceRoot>${project.build.directory}/generated/cxf</sourceRoot> @@ -303,6 +313,39 @@ </plugin> <plugin> + <groupId>org.openapitools</groupId> + <artifactId>openapi-generator-maven-plugin</artifactId> + <executions> + <execution> + <id>generate-sources-json</id> + <phase>generate-sources</phase> + <configuration> + <skip>false</skip> + <skipOverwrite>false</skipOverwrite> + <inputSpec>${project.basedir}/src/main/resources/wsdl/ernp_client/openapi.json</inputSpec> + <generatorName>java</generatorName> + <output>${project.build.directory}/generated/swagger</output> + <apiPackage>at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.api</apiPackage> + <modelPackage>at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model</modelPackage> + <invokerPackage>at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.invoker</invokerPackage> + <configOptions> + <configPackage>at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp</configPackage> + <delegatePattern>true</delegatePattern> + <basePackage>at.asitplus.eidas.specific.modules.auth.eidas.v2</basePackage> + <java8>true</java8> + <dateLibrary>java8</dateLibrary> + <serializationLibrary>jackson</serializationLibrary> + <library>resttemplate</library> + </configOptions> + </configuration> + <goals> + <goal>generate</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> <groupId>com.github.spotbugs</groupId> <artifactId>spotbugs-maven-plugin</artifactId> <version>${spotbugs-maven-plugin.version}</version> @@ -331,6 +374,7 @@ <exclude>**/szrservices/*</exclude> <exclude>**/generated/cxf/*</exclude> <exclude>**at/gv/bmi/namespace/*</exclude> + <exclude>**at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/ernp/*</exclude> </excludes> </configuration> </execution> diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java index bfb82474..272d79c4 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java @@ -100,6 +100,31 @@ public class Constants { public static final String FORWARD_METHOD_POST = "POST"; public static final String FORWARD_METHOD_GET = "GET"; + + // Common SSL client configuration + public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT = CONIG_PROPS_EIDAS_PREFIX + ".client.common"; + public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEYSTORE_PATH = CONIG_PROPS_EIDAS_COMMON_CLIENT + + ".ssl.keyStore.path"; + public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEYSTORE_PASSWORD = CONIG_PROPS_EIDAS_COMMON_CLIENT + + ".ssl.keyStore.password"; + public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEYSTORE_TYPE = CONIG_PROPS_EIDAS_COMMON_CLIENT + + ".ssl.keyStore.type"; + public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEYSTORE_NAME = CONIG_PROPS_EIDAS_COMMON_CLIENT + + ".ssl.keyStore.name"; + public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEYS_ALIAS = CONIG_PROPS_EIDAS_COMMON_CLIENT + + ".ssl.key.alias"; + public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEY_PASSWORD = CONIG_PROPS_EIDAS_COMMON_CLIENT + + ".ssl.key.password"; + public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_TRUSTSTORE_PATH = CONIG_PROPS_EIDAS_COMMON_CLIENT + + ".ssl.trustStore.path"; + public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_TRUSTSTORE_PASSWORD = CONIG_PROPS_EIDAS_COMMON_CLIENT + + ".ssl.trustStore.password"; + public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_TRUSTSTORE_TYPE = CONIG_PROPS_EIDAS_COMMON_CLIENT + + ".ssl.trustStore.type"; + public static final String CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_TRUSTSTORE_NAME = CONIG_PROPS_EIDAS_COMMON_CLIENT + + ".ssl.trustStore.name"; + + // ZMR Client configuration properties public static final String CONIG_PROPS_EIDAS_ZMRCLIENT = CONIG_PROPS_EIDAS_PREFIX + ".zmrclient"; public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_ENDPOINT = CONIG_PROPS_EIDAS_ZMRCLIENT @@ -110,6 +135,12 @@ public class Constants { + ".timeout.connection"; public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_TIMEOUT_RESPONSE = CONIG_PROPS_EIDAS_ZMRCLIENT + ".timeout.response"; + public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_REQ_ORGANIZATION_NR = CONIG_PROPS_EIDAS_ZMRCLIENT + + ".req.organisation.behoerdennr"; + public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_REQ_UPDATE_REASON_CODE = CONIG_PROPS_EIDAS_ZMRCLIENT + + ".req.update.reason.code"; + public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_REQ_UPDATE_REASON_TEXT = CONIG_PROPS_EIDAS_ZMRCLIENT + + ".req.update.reason.text"; public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_KEYSTORE_PATH = CONIG_PROPS_EIDAS_ZMRCLIENT + ".ssl.keyStore.path"; public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_KEYSTORE_PASSWORD = CONIG_PROPS_EIDAS_ZMRCLIENT @@ -130,15 +161,19 @@ public class Constants { + ".ssl.trustStore.type"; public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_TRUSTSTORE_NAME = CONIG_PROPS_EIDAS_ZMRCLIENT + ".ssl.trustStore.name"; - - public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_REQ_ORGANIZATION_NR = CONIG_PROPS_EIDAS_ZMRCLIENT + + // ErnP Client configuration properties + public static final String CONIG_PROPS_EIDAS_ERNPCLIENT = CONIG_PROPS_EIDAS_PREFIX + ".ernpclient"; + public static final String CONIG_PROPS_EIDAS_ERNPCLIENT_ENDPOINT = CONIG_PROPS_EIDAS_ERNPCLIENT + + ".endpoint"; + public static final String CONIG_PROPS_EIDAS_ERNPCLIENT_TIMEOUT_CONNECTION = CONIG_PROPS_EIDAS_ERNPCLIENT + + ".timeout.connection"; + public static final String CONIG_PROPS_EIDAS_ERNPCLIENT_TIMEOUT_RESPONSE = CONIG_PROPS_EIDAS_ERNPCLIENT + + ".timeout.response"; + public static final String CONIG_PROPS_EIDAS_ERNPCLIENT_REQ_ORGANIZATION_NR = CONIG_PROPS_EIDAS_ERNPCLIENT + ".req.organisation.behoerdennr"; - public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_REQ_UPDATE_REASON_CODE = CONIG_PROPS_EIDAS_ZMRCLIENT - + ".req.update.reason.code"; - public static final String CONIG_PROPS_EIDAS_ZMRCLIENT_REQ_UPDATE_REASON_TEXT = CONIG_PROPS_EIDAS_ZMRCLIENT - + ".req.update.reason.text"; - - + + // SZR Client configuration properties public static final String CONIG_PROPS_EIDAS_SZRCLIENT = CONIG_PROPS_EIDAS_PREFIX + ".szrclient"; public static final String CONIG_PROPS_EIDAS_SZRCLIENT_USETESTSERVICE = CONIG_PROPS_EIDAS_SZRCLIENT @@ -233,7 +268,13 @@ public class Constants { public static final String eIDAS_ATTRURN_PREFIX_NATURAL = eIDAS_ATTRURN_PREFIX + "naturalperson/"; public static final String eIDAS_ATTRURN_PERSONALIDENTIFIER = - eIDAS_ATTRURN_PREFIX_NATURAL + eIDAS_ATTR_PERSONALIDENTIFIER; + eIDAS_ATTRURN_PREFIX_NATURAL + eIDAS_ATTR_PERSONALIDENTIFIER; + public static final String eIDAS_ATTRURN_CURRENTGIVENNAME = + eIDAS_ATTRURN_PREFIX_NATURAL + "CurrentGivenName"; + public static final String eIDAS_ATTRURN_CURRENTFAMILYNAME = + eIDAS_ATTRURN_PREFIX_NATURAL + "CurrentFamilyName"; + public static final String eIDAS_ATTRURN_DATEOFBIRTH = + eIDAS_ATTRURN_PREFIX_NATURAL + eIDAS_ATTR_DATEOFBIRTH; public static final String eIDAS_ATTRURN_PLACEOFBIRTH = eIDAS_ATTRURN_PREFIX_NATURAL + eIDAS_ATTR_PLACEOFBIRTH; public static final String eIDAS_ATTRURN_BIRTHNAME = @@ -255,8 +296,10 @@ public class Constants { public static final String SZR_SCHEMA_LOCATIONS = "urn:SZRServices" + " " + "/szr_client/szr.xsd"; - // Default values for SZR communication + // Default values for SZR / ZMR / ERnP communication public static final String SZR_CONSTANTS_DEFAULT_DOCUMENT_TYPE = "ELEKTR_DOKUMENT"; + public static final String CLIENT_INFO = "eIDAS MS-Connector v{0}"; + // AuthBlock public static final String SZR_AUTHBLOCK = "authData_AUTHBLOCK"; @@ -277,10 +320,14 @@ public class Constants { // UI options public static final String HTML_FORM_ADVANCED_MATCHING_FAILED = "advancedMatchingFailed"; - + public static final String HTML_FORM_ADVANCED_MATCHING_FAILED_REASON = + HTML_FORM_ADVANCED_MATCHING_FAILED + "Reason"; + // ProcessEngine context public static final String CONTEXT_FLAG_ADVANCED_MATCHING_FAILED = HTML_FORM_ADVANCED_MATCHING_FAILED; + public static final String CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON = + HTML_FORM_ADVANCED_MATCHING_FAILED_REASON; /** * {@link at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.CreateNewErnpEntryTask}. 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 new file mode 100644 index 00000000..4c4e3d87 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java @@ -0,0 +1,857 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp; + +import java.io.IOException; +import java.text.MessageFormat; +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.annotation.Nonnull; +import javax.annotation.PostConstruct; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.HttpClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.web.client.ResponseErrorHandler; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +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.dao.SimpleEidasData.SimpleEidasDataBuilder; +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.Aendern; +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.Anlegen; +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.PersonendatenErgebnis; +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; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.Suchoptionen; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.Suchoptionen.HistorischEnum; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.ErnpRestCommunicationException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.WorkflowException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.VersionHolder; +import at.gv.bmi.namespace.zmr_su.base._20040201_.ServiceFault; +import at.gv.bmi.namespace.zmr_su.zmr._20040201.EidasSuchdatenType; +import at.gv.bmi.namespace.zmr_su.zmr._20040201.PersonSuchenRequest; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; +import at.gv.egiz.eaaf.core.impl.http.HttpClientConfiguration; +import at.gv.egiz.eaaf.core.impl.http.HttpClientConfiguration.ClientAuthMode; +import at.gv.egiz.eaaf.core.impl.http.IHttpClientFactory; +import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +/** + * Implements an ERnP client that uses REST API for communication. + * + * @author tlenz + * + */ +@Slf4j +public class ErnpRestClient implements IErnpClient { + + private static final String ERROR_MATCHING_11 = "module.eidasauth.matching.11"; + //private static final String ERROR_MATCHING_12 = "module.eidasauth.matching.12"; + private static final String ERROR_MATCHING_99 = "module.eidasauth.matching.99"; + + private static final String LOGMSG_MISSING_CONFIG = "Missing configuration with key: {0}"; + private static final String LOGMSG_ERNP_ERROR = + "Receive an error from ERnP during '{}' operation with msg: {}"; + private static final String LOGMSG_ERNP_RESP_PROCESS = + "Proces ERnP response during '{}' operation failes with msg: {}"; + + //private static final String LOGMSG_ERNP_REST_ERROR = + // "ERnP anwser for transaction: {0} with code: {1} and message: {2}"; + + private static final String PROCESS_SEARCH_PERSONAL_IDENTIFIER = + "Searching " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER; + private static final String PROCESS_SEARCH_MDS_ONLY = "Searching with MDS only"; + private static final String PROCESS_SEARCH_COUNTRY_SPECIFIC = "Searching {0} specific"; + + 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 + private static final String ERNP_RESPONSE_HEADER_SERVER_ID = "Server-Request-Id"; + + + @Autowired + IConfiguration basicConfig; + @Autowired + EaafKeyStoreFactory keyStoreFactory; + @Autowired + IHttpClientFactory httpClientFactory; + @Autowired + VersionHolder versionHolder; + + private DefaultApi ernpClient; + + @Override + public ErnpRegisterResult searchWithPersonIdentifier(String personIdentifier, String citizenCountryCode) + throws EidasSAuthenticationException { + try { + // build generic request metadata + final GenericRequestParams generic = buildGenericRequestParameters("stepId"); + + // build search request + final SuchEidas eidasInfos = new SuchEidas(); + eidasInfos.setArt(Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER); + eidasInfos.setWert(personIdentifier); + eidasInfos.setStaatscode2(citizenCountryCode); + + final PersonSuchen personSuchen = new PersonSuchen(); + personSuchen.setSuchoptionen(generateSearchParameters()); + personSuchen.setBegruendung(PROCESS_SEARCH_PERSONAL_IDENTIFIER); + final Suchdaten searchInfos = new Suchdaten(); + searchInfos.setEidas(Arrays.asList(eidasInfos)); + personSuchen.setSuchdaten(searchInfos); + + // request ERnP + log.trace("Requesting ERnP for '{}' operation", PROCESS_SEARCH_PERSONAL_IDENTIFIER); + final SuchenResponse resp = ernpClient.suchen(generic.getClientBehkz(), generic.clientName, + generic.getClientRequestTime(), generic.getClientRequestId(), personSuchen); + + // parse ZMR response + return processErnpResponse(resp, citizenCountryCode, true, PROCESS_SEARCH_PERSONAL_IDENTIFIER); + + } catch (RestClientException e) { + log.warn(LOGMSG_ERNP_ERROR, PROCESS_SEARCH_PERSONAL_IDENTIFIER, e.getMessage()); + throw new EidasSAuthenticationException(ERROR_MATCHING_11, new Object[] { e.getMessage() }, e); + + } catch (final EidasSAuthenticationException e) { + throw e; + + } catch (final Exception e) { + log.warn(LOGMSG_ERNP_RESP_PROCESS, PROCESS_SEARCH_PERSONAL_IDENTIFIER, e.getMessage()); + throw new EidasSAuthenticationException(ERROR_MATCHING_99, new Object[] { e.getMessage() }, e); + } + + } + + @Override + public ErnpRegisterResult searchWithMds(String givenName, String familyName, String dateOfBirth, + String citizenCountryCode) throws EidasSAuthenticationException { + try { + // build generic request metadata + final GenericRequestParams generic = buildGenericRequestParameters("stepMDS"); + + // build search request + final Suchdaten searchInfos = new Suchdaten(); + searchInfos.setFamilienname(familyName); + searchInfos.setVorname(givenName); + searchInfos.setGeburtsdatum(buildErnpBirthday(dateOfBirth)); + + final PersonSuchen personSuchen = new PersonSuchen(); + personSuchen.setSuchoptionen(generateSearchParameters()); + personSuchen.setBegruendung(PROCESS_SEARCH_MDS_ONLY); + personSuchen.setSuchdaten(searchInfos); + + // request ERnP + log.trace("Requesting ERnP for '{}' operation", PROCESS_SEARCH_MDS_ONLY); + final SuchenResponse resp = ernpClient.suchen(generic.getClientBehkz(), generic.clientName, + generic.getClientRequestTime(), generic.getClientRequestId(), personSuchen); + + // parse ZMR response + return processErnpResponse(resp, citizenCountryCode, false, PROCESS_SEARCH_MDS_ONLY); + + } catch (RestClientException e) { + log.warn(LOGMSG_ERNP_ERROR, PROCESS_SEARCH_MDS_ONLY, e.getMessage()); + throw new EidasSAuthenticationException(ERROR_MATCHING_11, new Object[] { e.getMessage() }, e); + + } catch (final EidasSAuthenticationException e) { + throw e; + + } catch (final Exception e) { + log.warn(LOGMSG_ERNP_RESP_PROCESS, PROCESS_SEARCH_MDS_ONLY, e.getMessage()); + throw new EidasSAuthenticationException(ERROR_MATCHING_99, new Object[] { e.getMessage() }, e); + } + } + + @Override + public ErnpRegisterResult searchCountrySpecific(PersonSuchenRequest personSearchDao, + String citizenCountryCode) throws EidasSAuthenticationException { + String countrySearchMsg = MessageFormat.format(PROCESS_SEARCH_COUNTRY_SPECIFIC, citizenCountryCode); + + try { + // build generic request metadata + final GenericRequestParams generic = buildGenericRequestParameters("stepCC"); + + // build search request + final PersonSuchen personSuchen = new PersonSuchen(); + personSuchen.setSuchoptionen(generateSearchParameters()); + personSuchen.setBegruendung(countrySearchMsg); + personSuchen.setSuchdaten(mapCountrySpecificSearchData(personSearchDao)); + + // request ERnP + log.trace("Requesting ERnP for '{}' operation", countrySearchMsg); + final SuchenResponse resp = ernpClient.suchen(generic.getClientBehkz(), generic.clientName, + generic.getClientRequestTime(), generic.getClientRequestId(), personSuchen); + + // parse ZMR response + return processErnpResponse(resp, citizenCountryCode, true, countrySearchMsg); + + } catch (RestClientException e) { + log.warn(LOGMSG_ERNP_ERROR, countrySearchMsg, e.getMessage()); + throw new EidasSAuthenticationException(ERROR_MATCHING_11, new Object[] { e.getMessage() }, e); + + } catch (final EidasSAuthenticationException e) { + throw e; + + } catch (final Exception e) { + log.warn(LOGMSG_ERNP_RESP_PROCESS, countrySearchMsg, e.getMessage()); + throw new EidasSAuthenticationException(ERROR_MATCHING_99, new Object[] { e.getMessage() }, e); + + } + } + + @Override + public ErnpRegisterResult update(RegisterResult registerResult, SimpleEidasData eidData) + throws EidasSAuthenticationException { + try { + //search person with register result, because update needs information from search response + Person ernpPersonToKitt = searchPersonForUpdate(registerResult); + + // select elements that have to be updated + Collection<? extends Eidas> eidasDocumentToAdd = + selectEidasDocumentsToAdd(ernpPersonToKitt, eidData); + SimpleEidasData mdsToUpdate = selectMdsInformationToUpdate(ernpPersonToKitt, eidData); + + if (eidasDocumentToAdd.isEmpty() && mdsToUpdate == null) { + log.info("Find no eIDAS document or MDS for update during: {}. Nothing todo on ERnP side", + PROCESS_KITT_GENERAL); + return new ErnpRegisterResult(Arrays.asList(registerResult)); + + } else { + log.info("Find #{} eIDAS documents for update during: {}", eidasDocumentToAdd.size(), PROCESS_KITT_GENERAL); + + // update entry based on selected update info's and results from search response + return updatePersonInErnp(ernpPersonToKitt, eidasDocumentToAdd, mdsToUpdate, eidData.getCitizenCountryCode()); + + } + + } catch (RestClientException e) { + log.warn(LOGMSG_ERNP_ERROR, PROCESS_KITT_GENERAL, e.getMessage()); + throw new EidasSAuthenticationException(ERROR_MATCHING_11, new Object[] { e.getMessage() }, e); + + } catch (final EidasSAuthenticationException e) { + throw e; + + } catch (final Exception e) { + log.warn(LOGMSG_ERNP_RESP_PROCESS, PROCESS_KITT_GENERAL, e.getMessage()); + throw new EidasSAuthenticationException(ERROR_MATCHING_99, new Object[] { e.getMessage() }, e); + + } + } + + @Override + public ErnpRegisterResult add(SimpleEidasData eidData) throws EidasSAuthenticationException { + try { + // build generic request metadata + final GenericRequestParams generic = buildGenericRequestParameters("stepNew"); + + // build update request + 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); + + 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_ADD_IDENITY); + + return new ErnpRegisterResult(Arrays.asList( + mapErnpResponseToRegisterResult(ernpResp.getPerson(), eidData.getCitizenCountryCode()))); + + } catch (RestClientException e) { + log.warn(LOGMSG_ERNP_ERROR, PROCESS_ADD_IDENITY, e.getMessage()); + throw new EidasSAuthenticationException(ERROR_MATCHING_11, new Object[] { e.getMessage() }, e); + + } catch (final Exception e) { + log.warn(LOGMSG_ERNP_RESP_PROCESS, PROCESS_ADD_IDENITY, e.getMessage()); + throw new EidasSAuthenticationException(ERROR_MATCHING_99, new Object[] { e.getMessage() }, e); + + } + } + + @Override + public ErnpRegisterResult searchWithResidenceData(String givenName, String familyName, String dateOfBirth, + String zipcode, String city, String street) { + log.warn("Matching with residence information is prohibited by design! This requests will be ignored"); + return new ErnpRegisterResult(Collections.emptyList()); + + } + + @PostConstruct + private void initialize() throws EaafException { + // validate additional Ernp communication parameters + valdiateAdditionalConfigParameters(); + + // set-up the Ernp client + final ApiClient baseClient = new ApiClient(buildRestClient()); + baseClient.setBasePath(basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_ERNPCLIENT_ENDPOINT)); + ernpClient = new DefaultApi(baseClient); + + } + + private void valdiateAdditionalConfigParameters() { + checkConfigurationValue(Constants.CONIG_PROPS_EIDAS_ERNPCLIENT_ENDPOINT); + checkConfigurationValue(Constants.CONIG_PROPS_EIDAS_ERNPCLIENT_REQ_ORGANIZATION_NR); + + } + + private void checkConfigurationValue(String key) { + if (StringUtils.isEmpty(basicConfig.getBasicConfiguration(key))) { + throw new RuntimeException(MessageFormat.format(LOGMSG_MISSING_CONFIG, key)); + + } + } + + private Suchoptionen generateSearchParameters() { + final Suchoptionen options = new Suchoptionen(); + options.setZmr(false); + options.setHistorisch(HistorischEnum.AKTUELLUNDHISTORISCH); + options.setSucheMitNamensteilen(false); + options.setSuchwizard(false); + return options; + + } + + @Nonnull + private ErnpRegisterResult processErnpResponse(SuchenResponse resp, @Nonnull String citizenCountryCode, + boolean forceSinglePersonMatch, @Nonnull String processStepFiendlyname) + throws EaafAuthenticationException { + if (resp.getPerson() == null + || resp.getPerson().isEmpty()) { + log.debug("ERnP result contains NO 'Person' or 'Person' is empty"); + return new ErnpRegisterResult(Collections.emptyList()); + + } else { + log.debug("Get #{} person results from '{}' operation", + resp.getPerson().size(), processStepFiendlyname); + + if (forceSinglePersonMatch) { + return new ErnpRegisterResult(processSearchPersonResponseSingleResult( + resp.getPerson(), citizenCountryCode, processStepFiendlyname)); + + } else { + return new ErnpRegisterResult(processSearchPersonResponse( + resp.getPerson(), citizenCountryCode)); + + } + } + } + + @Nonnull + private List<RegisterResult> processSearchPersonResponse( + @Nonnull List<Person> list, + @Nonnull String citizenCountryCode) throws EaafAuthenticationException { + return list.stream() + .map(el -> mapErnpResponseToRegisterResult(el, citizenCountryCode)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + } + + @NonNull + private List<RegisterResult> processSearchPersonResponseSingleResult( + @Nonnull List<Person> persons, + @Nonnull String citizenCountryCode, String processStepFiendlyname) throws EaafAuthenticationException { + if (persons.size() > 1) { + log.error("Find more-than-one ERnP entry with search criteria that has to be unique"); + throw new WorkflowException(processStepFiendlyname, + "Find more-than-one ERnP entry with search criteria that has to be unique", true); + + } else { + return Arrays.asList(mapErnpResponseToRegisterResult(persons.get(0), citizenCountryCode)); + + } + } + + @Nonnull + private RegisterResult mapErnpResponseToRegisterResult(@Nonnull Person person, + @Nonnull String citizenCountryCode) { + // build result + return RegisterResult.builder() + .pseudonym(selectAllEidasDocument(person, citizenCountryCode, + Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER)) + .familyName(person.getPersonendaten().getFamilienname()) + .givenName(person.getPersonendaten().getVorname()) + .dateOfBirth(getTextualBirthday(person.getPersonendaten().getGeburtsdatum())) + .bpk(person.getPersonendaten().getBpkZp()) + .placeOfBirth(selectSingleEidasDocument(person, citizenCountryCode, + Constants.eIDAS_ATTRURN_PLACEOFBIRTH)) + .birthName(selectSingleEidasDocument(person, citizenCountryCode, + Constants.eIDAS_ATTRURN_BIRTHNAME)) + .build(); + + } + + private Suchdaten mapCountrySpecificSearchData(PersonSuchenRequest personSearchDao) { + final Suchdaten searchInfos = new Suchdaten(); + searchInfos.setFamilienname(personSearchDao.getNatuerlichePerson().getPersonenName().getFamilienname()); + searchInfos.setVorname(personSearchDao.getNatuerlichePerson().getPersonenName().getVorname()); + searchInfos.setGeburtsdatum(buildErnpBirthday(personSearchDao.getNatuerlichePerson().getGeburtsdatum())); + + // map all eIDAS documents into ERnP format + searchInfos.setEidas(personSearchDao.getEidasSuchdaten().stream() + .map(el -> buildErnpEidasDocument(el)) + .collect(Collectors.toList())); + + return searchInfos; + + } + + private ErnpRegisterResult updatePersonInErnp(Person ernpPersonToKitt, + Collection<? extends Eidas> eidasDocumentToAdd, SimpleEidasData mdsToUpdate, 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 + if (!eidasDocumentToAdd.isEmpty()) { + log.debug("Find eIDAS Documents to update. Injection update entries into ERnP request ... "); + ernpReq.setAnlegen(new Anlegen()); + eidasDocumentToAdd.stream().forEach(el -> ernpReq.getAnlegen().addEidasItem(el)); + + } + + // update MDS if required + if (mdsToUpdate != null) { + log.debug("Find MDS to update. Injection update entries into ERnP request ... "); + ernpReq.setAendern(generateMdsChangeRequest(ernpPersonToKitt, mdsToUpdate)); + + } + + // 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<? extends Eidas> selectEidasDocumentsToAdd( + Person ernpPersonToKitt, SimpleEidasData eidData) { + + //TODO: maybe we should re-factor SimpleEidasData to a generic data-model to facilitate arbitrary eIDAS attributes + Set<Eidas> 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<Eidas> 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<Eidas> 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.setBpkZp(registerResult.getBpk()); + 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; + } + + private SimpleEidasData selectMdsInformationToUpdate(Person ernpPersonToKitt, SimpleEidasData eidData) { + PersonendatenErgebnis person = ernpPersonToKitt.getPersonendaten(); + SimpleEidasDataBuilder builder = SimpleEidasData.builder() + .givenName(eidData.getGivenName()) + .familyName(eidData.getFamilyName()) + .dateOfBirth(eidData.getDateOfBirth()); + + boolean findMatch = person.getVorname().equals(eidData.getGivenName()) + && person.getFamilienname().equals(eidData.getFamilyName()) + && getTextualBirthday(person.getGeburtsdatum()).equals(eidData.getDateOfBirth()); + return findMatch ? null : builder.build(); + + } + + private Aendern generateMdsChangeRequest(Person ernpPersonToKitt, SimpleEidasData mdsToUpdate) { + Aendern el = new Aendern(); + Personendaten person = new Personendaten(); + person.setEntityId(ernpPersonToKitt.getPersonendaten().getEntityId()); + el.setPersonendaten(person); + person.setFamilienname(mdsToUpdate.getFamilyName()); + person.setVorname(mdsToUpdate.getGivenName()); + person.setGeburtsdatum(buildErnpBirthday(mdsToUpdate.getDateOfBirth())); + return el; + + } + + /** + * Map an AT specific Date String 'yyyy-MM-dd' to ERnP birthday representation. + * + * <p> + * <b>Info:</b> {@link LocalDate} can not be used, because '1940-00-00' is also + * a valid birthday. + * </p> + * + * @param dateOfBirth in 'yyyy-MM-dd' format + * @return ERnP birthday representation + */ + private PartialDate buildErnpBirthday(String dateOfBirth) { + String[] elements = dateOfBirth.split("-"); + Assert.isTrue(elements.length == 3, "Find invalid dateOfBirth element: " + dateOfBirth); + + PartialDate result = new PartialDate(); + result.setJahr(Integer.valueOf(elements[0])); + result.setMonat(Integer.valueOf(elements[1])); + result.setTag(Integer.valueOf(elements[2])); + return result; + + } + + /** + * Map eIDAS search-data from ZMR model into ERnP model. + * + * @param daten eIDAS document as ZMR model + * @return the same eIDAS document as an ERnP model + */ + private SuchEidas buildErnpEidasDocument(EidasSuchdatenType daten) { + return new SuchEidas() + .art(daten.getEidasArt()) + .wert(daten.getEidasWert()) + .staatscode2(daten.getStaatscode2()); + } + + + /** + * Build AT specific Date String 'yyyy-MM-dd' from ERnP birthday representation. + * + * <p> + * <b>Info:</b> {@link LocalDate} can not be used, because '1940-00-00' is also + * a valid birthday on ERnP site. + * </p> + * + * @param geburtsdatum ERnP birthday representation + * @return birthday in 'yyyy-MM-dd' format + */ + private String getTextualBirthday(PartialDate geburtsdatum) { + return MessageFormat.format("{0}-{1}-{2}", + String.valueOf(geburtsdatum.getJahr()), + String.format("%02d", geburtsdatum.getMonat()), + String.format("%02d", geburtsdatum.getTag())); + + } + + + /** + * Get all eIDAS document with the specified country code and document type. + * + * @param person Person information from ERnP + * @param citizenCountryCode Country code of the eIDAS attribute + * @param eidasAttrurnPersonalidentifier eIDAS attribute identifier + * @return {@link List} of eIDAS attribute values or an empty list if's not + * found + */ + @NonNull + private List<String> selectAllEidasDocument(Person person, String citizenCountryCode, + String eidasAttrurnPersonalidentifier) { + if (person.getEidas() != null) { + return person.getEidas().stream() + .filter(el -> eidasAttrurnPersonalidentifier.equals(el.getArt()) + && el.getStaatscode2().equals(citizenCountryCode)) + .map(el -> el.getWert()) + .collect(Collectors.toList()); + + } else { + return Collections.emptyList(); + + } + + } + + /** + * Get the first eIDAS document with the specified country code and document + * type. + * + * @param person Person information from ERnP + * @param citizenCountryCode Country code of the eIDAS attribute + * @param eidasAttrurnPersonalidentifier eIDAS attribute identifier + * @return Value of this eIDAS attribute or <code>null</code> if's not found + */ + @Nullable + private String selectSingleEidasDocument(Person person, String citizenCountryCode, + String eidasAttrurnPersonalidentifier) { + if (person.getEidas() != null) { + return person.getEidas().stream() + .filter(el -> eidasAttrurnPersonalidentifier.equals(el.getArt()) + && el.getStaatscode2().equals(citizenCountryCode)) + .findFirst() + .map(el -> el.getWert()) + .orElse(null); + + } else { + return null; + + } + } + + private RestTemplate buildRestClient() throws EaafException { + log.debug("Building REST-Client for ERnP communication ... "); + final HttpClient httpClient = httpClientFactory.getHttpClient(buildHttpClientConfiguration()); + final ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); + final RestTemplate springClient = new RestTemplate(requestFactory); + springClient.setErrorHandler(buildErrorHandler()); + springClient.getMessageConverters().add(0, buildCustomJacksonObjectMapper()); + return springClient; + + } + + private HttpMessageConverter<?> buildCustomJacksonObjectMapper() { + final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON)); + converter.getObjectMapper().setSerializationInclusion(Include.NON_NULL); + + converter.getObjectMapper().registerModule(new JavaTimeModule()); + converter.getObjectMapper().configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + return converter; + + } + + @Nonnull + private ResponseErrorHandler buildErrorHandler() { + return new ResponseErrorHandler() { + + @Override + public boolean hasError(ClientHttpResponse response) throws IOException { + return response.getStatusCode().is4xxClientError() + || response.getStatusCode().is5xxServerError(); + + } + + @Override + public void handleError(ClientHttpResponse response) throws IOException { + // TODO: opimize errorHandling based on response info's from real ERnP + + List<String> serverId = response.getHeaders().getOrEmpty(ERNP_RESPONSE_HEADER_SERVER_ID); + log.warn("Receive http-error: {} from ERnP with serverTransactionId {}", + response.getRawStatusCode(), serverId.isEmpty() ? "'not set'" : serverId.get(0)); + log.warn(" Full ERnP response-body: {}", IOUtils.toString(response.getBody(), "UTF-8")); + throw new ErnpRestCommunicationException(response.getRawStatusCode()); + + } + }; + } + + @Nonnull + private HttpClientConfiguration buildHttpClientConfiguration() throws EaafException { + final HttpClientConfiguration config = new HttpClientConfiguration(FRIENDLYNAME_HTTP_CLIENT); + config.setAuthMode(ClientAuthMode.SSL.getMode()); + + // Set keystore configuration + config.buildKeyStoreConfig( + basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEYSTORE_TYPE), + basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEYSTORE_PATH), + basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEYSTORE_PASSWORD), + basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEYSTORE_NAME)); + + // Set key information + config.setSslKeyAlias( + basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEYS_ALIAS)); + config.setSslKeyPassword( + basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_COMMON_CLIENT_SSL_KEY_PASSWORD)); + + // Set connection parameters + // TODO: update EAAF-components to allow custom HTTP Connection-Timeouts + + return config; + } + + @AllArgsConstructor + @Getter + public static class ErnpRegisterResult { + private final List<RegisterResult> personResult; + + } + + private GenericRequestParams buildGenericRequestParameters(String operationIdentifier) { + return GenericRequestParams.builder() + .clientBehkz(basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_REQ_ORGANIZATION_NR)) + .clientName(MessageFormat.format(Constants.CLIENT_INFO, versionHolder.getVersion())) + .clientRequestTime(OffsetDateTime.now()) + .clientRequestId(TransactionIdUtils.getTransactionId() + "_" + operationIdentifier) + .build(); + + } + + @Builder + @Getter + private static class GenericRequestParams { + String clientBehkz; + String clientName; + OffsetDateTime clientRequestTime; + String clientRequestId; + + } + +} 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 new file mode 100644 index 00000000..7a957531 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java @@ -0,0 +1,114 @@ +/* + * Copyright 2020 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.clients.ernp; + +import javax.annotation.Nonnull; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.ErnpRestClient.ErnpRegisterResult; +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 at.gv.bmi.namespace.zmr_su.zmr._20040201.PersonSuchenRequest; + +public interface IErnpClient { + + /** + * Search person based on eIDAS personal identifier. + * + * @param personIdentifier Full eIDAS personal identifier with prefix + * @param citizenCountryCode CountryCode of the eIDAS proxy-service + * @return Search result but never <code>null</code> + * @throws EidasSAuthenticationException In case of a communication error + */ + @Nonnull + ErnpRegisterResult searchWithPersonIdentifier(@Nonnull String personIdentifier, + @Nonnull String citizenCountryCode) throws EidasSAuthenticationException; + + /** + * Search person based on eIDSA MDS information. + * + * @param givenName eIDAS given name + * @param familyName eIDAS principle name + * @param dateOfBirth eIDAS date-of-birth + * @param citizenCountryCode CountryCode of the eIDAS proxy-service + * @return Search result but never <code>null</code> + * @throws EidasSAuthenticationException In case of a communication error + */ + @Nonnull + ErnpRegisterResult searchWithMds(@Nonnull String givenName, @Nonnull String familyName, + @Nonnull String dateOfBirth, @Nonnull String citizenCountryCode) + throws EidasSAuthenticationException; + + /** + * Search person based on country-specific natural person set. + * + * @param personSearchDao Specific set of natural person informations. + * @param citizenCountryCode CountryCode of the eIDAS proxy-service + * @return Search result but never <code>null</code> + * @throws EidasSAuthenticationException In case of a communication error + */ + @Nonnull + ErnpRegisterResult searchCountrySpecific(@Nonnull PersonSuchenRequest personSearchDao, + @Nonnull String citizenCountryCode) throws EidasSAuthenticationException; + + /** + * Update ERnP entry to KITT existing ERnP identity with this eIDAS authentication. + * + * @param registerResult Already matched eIDAS identity that should be KITT + * @param eidData eIDAS eID information from current authentication process + * @return Update result but never <code>null</code> + * @throws EidasSAuthenticationException In case of a communication error + */ + @Nonnull + 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 <code>null</code> + * @throws EidasSAuthenticationException In case of a communication error + */ + @Nonnull + ErnpRegisterResult add(SimpleEidasData eidData) throws EidasSAuthenticationException; + + + /** + * Search person based on address information. + * + * @param givenName eIDAS given name + * @param familyName eIDAS principle name + * @param dateOfBirth eIDAS date-of-birth + * @param zipcode ZipCode + * @param city City + * @param street Street + * @return Search result but never <code>null</code> + */ + @Nonnull + ErnpRegisterResult searchWithResidenceData(String givenName, String familyName, + String dateOfBirth, String zipcode, String city, String street); + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/szr/SzrClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/szr/SzrClient.java index 397cbe46..bd1eb13e 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/szr/SzrClient.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/szr/SzrClient.java @@ -111,28 +111,6 @@ public class SzrClient extends AbstractSoapClient { final ObjectMapper mapper = new ObjectMapper(); - /** - * Get IdentityLink of a person. - * - * - * @param eidData minimum dataset of person - * @return IdentityLink - * @throws SzrCommunicationException In case of a SZR error - */ - public IdentityLinkType getIdentityLinkInRawMode(SimpleEidasData eidData) - throws SzrCommunicationException { - try { - final GetIdentityLinkEidas getIdl = new GetIdentityLinkEidas(); - getIdl.setPersonInfo(generateSzrRequest(eidData)); - - return getIdentityLinkGeneric(getIdl); - - } catch (final Exception e) { - log.warn("SZR communication FAILED. Reason: " + e.getMessage(), e); - throw new SzrCommunicationException("ernb.02", new Object[]{e.getMessage()}, e); - - } - } /** * Get IdentityLink of a person. @@ -206,33 +184,6 @@ public class SzrClient extends AbstractSoapClient { } return resp; } - - /** - * Request a encrypted baseId from SZR. - * - * <b>Note</b>: Previously, this method did create a new ERnP entry, if it did not exist. This is - * <b>not</b> the case any more. See {@link #createNewErnpEntry(SimpleEidasData)} for that functionality. - * - * @param eidData Minimum dataset of person - * @return encrypted baseId - * @throws SzrCommunicationException In case of a SZR error - */ - public String getEncryptedStammzahl(final SimpleEidasData eidData) - throws SzrCommunicationException { - final String resp; - try { - resp = this.szr.getStammzahlEncrypted(generateSzrRequest(eidData), false); - } catch (SZRException_Exception e) { - throw new SzrCommunicationException("ernb.02", new Object[]{e.getMessage()}, e); - } - - if (StringUtils.isEmpty(resp)) { - throw new SzrCommunicationException("ernb.01", new Object[]{"Stammzahl response empty"}); // TODO error handling - } - - return resp; - - } /** * Request a encrypted baseId from SZR. diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/IZmrClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/IZmrClient.java index c4e8ece0..f3c32c96 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/IZmrClient.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/IZmrClient.java @@ -29,6 +29,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient.ZmrRegisterResult; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController.AdresssucheOutput; 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; @@ -80,6 +81,23 @@ public interface IZmrClient { throws EidasSAuthenticationException; /** + * Search person based on MDS information and Austrian residence. + * + * @param zmrProzessId zmrProzessId zmrProzessId ProcessId from ZMR or <code>null</code> if no processId exists + * @param givenName eIDAS given name + * @param familyName eIDAS principle name + * @param dateOfBirth eIDAS date-of-birth + * @param citizenCountryCode citizenCountryCode CountryCode of the eIDAS proxy-service + * @param address Address information for searching + * @return Search result but never <code>null</code> + * @throws EidasSAuthenticationException In case of a communication error + */ + @Nonnull + ZmrRegisterResult searchWithResidenceData(@Nullable BigInteger zmrProzessId, @Nonnull String givenName, + @Nonnull String familyName, @Nonnull String dateOfBirth, @Nonnull String citizenCountryCode, + @Nonnull AdresssucheOutput address) throws EidasSAuthenticationException; + + /** * Update ZMR entry to KITT existing ZMR identity with this eIDAS authentication. * * @param zmrProzessId zmrProzessId ProcessId from ZMR or <code>null</code> if no processId exists @@ -92,7 +110,4 @@ public interface IZmrClient { ZmrRegisterResult update(@Nullable BigInteger zmrProzessId, RegisterResult registerResult, SimpleEidasData eidData) throws EidasSAuthenticationException; - ZmrRegisterResult searchWithResidenceData(@Nullable BigInteger zmrProzessId, String givenName, String familyName, - String dateOfBirth, String zipcode, String city, String street); - } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java index 711226e2..8dbd0632 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java @@ -24,6 +24,7 @@ import org.springframework.lang.Nullable; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.AbstractSoapClient; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController.AdresssucheOutput; 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; @@ -56,6 +57,8 @@ import at.gv.bmi.namespace.zmr_su.zmr._20040201.SuchkriterienType; import at.gv.e_government.reference.namespace.persondata.de._20040201.IdentificationType; import at.gv.e_government.reference.namespace.persondata.de._20040201.NatuerlichePersonTyp; import at.gv.e_government.reference.namespace.persondata.de._20040201.PersonenNameTyp; +import at.gv.e_government.reference.namespace.persondata.de._20040201.PostAdresseTyp; +import at.gv.e_government.reference.namespace.persondata.de._20040201.ZustelladresseTyp; import at.gv.egiz.eaaf.core.api.data.EaafConstants; import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException; import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; @@ -95,12 +98,12 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient { "Searching " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER; private static final String PROCESS_SEARCH_MDS_ONLY = "Searching with MDS only"; private static final String PROCESS_SEARCH_COUNTRY_SPECIFIC = "Searching {0} specific"; + private static final String PROCESS_SEARCH_BY_RESIDENCE = "Searching by residence"; 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 CLIENT_INFO = "eIDAS MS-Connector v{0}"; private static final String CLIENT_DEFAULT = "ZMR Client"; @@ -174,15 +177,7 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient { // set eIDAS person information final PersonSuchenRequest searchPersonReq = new PersonSuchenRequest(); req.setPersonSuchenRequest(searchPersonReq); - - final NatuerlichePersonTyp searchNatPerson = new NatuerlichePersonTyp(); - searchPersonReq.setNatuerlichePerson(searchNatPerson); - final PersonenNameTyp searchNatPersonName = new PersonenNameTyp(); - searchNatPerson.setPersonenName(searchNatPersonName); - - searchNatPersonName.setFamilienname(familyName); - searchNatPersonName.setVorname(givenName); - searchNatPerson.setGeburtsdatum(dateOfBirth); + searchPersonReq.setNatuerlichePerson(buildSearchNatPerson(givenName, familyName, dateOfBirth)); // set work-flow client information req.setWorkflowInfoClient(generateWorkFlowInfos(PROCESS_TASK_SEARCH, zmrProzessId)); @@ -269,8 +264,12 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient { Collection<? extends EidasIdentitaetAnlageType> eidasDocumentToAdd = selectEidasDocumentsToAdd(zmrPersonToKitt, eidData); + /*TODO: Is there a requirement to change 'eIDAS-Documents'? + * We add MDS information as 'eIDAS-Documents' too. Maybe, we should update that in a later version. + */ + if (eidasDocumentToAdd.isEmpty()) { - log.info("Find no eIDAS document for update during: {}. Looks strange but nothing todo", + log.info("Find no eIDAS document for update during: {}. Nothing todo on ZMR side", PROCESS_KITT_GENERAL); return new ZmrRegisterResult(Arrays.asList(registerResult), zmrProzessId); @@ -297,12 +296,49 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient { } } - + @Override public ZmrRegisterResult searchWithResidenceData(BigInteger zmrProzessId, String givenName, String familyName, - String dateOfBirth, String zipcode, String city, String street) { - // TODO Auto-generated method stub - return null; + String dateOfBirth, String citizenCountryCode, AdresssucheOutput address) + throws EidasSAuthenticationException { + try { + // build search request + final RequestType req = new RequestType(); + + // set person information + final PersonSuchenRequest searchPersonReq = new PersonSuchenRequest(); + req.setPersonSuchenRequest(searchPersonReq); + searchPersonReq.setNatuerlichePerson(buildSearchNatPerson(givenName, familyName, dateOfBirth)); + searchPersonReq.setPostAdresse(buildSearchAddress(address)); + + // set work-flow client information + req.setWorkflowInfoClient(generateWorkFlowInfos(PROCESS_TASK_SEARCH, zmrProzessId)); + req.setClientInfo(generateClientInfos()); + + // set additionl search parameters + searchPersonReq.setPersonensucheInfo(generateSearchCriteria( + PROCESS_SEARCH_BY_RESIDENCE, false, true, false)); + + // request ZMR + log.trace("Requesting ZMR for '{}' operation", PROCESS_SEARCH_BY_RESIDENCE); + final ResponseType resp = zmrClient.service(req, null); + + // parse ZMR response + return processZmrResponse(resp, citizenCountryCode, false, PROCESS_SEARCH_BY_RESIDENCE); + + } catch (final ServiceFault e) { + final String errorMsg = extractReasonFromError(e); + log.warn(LOGMSG_ZMR_ERROR, PROCESS_SEARCH_BY_RESIDENCE, errorMsg); + throw new ZmrCommunicationException(ERROR_MATCHING_01, new Object[] { errorMsg }, e); + + } catch (EidasSAuthenticationException e) { + throw e; + + } catch (final Exception e) { + log.warn(LOGMSG_ZMR_RESP_PROCESS, PROCESS_SEARCH_BY_RESIDENCE, e.getMessage()); + throw new EidasSAuthenticationException(ERROR_MATCHING_99, new Object[] { e.getMessage() }, e); + + } } @PostConstruct @@ -429,7 +465,7 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient { clientInfo.setOrganisation(clientOrganisation); // set client information - clientInfo.setClient(MessageFormat.format(CLIENT_INFO, versionHolder.getVersion())); + clientInfo.setClient(MessageFormat.format(Constants.CLIENT_INFO, versionHolder.getVersion())); // set Behoerdennummer as organization identifier clientOrganisation.setBehoerdenNr(basicConfig.getBasicConfiguration( @@ -465,7 +501,6 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient { return new ZmrRegisterResult(Collections.emptyList(), extractZmrProcessId(resp.getWorkflowInfoServer())); } else { - // TODO: what we to with ERnP results? log.debug("Get #{} person results from '{}' operation", searchPersonResp.getPersonensuchergebnis().getGefundeneSaetze(), processStepFiendlyname); @@ -687,6 +722,43 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient { } } + private NatuerlichePersonTyp buildSearchNatPerson(String givenName, String familyName, String dateOfBirth) { + final NatuerlichePersonTyp searchNatPerson = new NatuerlichePersonTyp(); + final PersonenNameTyp searchNatPersonName = new PersonenNameTyp(); + searchNatPerson.setPersonenName(searchNatPersonName); + searchNatPersonName.setFamilienname(familyName); + searchNatPersonName.setVorname(givenName); + searchNatPerson.setGeburtsdatum(dateOfBirth); + return searchNatPerson; + + } + + private PostAdresseTyp buildSearchAddress(AdresssucheOutput address) { + PostAdresseTyp postAdresse = new PostAdresseTyp(); + if (StringUtils.isNotBlank(address.getPostleitzahl())) { + postAdresse.setPostleitzahl(address.getPostleitzahl()); + } + if (StringUtils.isNotBlank(address.getMunicipality())) { + postAdresse.setGemeinde(address.getMunicipality()); + } + if (StringUtils.isNotBlank(address.getVillage())) { + postAdresse.setOrtschaft(address.getVillage()); + } + if (StringUtils.isNotBlank(address.getStreet()) || StringUtils.isNotBlank(address.getNumber())) { + ZustelladresseTyp zustelladresse = new ZustelladresseTyp(); + if (StringUtils.isNotBlank(address.getStreet())) { + zustelladresse.setStrassenname(address.getStreet()); + } + if (StringUtils.isNotBlank(address.getNumber())) { + zustelladresse.setOrientierungsnummer(address.getNumber()); + } + postAdresse.setZustelladresse(zustelladresse); + } + + return postAdresse; + + } + private Collection<? extends EidasIdentitaetAnlageType> selectEidasDocumentsToAdd( PersonErgebnisType zmrPersonToKitt, SimpleEidasData eidData) { @@ -698,6 +770,14 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient { Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth(), false); addEidasDocumentIfNotAvailable(result, zmrPersonToKitt, eidData.getCitizenCountryCode(), Constants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName(), false); + + // add MDS attributes as 'eIDAS-Documents' too, because ZMR does not allow a MDS update on regular places. + addEidasDocumentIfNotAvailable(result, zmrPersonToKitt, eidData.getCitizenCountryCode(), + Constants.eIDAS_ATTRURN_CURRENTGIVENNAME, eidData.getGivenName(), false); + addEidasDocumentIfNotAvailable(result, zmrPersonToKitt, eidData.getCitizenCountryCode(), + Constants.eIDAS_ATTRURN_CURRENTFAMILYNAME, eidData.getFamilyName(), false); + addEidasDocumentIfNotAvailable(result, zmrPersonToKitt, eidData.getCitizenCountryCode(), + Constants.eIDAS_ATTRURN_DATEOFBIRTH, eidData.getDateOfBirth(), false); return result; diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/controller/AdresssucheController.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/controller/AdresssucheController.java new file mode 100644 index 00000000..6dcd4879 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/controller/AdresssucheController.java @@ -0,0 +1,269 @@ +/* + * 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.controller; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.CompareToBuilder; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ResourceLoader; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; +import at.asitplus.eidas.specific.connector.gui.StaticGuiBuilderConfiguration; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrAddressSoapClient; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException; +import at.gv.bmi.namespace.zmr_su.zrm._20040201_.address.Adressdaten; +import at.gv.e_government.reference.namespace.persondata.de._20040201.PostAdresseTyp; +import at.gv.e_government.reference.namespace.persondata.de._20040201.ZustelladresseTyp; +import at.gv.egiz.eaaf.core.api.data.EaafConstants; +import at.gv.egiz.eaaf.core.api.gui.ISpringMvcGuiFormBuilder; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.exceptions.GuiBuildException; +import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +/** + * Default process-engine signaling controller. + * + * @author tlenz + */ +@Controller +@Slf4j +public class AdresssucheController { + + public static final String PARAM_POSTLEITZAHL = "postleitzahl"; + public static final String PARAM_MUNIPICALITY = "municipality"; + public static final String PARAM_VILLAGE = "village"; + public static final String PARAM_STREET = "street"; + public static final String PARAM_NUMBER = "number"; + + @Autowired + private ISpringMvcGuiFormBuilder guiBuilder; + + @Autowired + private IConfiguration basicConfig; + + @Autowired + private ResourceLoader resourceLoader; + + @Autowired + private ZmrAddressSoapClient client; + + @Autowired + private IPendingRequestIdGenerationStrategy pendingReqGeneration; + + /** + * Show the "residency.html" directly. + * TODO Remove this after testing. + */ + @RequestMapping(value = {"/test"}, method = {RequestMethod.GET}) + public void test(HttpServletRequest request, HttpServletResponse response) throws GuiBuildException, EaafException { + final StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration( + basicConfig, + "http://localhost:8080/ms_connector/", + basicConfig.getBasicConfiguration(//TODO + MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_RESIDENCY, + MsEidasNodeConstants.TEMPLATE_HTML_RESIDENCY), + MsEidasNodeConstants.ENDPOINT_RESIDENCY_INPUT, + resourceLoader); + config.putCustomParameter(null, "pendingid", pendingReqGeneration.generateExternalPendingRequestId()); + guiBuilder.build(request, response, config, "Query Austrian residency"); + } + + /** + * Show the "other_login_method.html" directly. + * TODO Remove this after testing. + */ + @RequestMapping(value = {"/olm"}, method = {RequestMethod.GET}) + public void otherloginmethod(HttpServletRequest request, HttpServletResponse response) throws GuiBuildException, + EaafException { + final StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration( + basicConfig, + "http://localhost:8080/ms_connector/", + basicConfig.getBasicConfiguration(//TODO + MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_OTHER_LOGIN_METHOD_SELECTION, + MsEidasNodeConstants.TEMPLATE_HTML_OTHERLOGINMETHODS), + MsEidasNodeConstants.ENDPOINT_OTHER_LOGIN_METHOD_SELECTION, + resourceLoader); + config.putCustomParameter(null, "pendingid", pendingReqGeneration.generateExternalPendingRequestId()); + guiBuilder.build(request, response, config, "Other Login Method"); + } + + /** + * Show the "country_selection.html" directly. + * TODO Remove this after testing. + */ + @RequestMapping(value = {"/country"}, method = {RequestMethod.GET}) + public void countryselection(HttpServletRequest request, HttpServletResponse response) throws GuiBuildException, + EaafException { + final StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration( + basicConfig, + "http://localhost:8080/ms_connector/", + basicConfig.getBasicConfiguration(//TODO + MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_CCSELECTION, + MsEidasNodeConstants.TEMPLATE_HTML_COUNTRYSELECTION), + MsEidasNodeConstants.ENDPOINT_COUNTRYSELECTION, + resourceLoader); + config.putCustomParameter(null, "pendingid", pendingReqGeneration.generateExternalPendingRequestId()); + guiBuilder.build(request, response, config, "Country Selection"); + } + + /** + * Performs search for addresses in ZMR. + */ + @RequestMapping(value = {"/residency/search"}, method = {RequestMethod.POST}) + public ResponseEntity<AdresssucheResult> search( + @RequestParam(PARAM_POSTLEITZAHL) String postleitzahl, + @RequestParam(PARAM_MUNIPICALITY) String municipality, + @RequestParam(PARAM_VILLAGE) String village, + @RequestParam(PARAM_STREET) String street, + @RequestParam(PARAM_NUMBER) String number, + @RequestParam(EaafConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID) String pendingId) { + log.info("Search with '{}', '{}', '{}', '{}', '{}'", + postleitzahl.replaceAll("[\r\n]", ""), + municipality.replaceAll("[\r\n]", ""), + village.replaceAll("[\r\n]", ""), + street.replaceAll("[\r\n]", ""), + number.replaceAll("[\r\n]", "")); + try { + pendingReqGeneration.validateAndGetPendingRequestId(pendingId); + + } catch (PendingReqIdValidationException e) { + log.warn("Search with pendingId '{}' is not valid", pendingId.replaceAll("[\r\n]", "")); + return ResponseEntity.badRequest().build(); + + } + + try { + Adressdaten searchInput = buildSearchInput(postleitzahl, municipality, village, street, number); + ZmrAddressSoapClient.AddressInfo searchOutput = client.searchAddress(searchInput); + AdresssucheResult output = buildResponse(searchOutput); + return ResponseEntity.ok(output); + + } catch (EidasSAuthenticationException e) { + log.warn("Search failed", e); + return ResponseEntity.badRequest().build(); + + } + } + + private AdresssucheResult buildResponse(ZmrAddressSoapClient.AddressInfo searchOutput) { + if (searchOutput.getPersonResult().isEmpty()) { + log.warn("No result from ZMR"); + return new AdresssucheResult(Collections.emptyList(), 0); + + } + + log.info("Result level is {}", searchOutput.getLevel()); + Set<AdresssucheOutput> result = searchOutput.getPersonResult().stream() + .map(Adressdaten::getPostAdresse) + .map(it -> new AdresssucheOutput(it.getPostleitzahl(), it.getGemeinde(), it.getOrtschaft(), + it.getZustelladresse().getStrassenname(), it.getZustelladresse().getOrientierungsnummer())) + .collect(Collectors.toSet()); + // TODO Add configuration option for the limit of 30 + List<AdresssucheOutput> sorted = result.stream().sorted().limit(30).collect(Collectors.toList()); + return new AdresssucheResult(sorted, result.size()); + + } + + private Adressdaten buildSearchInput(String postleitzahl, + String municipality, + String village, + String street, + String number) { + PostAdresseTyp postAdresse = new PostAdresseTyp(); + if (StringUtils.isNotBlank(postleitzahl)) { + postAdresse.setPostleitzahl(postleitzahl); + } + if (StringUtils.isNotBlank(municipality)) { + postAdresse.setGemeinde(municipality); + } + if (StringUtils.isNotBlank(village)) { + postAdresse.setOrtschaft(village); + } + if (StringUtils.isNotBlank(street) || StringUtils.isNotBlank(number)) { + ZustelladresseTyp zustelladresse = new ZustelladresseTyp(); + if (StringUtils.isNotBlank(street)) { + zustelladresse.setStrassenname(street); + } + if (StringUtils.isNotBlank(number)) { + zustelladresse.setOrientierungsnummer(number); + } + postAdresse.setZustelladresse(zustelladresse); + } + Adressdaten searchInput = new Adressdaten(); + searchInput.setPostAdresse(postAdresse); + return searchInput; + + } + + @Data + @AllArgsConstructor + public static class AdresssucheResult { + private final Collection<AdresssucheOutput> results; + private final int resultCount; + } + + @Data + @AllArgsConstructor + @Builder + public static class AdresssucheOutput implements Comparable<AdresssucheOutput> { + private final String postleitzahl; + private final String municipality; + private final String village; + private final String street; + private final String number; + + @Override + public int compareTo(@NotNull AdresssucheOutput o) { + return new CompareToBuilder() + .append(this.postleitzahl, o.postleitzahl) + .append(this.municipality, o.municipality) + .append(this.village, o.village) + .append(this.street, o.street) + .append(this.number, o.number) + .toComparison(); + } + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/MatchedPersonResult.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/MatchedPersonResult.java index 1e8fcecf..1dcea7fc 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/MatchedPersonResult.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/MatchedPersonResult.java @@ -1,5 +1,7 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao; +import java.io.Serializable; + import lombok.Builder; import lombok.Getter; @@ -11,7 +13,9 @@ import lombok.Getter; */ @Getter @Builder -public class MatchedPersonResult { +public class MatchedPersonResult implements Serializable { + + private static final long serialVersionUID = 9110998952621456281L; /** * Matched person result from matching result. 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 index aa82d806..e5878ff3 100644 --- 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 @@ -23,6 +23,7 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao; +import java.io.Serializable; import java.util.List; import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType; @@ -31,8 +32,10 @@ import lombok.Getter; @Builder @Getter -public class RegisterResult { +public class RegisterResult implements Serializable { + private static final long serialVersionUID = 762728480185716130L; + // MDS private final List<String> pseudonym; private final String givenName; 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 index 5ad92507..aca5025f 100644 --- 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 @@ -23,14 +23,19 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao; +import java.io.Serializable; + +import org.apache.commons.lang3.builder.EqualsBuilder; + import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType; import lombok.Builder; import lombok.Data; -import org.apache.commons.lang3.builder.EqualsBuilder; @Data -@Builder -public class SimpleEidasData { +@Builder(toBuilder = true) +public class SimpleEidasData implements Serializable { + + private static final long serialVersionUID = 2848914124372968418L; /** * Full eIDAS personal identifier with prefix. @@ -68,8 +73,11 @@ public class SimpleEidasData { .append(result.getGivenName(), givenName) .append(result.getFamilyName(), familyName) .append(result.getDateOfBirth(), dateOfBirth) - .isEquals() - && result.getPseudonym().stream().anyMatch(el -> el.equals(pseudonym)); + .appendSuper(result.getPseudonym().stream().anyMatch(el -> el.equals(pseudonym))) + .appendSuper(checkOptionalAttributes(result.getPlaceOfBirth(), placeOfBirth)) + .appendSuper(checkOptionalAttributes(result.getBirthName(), birthName)) + .isEquals(); + } /** @@ -84,5 +92,17 @@ public class SimpleEidasData { .isEquals(); } + /** + * Check if eIDAS attribute is available. + * + * @param registerData Attribute value from register + * @param eidasData Attribute value from eIDAS + * @return <code>true</code> if eidasData is <code>null</code> or eidasData does not match to register value, + * otherwise <code>false</code> + */ + private static boolean checkOptionalAttributes(String registerData, String eidasData) { + return eidasData == null || eidasData.equals(registerData); + + } } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleMobileSignatureData.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleMobileSignatureData.java index 92e727ea..54cb3f31 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleMobileSignatureData.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleMobileSignatureData.java @@ -23,6 +23,8 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao; +import java.io.Serializable; + import org.apache.commons.lang3.builder.EqualsBuilder; import lombok.Builder; @@ -30,7 +32,9 @@ import lombok.Data; @Data @Builder -public class SimpleMobileSignatureData { +public class SimpleMobileSignatureData implements Serializable { + + private static final long serialVersionUID = 7775305733438275312L; private final String bpk; private final String givenName; 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 77f5e3cd..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 @@ -24,51 +24,58 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.ernp; import java.util.Collections; -import java.util.List; import org.springframework.stereotype.Service; +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 at.gv.bmi.namespace.zmr_su.zmr._20040201.PersonSuchenRequest; @Service("ErnbClientForeIDAS") public class DummyErnpClient implements IErnpClient { + @Override - public List<RegisterResult> searchWithPersonIdentifier(String personIdentifier) { - return Collections.emptyList(); + public ErnpRegisterResult searchWithPersonIdentifier(String personIdentifier, String citizenCountryCode) + throws EidasSAuthenticationException { + return buildEmptyResult(); } @Override - public List<RegisterResult> searchWithMds(String givenName, String familyName, String dateOfBirth) { - //TODO will I only receive matches where all three values match perfectly? - return Collections.emptyList(); + public ErnpRegisterResult searchWithMds(String givenName, String familyName, String dateOfBirth, + String citizenCountryCode) throws EidasSAuthenticationException { + return buildEmptyResult(); } @Override - public List<RegisterResult> searchDeSpecific(String givenName, String familyName, String dateOfBirth, - String birthPlace, String birthName) { - //TODO - return Collections.emptyList(); + public ErnpRegisterResult searchCountrySpecific(PersonSuchenRequest personSearchDao, + String citizenCountryCode) throws EidasSAuthenticationException { + return buildEmptyResult(); } @Override - public List<RegisterResult> searchItSpecific(String taxNumber) { - //TODO - return Collections.emptyList(); + public ErnpRegisterResult update(RegisterResult registerResult, SimpleEidasData eidData) + throws EidasSAuthenticationException { + return buildEmptyResult(); } @Override - public RegisterResult update(RegisterResult registerResult, SimpleEidasData eidData) { - //TODO - return null; + public ErnpRegisterResult searchWithResidenceData(String givenName, String familyName, String dateOfBirth, + String zipcode, String city, String street) { + return buildEmptyResult(); } - @Override - public List<RegisterResult> searchWithBpkZp(String bpkzp) { - //TODO - return Collections.emptyList(); + private static ErnpRegisterResult buildEmptyResult() { + return new ErnpRegisterResult(Collections.emptyList()); + } + @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/ernp/IErnpClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/IErnpClient.java deleted file mode 100644 index b2a9005b..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/IErnpClient.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2020 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.ernp; - -import java.util.List; - -import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; - -public interface IErnpClient { - - List<RegisterResult> searchWithPersonIdentifier(String personIdentifier); - - List<RegisterResult> searchWithMds(String givenName, String familyName, String dateOfBirth); - - List<RegisterResult> searchDeSpecific(String givenName, String familyName, String dateOfBirth, - String birthPlace, String birthName); - - List<RegisterResult> searchItSpecific(String taxNumber); - - RegisterResult update(RegisterResult registerResult, SimpleEidasData eidData); - - List<RegisterResult> searchWithBpkZp(String bpkzp); - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ErnpRestCommunicationException.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ErnpRestCommunicationException.java new file mode 100644 index 00000000..566a8fa4 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ErnpRestCommunicationException.java @@ -0,0 +1,29 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.exception; + +import java.io.IOException; + +import lombok.Getter; + +/** + * ERnP exception in case of a REST communication error. + * + * @author tlenz + * + */ +public class ErnpRestCommunicationException extends IOException { + private static final long serialVersionUID = -3178689122077228976L; + + @Getter + int httpStatusCode; + + /** + * ERnP communication error on HTTP REST level. + * + * @param rawStatusCode HTTP statuscode + */ + public ErnpRestCommunicationException(int rawStatusCode) { + super("ERnP service answers with an error and HTTP status-code: " + rawStatusCode); + this.httpStatusCode = rawStatusCode; + + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/RegisterSearchService.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/RegisterSearchService.java index 047d75ae..c3bf4309 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/RegisterSearchService.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/RegisterSearchService.java @@ -7,19 +7,23 @@ import java.util.List; import javax.annotation.Nonnull; import org.jetbrains.annotations.Nullable; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; import com.google.common.collect.Streams; +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.clients.zmr.IZmrClient; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient.ZmrRegisterResult; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController.AdresssucheOutput; 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.ernp.IErnpClient; import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.WorkflowException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.ZmrCommunicationException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.CountrySpecificDetailSearchProcessor; +import at.gv.bmi.namespace.zmr_su.zmr._20040201.PersonSuchenRequest; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -77,8 +81,8 @@ public class RegisterSearchService { final ZmrRegisterResult resultsZmr = zmrClient.searchWithPersonIdentifier( operationStatus != null ? operationStatus.getZmrProcessId() : null, eidasData.getPseudonym(), eidasData.getCitizenCountryCode()); - final List<RegisterResult> resultsErnp = ernpClient.searchWithPersonIdentifier( - eidasData.getPersonalIdentifier()); + final ErnpRegisterResult resultsErnp = ernpClient.searchWithPersonIdentifier( + eidasData.getPseudonym(), eidasData.getCitizenCountryCode()); return RegisterStatusResults.fromZmrAndErnp(resultsZmr, resultsErnp); @@ -104,9 +108,9 @@ public class RegisterSearchService { zmrClient.searchWithMds(operationStatus.getZmrProcessId(), eidasData.getGivenName(), eidasData.getFamilyName(), eidasData.getDateOfBirth(), eidasData.getCitizenCountryCode()); - final List<RegisterResult> resultsErnp = - ernpClient.searchWithMds(eidasData.getGivenName(), eidasData.getFamilyName(), eidasData - .getDateOfBirth()); + final ErnpRegisterResult resultsErnp = + ernpClient.searchWithMds(eidasData.getGivenName(), + eidasData.getFamilyName(), eidasData.getDateOfBirth(), eidasData.getCitizenCountryCode()); return RegisterStatusResults.fromZmrAndErnp(resultsZmr, resultsErnp); @@ -132,16 +136,22 @@ public class RegisterSearchService { try { @Nullable final CountrySpecificDetailSearchProcessor ccSpecificProcessor = findSpecificProcessor(eidasData); if (ccSpecificProcessor != null) { - log.debug("Selecting country-specific search processor: {}", ccSpecificProcessor.getName()); + log.debug("Selecting country-specific search processor: {}", ccSpecificProcessor.getName()); + PersonSuchenRequest ccSpecificSearchReq = ccSpecificProcessor.generateSearchRequest(eidasData); + + // search in ZMR final ZmrRegisterResult resultsZmr = zmrClient.searchCountrySpecific(operationStatus.getZmrProcessId(), - ccSpecificProcessor.generateSearchRequest(eidasData), - eidasData.getCitizenCountryCode()); - return RegisterStatusResults.fromZmr(resultsZmr); + ccSpecificSearchReq, eidasData.getCitizenCountryCode()); + + //search in ERnP + ErnpRegisterResult resultErnp = ernpClient.searchCountrySpecific( + ccSpecificSearchReq, eidasData.getCitizenCountryCode()); + + return RegisterStatusResults.fromZmrAndErnp(resultsZmr, resultErnp); } else { - // TODO: add search procesfor for ERnP searching - return RegisterStatusResults.fromErnp(operationStatus, Collections.emptyList()); + return RegisterStatusResults.fromEmpty(operationStatus); } @@ -156,18 +166,29 @@ public class RegisterSearchService { * Search with residence infos. * * @param operationStatus Current register-operation status that contains processing informations - * @param zipcode Provided Zipcode - * @param city Provided City - * @param street Provided street + * @param eidasData Receive eIDAS eID information + * @param address Address information provided by user * @return Results from ZMR or ERnP search + * @throws WorkflowException In case of a register interaction error */ - public RegisterStatusResults searchWithResidence(RegisterOperationStatus operationStatus, SimpleEidasData eidasData, - String zipcode, String city, String street) { - final ZmrRegisterResult resultsZmr = zmrClient.searchWithResidenceData( - operationStatus.getZmrProcessId(), eidasData.getGivenName(), eidasData.getFamilyName(), - eidasData.getDateOfBirth(), zipcode, city, street); - return RegisterStatusResults.fromZmr(resultsZmr); + public RegisterStatusResults searchWithResidence(RegisterOperationStatus operationStatus, SimpleEidasData eidasData, + AdresssucheOutput address) throws WorkflowException { + try { + final ZmrRegisterResult resultsZmr = zmrClient.searchWithResidenceData( + operationStatus.getZmrProcessId(), eidasData.getGivenName(), eidasData.getFamilyName(), + eidasData.getDateOfBirth(), eidasData.getCitizenCountryCode(), address); + /* ERnP search is not used here, + * because we only search for people with Austrian residence and they are in ZMR only + */ + + return RegisterStatusResults.fromZmr(resultsZmr); + + } catch (final EidasSAuthenticationException e) { + throw new WorkflowException("searchWithResidenceInformation", e.getMessage(), + !(e instanceof ZmrCommunicationException), e); + + } } /** @@ -178,34 +199,49 @@ public class RegisterSearchService { * @param initialEidasData Received eidas data from initial authn * @return */ + @NonNull public RegisterStatusResults step7aKittProcess(RegisterStatusResults registerResult, SimpleEidasData initialEidasData) throws WorkflowException { log.trace("Starting step7aKittProcess"); - // TODO verify with which data this method gets called + + // check if only one single result was found if (registerResult.getResultCount() != 1) { throw new WorkflowException("step7aKittProcess", "getResultCount() != 1"); + } + + // perform updated operation in respect to register results try { if (registerResult.getResultsZmr().size() == 1) { RegisterResult entryZmr = registerResult.getResultsZmr().get(0); ZmrRegisterResult updateZmr = zmrClient .update(registerResult.getOperationStatus().getZmrProcessId(), entryZmr, initialEidasData); return RegisterStatusResults.fromZmr(updateZmr); + } else { RegisterResult entryErnp = registerResult.getResultsErnp().get(0); - RegisterResult updateErnp = ernpClient.update(entryErnp, initialEidasData); - return RegisterStatusResults.fromErnp(registerResult.operationStatus, Collections.singletonList(updateErnp)); + ErnpRegisterResult updateErnp = ernpClient.update(entryErnp, initialEidasData); + return RegisterStatusResults.fromErnp(registerResult.operationStatus, updateErnp); + } } catch (final EidasSAuthenticationException e) { throw new WorkflowException("kittMatchedIdentitiess", e.getMessage(), !(e instanceof ZmrCommunicationException), e); + } } - //TODO: check this method, because it's different to 'step7aKittProcess'??? /** * Automatic process to fix the register entries. * Called when the alternative eIDAS authn leads to a match in a register. + * + * <p>This method perform two additional operations: + * <ul> + * <li>Use bPK to check if <i>altSearchResult</i> is part of <i>initialSearchResult</i>.</li> + * <li>Update register entry twice, be using information from alternative authentication <i>altEidasData</i> + * and from initial authentication <i>initialEidasData</i>.</li> + * </ul> + * </p> * * @param initialSearchResult Register results from initial authentication * @param initialEidasData Received eIDAS data from initial authentication @@ -263,9 +299,9 @@ public class RegisterSearchService { ernpClient.update(entryErnp, initialEidasData); // update ZMR entry by using eIDAS information from alternative authentication - RegisterResult updateAlt = ernpClient.update(entryErnp, altEidasData); + ErnpRegisterResult updateAlt = ernpClient.update(entryErnp, altEidasData); - return RegisterStatusResults.fromErnp(altSearchResult.operationStatus, Collections.singletonList(updateAlt)); + return RegisterStatusResults.fromErnp(altSearchResult.getOperationStatus(), updateAlt); } } catch (final EidasSAuthenticationException e) { throw new WorkflowException("kittMatchedIdentitiess", e.getMessage(), @@ -373,13 +409,17 @@ public class RegisterSearchService { result.getPersonResult(), Collections.emptyList()); } - static RegisterStatusResults fromZmrAndErnp(ZmrRegisterResult result, List<RegisterResult> resultsErnp) { + static RegisterStatusResults fromZmrAndErnp(ZmrRegisterResult result, ErnpRegisterResult resultErnp) { return new RegisterStatusResults(new RegisterOperationStatus(result.getProcessId()), - result.getPersonResult(), resultsErnp); + result.getPersonResult(), resultErnp.getPersonResult()); } - static RegisterStatusResults fromErnp(RegisterOperationStatus status, List<RegisterResult> resultsErnp) { - return new RegisterStatusResults(status, Collections.emptyList(), resultsErnp); + static RegisterStatusResults fromErnp(RegisterOperationStatus status, ErnpRegisterResult updateErnp) { + return new RegisterStatusResults(status, Collections.emptyList(), updateErnp.getPersonResult()); + } + + static RegisterStatusResults fromEmpty(RegisterOperationStatus status) { + return new RegisterStatusResults(status, Collections.emptyList(), Collections.emptyList()); } } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java index f021fae9..96aa9c51 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java @@ -23,6 +23,8 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks; +import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED; +import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON; import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK; import java.util.Map; @@ -78,6 +80,8 @@ import lombok.extern.slf4j.Slf4j; @SuppressWarnings("PMD.TooManyStaticImports") public class AlternativeSearchTask extends AbstractAuthServletTask { + private static final String MSG_PROP_25 = "module.eidasauth.matching.25"; + private final RegisterSearchService registerSearchService; private final ICcSpecificEidProcessingService eidPostProcessor; @@ -200,6 +204,8 @@ public class AlternativeSearchTask extends AbstractAuthServletTask { log.trace("'step12CountrySpecificSearch' ends with no result. Forward to GUI based matching step ... "); log.debug("Forward to GUI based matching steps ... "); executionContext.put(TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK, true); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON, MSG_PROP_25); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); } else if (ccAltSearchResult.getResultCount() == 1) { log.debug("'step12CountrySpecificSearch' find single result. Starting KITT operation ... "); diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java index c95c275e..0aba70d1 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java @@ -23,21 +23,16 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks; -import java.io.IOException; -import java.io.InputStream; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.xml.parsers.ParserConfigurationException; import org.jetbrains.annotations.Nullable; import org.jose4j.lang.JoseException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; import com.fasterxml.jackson.core.JsonProcessingException; @@ -64,8 +59,6 @@ import at.gv.egiz.eaaf.core.impl.data.Pair; import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper; import at.gv.egiz.eaaf.core.impl.idp.auth.data.SimpleIdentityLinkAssertionParser; import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; -import at.gv.egiz.eaaf.core.impl.utils.DomUtils; -import at.gv.egiz.eaaf.core.impl.utils.XPathUtils; import lombok.Data; import lombok.extern.slf4j.Slf4j; import szrservices.IdentityLinkType; @@ -86,9 +79,6 @@ import szrservices.IdentityLinkType; * <ul> * <li>{@link at.gv.egiz.eaaf.core.impl.idp.controller.tasks.FinalizeAuthenticationTask}</li> * </ul> - * TODO Take Constants#DATA_SIMPLE_EIDAS and Constants#DATA_RESULT_MATCHING_BPK - * TODO Only do VSZ Erstellung and eidasBind -- this is always the end of the whole process - * TODO Move Eintragung to separate Task, as it does not happen every time * @author tlenz */ @Slf4j @@ -127,21 +117,17 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask { final SimpleEidasData eidData = MatchingTaskUtils.getInitialEidasData(pendingReq); MatchedPersonResult matchedPersonData = MatchingTaskUtils.getFinalMatchingResult(pendingReq); + // write log information based on current configuration writeMdsLogInformation(eidData); - if (basicConfig.getBasicConfigurationBoolean(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_USEDUMMY, false)) { - buildDummyIdentityLink(eidData); + //request SZR based on IDL or E-ID mode + if (pendingReq.getServiceProviderConfiguration() + .isConfigurationValue(MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE, false)) { + executeEidMode(eidData, matchedPersonData); } else { - //request SZR based on IDL or E-ID mode - if (pendingReq.getServiceProviderConfiguration() - .isConfigurationValue(MsEidasNodeConstants.PROP_CONFIG_SP_NEW_EID_MODE, false)) { - executeEidMode(eidData, matchedPersonData); + executeIdlMode(eidData, matchedPersonData); - } else { - executeIdlMode(eidData, matchedPersonData); - - } } storeGenericInfoToSession(eidData); @@ -192,16 +178,8 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask { private void executeEidMode(SimpleEidasData eidData, MatchedPersonResult matchedPersonData) throws JsonProcessingException, EaafException, JoseException { // get encrypted baseId - String vsz; - if (matchedPersonData != null) { - log.debug("Requesting encrypted baseId by already matched person information ... "); - vsz = szrClient.getEncryptedStammzahl(matchedPersonData); - - } else { - log.debug("Requesting encrypted baseId by using eIDAS information directly ... "); - vsz = szrClient.createNewErnpEntry(eidData); - - } + log.debug("Requesting encrypted baseId by already matched person information ... "); + String vsz = szrClient.getEncryptedStammzahl(matchedPersonData); //write revision-Log entry and extended infos personal-identifier mapping revisionsLogger.logEvent(pendingReq, MsConnectorEventCodes.SZR_VSZ_RECEIVED); @@ -224,21 +202,6 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask { } - private void buildDummyIdentityLink(SimpleEidasData eidData) - throws ParserConfigurationException, SAXException, IOException, EaafException { - AuthProcessDataWrapper authProcessDataWrapper = MatchingTaskUtils.getAuthProcessDataWrapper(pendingReq); - SzrResultHolder idlResult = createDummyIdentityLinkForTestDeployment(eidData); - //inject personal-data into session - authProcessDataWrapper.setIdentityLink(idlResult.getIdentityLink()); - - // set bPK and bPKType into auth session - authProcessDataWrapper.setGenericDataToSession(PvpAttributeDefinitions.BPK_NAME, extendBpkByPrefix( - idlResult.getBpK(), pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier())); - authProcessDataWrapper.setGenericDataToSession(PvpAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME, - pendingReq.getServiceProviderConfiguration() - .getAreaSpecificTargetIdentifier()); - } - private void writeExtendedRevisionLogEntry(SimpleEidasData eidData, String personalIdentifier) { // write ERnP input-data into revision-log if (basicConfig.getBasicConfigurationBoolean( @@ -252,18 +215,8 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask { private SzrResultHolder requestSzrForIdentityLink(SimpleEidasData eidData, MatchedPersonResult matchedPersonData) throws EaafException { //request IdentityLink from SZR - IdentityLinkType result; - - if (matchedPersonData != null) { - log.debug("Requesting encrypted baseId by already matched person information ... "); - result = szrClient.getIdentityLinkInRawMode(matchedPersonData); - - } else { - log.debug("Requesting encrypted baseId by using eIDAS information directly ... "); - result = szrClient.getIdentityLinkInRawMode(eidData); - - } - + log.debug("Requesting encrypted baseId by already matched person information ... "); + IdentityLinkType result = szrClient.getIdentityLinkInRawMode(matchedPersonData); final Element idlFromSzr = (Element) result.getAssertion(); final IIdentityLink identityLink = new SimpleIdentityLinkAssertionParser(idlFromSzr).parseIdentityLink(); @@ -364,63 +317,4 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask { final String bpK; } - - /** - * Build a dummy IdentityLink and a dummy bPK based on eIDAS information. - * - * <br><br> - * <b>FOR LOCAL TESTING ONLY!!!</b> - * - * @param eidData Information from eIDAS response - * @return IdentityLink and bPK - * @throws ParserConfigurationException In case of an IDL processing error - * @throws SAXException In case of an IDL processing error - * @throws IOException In case of an IDL processing error - * @throws EaafException In case of a bPK generation error - */ - private SzrResultHolder createDummyIdentityLinkForTestDeployment(SimpleEidasData eidData) - throws ParserConfigurationException, SAXException, IOException, EaafException { - log.warn("SZR-Dummy IS ACTIVE! IdentityLink is NOT VALID!!!!"); - // create fake IdL - // - fetch IdL template from resources - final InputStream s = CreateIdentityLinkTask.class - .getResourceAsStream("/resources/xmldata/fakeIdL_IdL_template.xml"); - final Element idlTemplate = DomUtils.parseXmlValidating(s); - - IIdentityLink identityLink = new SimpleIdentityLinkAssertionParser(idlTemplate).parseIdentityLink(); - - // replace data - final Element idlassertion = identityLink.getSamlAssertion(); - - // - set fake baseID; - final Node prIdentification = XPathUtils - .selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH); - prIdentification.getFirstChild().setNodeValue(eidData.getPseudonym()); - - // - set last name - final Node prFamilyName = XPathUtils - .selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_FAMILY_NAME_XPATH); - prFamilyName.getFirstChild().setNodeValue(eidData.getFamilyName()); - - // - set first name - final Node prGivenName = XPathUtils - .selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_GIVEN_NAME_XPATH); - prGivenName.getFirstChild().setNodeValue(eidData.getGivenName()); - - // - set date of birth - final Node prDateOfBirth = XPathUtils - .selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_DATE_OF_BIRTH_XPATH); - - prDateOfBirth.getFirstChild().setNodeValue(eidData.getDateOfBirth()); - - identityLink = new SimpleIdentityLinkAssertionParser(idlassertion).parseIdentityLink(); - - String idValue = identityLink.getIdentificationValue(); - String idType = identityLink.getIdentificationType(); - String targetId = pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier(); - final Pair<String, String> bpkCalc = BpkBuilder.generateAreaSpecificPersonIdentifier(idValue, idType, targetId); - return new SzrResultHolder(identityLink, bpkCalc.getFirst()); - - } - } 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..c7843be5 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; * <li>TODO MDS, BPK of new entry</li> * </ul> * + * @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 client 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/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateOtherLoginMethodGuiTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateOtherLoginMethodGuiTask.java index 7107709f..d29519be 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateOtherLoginMethodGuiTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateOtherLoginMethodGuiTask.java @@ -79,6 +79,13 @@ public class GenerateOtherLoginMethodGuiTask extends AbstractAuthServletTask { config.putCustomParameter(AbstractGuiFormBuilderConfiguration.PARAM_GROUP_UIOPTIONS, Constants.HTML_FORM_ADVANCED_MATCHING_FAILED, String.valueOf(true)); + //set detailed error-code + if (executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON) != null) { + config.putCustomParameter(AbstractGuiFormBuilderConfiguration.PARAM_GROUP_UIOPTIONS, + Constants.HTML_FORM_ADVANCED_MATCHING_FAILED_REASON, + executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON).toString()); + } + } guiBuilder.build(request, response, config, "Other login methods selection form"); 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 f295d66b..3a775837 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 @@ -122,8 +122,9 @@ public class InitialSearchTask extends AbstractAuthServletTask { if (resultCount == 0) { step6CountrySpecificSearch(executionContext, searchResult.getOperationStatus(), eidasData); - } else if (resultCount == 1) { - foundMatchFinalizeTask(searchResult, eidasData); + } else if (resultCount == 1) { + RegisterResult updatedResult = step3CheckRegisterUpdateNecessary(searchResult, eidasData); + foundMatchFinalizeTask(updatedResult, eidasData); } else { throw new WorkflowException("step2RegisterSearchWithPersonIdentifier", @@ -146,10 +147,12 @@ public class InitialSearchTask extends AbstractAuthServletTask { if (searchResult.getResultCount() == 0) { log.trace("'step6CountrySpecificSearch' ends with no result. Forward to next matching step ... "); step8RegisterSearchWithMds(executionContext, searchResult.getOperationStatus(), eidasData); + } else if (searchResult.getResultCount() == 1) { log.trace("'step6CountrySpecificSearch' finds a person. Forward to 'step7aKittProcess' step ... "); - registerSearchService.step7aKittProcess(searchResult, eidasData); - foundMatchFinalizeTask(searchResult, eidasData); + RegisterStatusResults updatedResult = registerSearchService.step7aKittProcess(searchResult, eidasData); + foundMatchFinalizeTask(updatedResult.getResult(), eidasData); + } else { throw new WorkflowException("step6CountrySpecificSearch", "More than one entry with unique country-specific information", true); @@ -164,34 +167,36 @@ public class InitialSearchTask extends AbstractAuthServletTask { if (registerData.getResultCount() == 0) { log.debug("Matching step: 'step8RegisterSearchWithMds' has no result. Forward to create new ERnP entry ... "); executionContext.put(TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK, true); + } else { log.debug("Matching step: 'step8RegisterSearchWithMds' has #{} results. " + "Forward to GUI based matching steps ... ", registerData.getResultCount()); MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerData); executionContext.put(TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK, true); + } } - private void foundMatchFinalizeTask(RegisterStatusResults searchResult, SimpleEidasData eidasData) - throws WorkflowException, EaafStorageException { - RegisterResult updatedResult = step3CheckRegisterUpdateNecessary(searchResult.getResult(), eidasData); - MatchedPersonResult result = MatchedPersonResult.generateFormMatchingResult( - updatedResult, eidasData.getCitizenCountryCode()); - MatchingTaskUtils.storeFinalMatchingResult(pendingReq, result); - } - - private RegisterResult step3CheckRegisterUpdateNecessary(RegisterResult searchResult, - SimpleEidasData eidasData) { + private RegisterResult step3CheckRegisterUpdateNecessary( + RegisterStatusResults searchResult, SimpleEidasData eidasData) throws WorkflowException { log.trace("Starting step3CheckRegisterUpdateNecessary"); - if (!eidasData.equalsRegisterData(searchResult)) { - log.info("Skipping update-register-information step, because it's not supported yet"); - //TODO: return updated search result if updates are allowed - return searchResult; + if (!eidasData.equalsRegisterData(searchResult.getResult())) { + log.debug("PersonalIdentifier match but MDS or other information changed. Starting update process ... "); + return registerSearchService.step7aKittProcess(searchResult, eidasData).getResult(); + } else { log.debug("Register information match to eIDAS information. No update required"); - return searchResult; + return searchResult.getResult(); } } + + private void foundMatchFinalizeTask(RegisterResult updatedResult, SimpleEidasData eidasData) + throws WorkflowException, EaafStorageException { + MatchedPersonResult result = + MatchedPersonResult.generateFormMatchingResult(updatedResult, eidasData.getCitizenCountryCode()); + MatchingTaskUtils.storeFinalMatchingResult(pendingReq, result); + + } @NotNull private SimpleEidasData convertEidasAttrToSimpleData() diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java index acf469d3..89a3f350 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java @@ -23,16 +23,24 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks; +import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED; +import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON; +import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK; + import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.springframework.stereotype.Component; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController.AdresssucheOutput; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController.AdresssucheOutput.AdresssucheOutputBuilder; 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.ManualFixNecessaryException; @@ -43,15 +51,9 @@ 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.auth.modules.AbstractAuthServletTask; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; +import at.gv.egiz.eaaf.core.impl.idp.controller.tasks.AbstractLocaleAuthServletTask; import lombok.extern.slf4j.Slf4j; -import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED; -import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK; - /** * Task receives the response of {@link GenerateAustrianResidenceGuiTask} and handles it. @@ -67,7 +69,7 @@ import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.TRANSIT * </ul> * Transitions: * <ul> - * <li>{@link CreateNewErnpEntryTask} if no results from search with residency data in registers</li> + * <li>{@link GenerateOtherLoginMethodGuiTask} if no results from search with residency data in registers</li> * <li>{@link CreateIdentityLinkTask} if one exact match between initial register search (with MDS) and results * from search with residency data in registers exists</li> * <li>{@link GenerateOtherLoginMethodGuiTask} if a user input error has happened</li> @@ -79,71 +81,77 @@ import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.TRANSIT */ @Slf4j @Component("ReceiveAustrianResidenceGuiResponseTask") -public class ReceiveAustrianResidenceGuiResponseTask extends AbstractAuthServletTask { +public class ReceiveAustrianResidenceGuiResponseTask extends AbstractLocaleAuthServletTask { - public static final String PARAM_FORMER_RESIDENCE_AVAILABLE = "formerResidenceAvailable"; - public static final String PARAM_STREET = "street"; - public static final String PARAM_CITY = "city"; - public static final String PARAM_ZIPCODE = "zipcode"; + private static final String MSG_PROP_20 = "module.eidasauth.matching.20"; + private static final String MSG_PROP_21 = "module.eidasauth.matching.21"; + private static final String MSG_PROP_22 = "module.eidasauth.matching.22"; + + public static final String HTTP_PARAM_NO_RESIDENCE = "noResidence"; private final RegisterSearchService registerSearchService; public ReceiveAustrianResidenceGuiResponseTask(RegisterSearchService registerSearchService) { this.registerSearchService = registerSearchService; + } - - @Data - @AllArgsConstructor - @NoArgsConstructor - public static class UserInput { - private boolean formerResidenceAvailable; - private String zipcode; - private String city; - private String street; - } - + @Override - public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) - throws TaskExecutionException { + protected void executeWithLocale(ExecutionContext executionContext, HttpServletRequest request, + HttpServletResponse response) throws TaskExecutionException { log.trace("Starting ReceiveAustrianResidenceGuiResponseTask"); - UserInput input = parseHtmlInput(request); - if (!input.isFormerResidenceAvailable()) { - moveToNextTask(executionContext); - return; - - } - - if (input.getStreet().isEmpty() || input.getCity().isEmpty() || input.getZipcode().isEmpty()) { - // HTML form should ensure that mandatory fields are set => this should never happen - executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); - executionContext.put(TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK, true); - return; - - } + try { + //return to AuswahlScreen if HTTP_PARAM_NO_RESIDENCE was selected + final boolean forwardWithOutMandate = parseFlagFromHttpRequest(request, HTTP_PARAM_NO_RESIDENCE, false); + if (forwardWithOutMandate) { + log.debug("User selects 'no residence' button. Switch back to 'other matching' selection ... "); + executionContext.put(TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK, true); + + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON, MSG_PROP_20); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); + return; + + } + + //load search parameters from HTML form + AdresssucheOutput input = parseHtmlInput(request); + if (validateHtmlInput(input)) { + // HTML form should ensure that mandatory fields are set => this should never happen + log.warn("HTML form contains no residence information. Switch back to 'other matching' selection ... "); + executionContext.put(TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK, true); + + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON, MSG_PROP_21); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); + return; - try { + } + + // get pre-processed information SimpleEidasData eidasData = MatchingTaskUtils.getInitialEidasData(pendingReq); RegisterStatusResults initialSearchResult = MatchingTaskUtils.getIntermediateMatchingResult(pendingReq); + // search in register RegisterStatusResults residencyResult = - registerSearchService.searchWithResidence(initialSearchResult.getOperationStatus(), - eidasData, input.zipcode, input.city, input.street); - if (residencyResult.getResultCount() == 0) { - //TODO: her we should add a GUI step of result is zero to inform user an forward process by click - moveToNextTask(executionContext); - - } else if (residencyResult.getResultCount() == 1) { - compareSearchResultWithInitialData(executionContext, residencyResult, eidasData); + registerSearchService.searchWithResidence(initialSearchResult.getOperationStatus(), eidasData, input); + + // validate matching response from registers + if (residencyResult.getResultCount() != 1) { + log.info("Find {} match by using residence information. Forward user to 'other matching' selection ... ", + residencyResult.getResultCount() == 0 ? "no" : "more-than-one"); + executionContext.put(TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK, true); + + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON, MSG_PROP_22); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); } else { - /*TODO: align with form generation task and to better error handling in case of more-than-one result. - * Maybe the user has to provide more information. - */ - throw new TaskExecutionException(pendingReq, - "Manual Fix necessary", new ManualFixNecessaryException(eidasData)); + log.debug("Find single match by using residence information. Starting data validation ... "); + compareSearchResultWithInitialData(residencyResult, eidasData); } + } catch (WorkflowException e) { + throw new TaskExecutionException(pendingReq, "Search with residency data failed", e); + } catch (EaafStorageException e) { log.error("Search with residency data failed", e); throw new TaskExecutionException(pendingReq, "Search with residency data failed", e); @@ -151,58 +159,67 @@ public class ReceiveAustrianResidenceGuiResponseTask extends AbstractAuthServlet } } - private void compareSearchResultWithInitialData(ExecutionContext executionContext, - RegisterStatusResults residencyResult, SimpleEidasData eidasData) + private boolean validateHtmlInput(AdresssucheOutput input) { + return StringUtils.isEmpty(input.getMunicipality()) + && StringUtils.isEmpty(input.getNumber()) + && StringUtils.isEmpty(input.getPostleitzahl()) + && StringUtils.isEmpty(input.getStreet()) + && StringUtils.isEmpty(input.getVillage()); + } + + private void compareSearchResultWithInitialData(RegisterStatusResults residencyResult, SimpleEidasData eidasData) throws TaskExecutionException, EaafStorageException { try { - if (eidasData.equalsRegisterData(residencyResult.getResult())) { + if (!eidasData.equalsRegisterData(residencyResult.getResult())) { // update register information - registerSearchService.step7aKittProcess(residencyResult, eidasData); + RegisterStatusResults updateResult = registerSearchService.step7aKittProcess(residencyResult, eidasData); - // store search result to re-used in CreateIdentityLink step, because there we need bPK and MDS + // store updated result to re-used in CreateIdentityLink step, because there we need bPK and MDS MatchingTaskUtils.storeFinalMatchingResult(pendingReq, MatchedPersonResult.generateFormMatchingResult( - residencyResult.getResult(), eidasData.getCitizenCountryCode())); + updateResult.getResult(), eidasData.getCitizenCountryCode())); } else { - moveToNextTask(executionContext); - + log.warn("Suspect state FOUND. Matching by residence was neccessary but NO register-update are required!"); + // no update required. Data can be used as it is. + MatchingTaskUtils.storeFinalMatchingResult(pendingReq, + MatchedPersonResult.generateFormMatchingResult( + residencyResult.getResult(), eidasData.getCitizenCountryCode())); + } - + } catch (WorkflowException e) { + log.warn("Kitt operation after successful residence matching FAILED.", e); throw new TaskExecutionException(pendingReq, "Search failed", new ManualFixNecessaryException(eidasData)); } } - private void moveToNextTask(ExecutionContext executionContext) { - // Later on, this should transition to Step 20 - executionContext.put(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK, true); - - } - - private @NotNull UserInput parseHtmlInput(HttpServletRequest request) { + private @NotNull AdresssucheOutput parseHtmlInput(HttpServletRequest request) { Enumeration<String> reqParamNames = request.getParameterNames(); - UserInput result = new UserInput(); + AdresssucheOutputBuilder resultBuilder = AdresssucheOutput.builder(); while (reqParamNames.hasMoreElements()) { final String paramName = reqParamNames.nextElement(); String escaped = StringEscapeUtils.escapeHtml(request.getParameter(paramName)); - if (PARAM_FORMER_RESIDENCE_AVAILABLE.equalsIgnoreCase(paramName)) { - result.setFormerResidenceAvailable(Boolean.parseBoolean(escaped)); + if (AdresssucheController.PARAM_MUNIPICALITY.equalsIgnoreCase(paramName)) { + resultBuilder.municipality(escaped); - } else if (PARAM_STREET.equalsIgnoreCase(paramName)) { - result.setStreet(escaped); + } else if (AdresssucheController.PARAM_NUMBER.equalsIgnoreCase(paramName)) { + resultBuilder.number(escaped); - } else if (PARAM_CITY.equalsIgnoreCase(paramName)) { - result.setCity(escaped); + } else if (AdresssucheController.PARAM_POSTLEITZAHL.equalsIgnoreCase(paramName)) { + resultBuilder.postleitzahl(escaped); - } else if (PARAM_ZIPCODE.equalsIgnoreCase(paramName)) { - result.setZipcode(escaped); + } else if (AdresssucheController.PARAM_STREET.equalsIgnoreCase(paramName)) { + resultBuilder.street(escaped); + + } else if (AdresssucheController.PARAM_VILLAGE.equalsIgnoreCase(paramName)) { + resultBuilder.village(escaped); } } - return result; - + + return resultBuilder.build(); } } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseTask.java index 3e57ea24..514e38ba 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseTask.java @@ -24,6 +24,7 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks; import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED; +import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON; import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK; import static at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING; @@ -127,6 +128,9 @@ public class ReceiveMobilePhoneSignatureResponseTask extends AbstractAuthServlet private static final String ERROR_MSG_02 = "PVP response decryption FAILED. No credential found."; private static final String ERROR_MSG_03 = "PVP response validation FAILED."; + private static final String MSG_PROP_23 = "module.eidasauth.matching.23"; + private static final String MSG_PROP_24 = "module.eidasauth.matching.24"; + /** * Creates the new task, with autowired dependencies from Spring. */ @@ -152,7 +156,9 @@ public class ReceiveMobilePhoneSignatureResponseTask extends AbstractAuthServlet Pair<PvpSProfileResponse, Boolean> processedMsg = validateAssertion((PvpSProfileResponse) inboundMessage); if (processedMsg.getSecond()) { // forward to next matching step in case of ID Autria authentication was stopped by user - executionContext.put(Constants.TRANSITION_TO_GENERATE_GUI_QUERY_AUSTRIAN_RESIDENCE_TASK, true); + executionContext.put(TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK, true); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON, MSG_PROP_23); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); return; } @@ -171,8 +177,9 @@ public class ReceiveMobilePhoneSignatureResponseTask extends AbstractAuthServlet // check if MDS from ID Austria authentication matchs to eIDAS authentication if (!simpleMobileSignatureData.equalsSimpleEidasData(eidasData)) { - executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); executionContext.put(TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK, true); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON, MSG_PROP_24); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); return; } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveOtherLoginMethodGuiResponseTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveOtherLoginMethodGuiResponseTask.java index f4419c1c..c9f043b5 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveOtherLoginMethodGuiResponseTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveOtherLoginMethodGuiResponseTask.java @@ -23,17 +23,19 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks; +import java.util.Enumeration; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringEscapeUtils; +import org.springframework.stereotype.Component; + import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SelectedLoginMethod; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.impl.idp.controller.tasks.AbstractLocaleAuthServletTask; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.StringEscapeUtils; -import org.springframework.stereotype.Component; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Enumeration; /** * Handles user's selection from {@link GenerateOtherLoginMethodGuiTask}. @@ -65,12 +67,13 @@ public class ReceiveOtherLoginMethodGuiResponseTask extends AbstractLocaleAuthSe SelectedLoginMethod selection = SelectedLoginMethod.valueOf(extractUserSelection(request)); executionContext.put(Constants.REQ_SELECTED_LOGIN_METHOD_PARAMETER, selection); executionContext.remove(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED); + executionContext.remove(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON); transitionToNextTask(executionContext, selection); } catch (final Exception e) { log.error("Parsing selected login method FAILED.", e); executionContext.put(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); - executionContext.put(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK, true); + executionContext.put(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK, true); } } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml index c9bdad94..6ca21550 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml @@ -35,6 +35,8 @@ <!-- alternative matching modes --> <pd:Transition from="generateOtherLoginMethodGuiTask" to="receiveOtherLoginMethodGuiResponseTask" /> + <pd:Transition conditionExpression="ctx['TASK_GenerateOtherLoginMethodGuiTask'] or ctx['changeLanguage']" + from="receiveOtherLoginMethodGuiResponseTask" to="generateOtherLoginMethodGuiTask" /> <pd:Transition conditionExpression="ctx['TASK_GenerateAlternativeEidasAuthn']" from="receiveOtherLoginMethodGuiResponseTask" to="generateAlternativeEidasAuthnRequest" /> <pd:Transition conditionExpression="ctx['TASK_GenerateMobilePhoneSignatureRequestTask']" @@ -54,17 +56,17 @@ <!-- ID Austria authentication --> <pd:Transition from="generateMobilePhoneSignatureRequestTask" to="receiveMobilePhoneSignatureResponseTask" /> - <pd:Transition conditionExpression="ctx['TASK_GenerateAustrianResidenceGuiTask']" + <pd:Transition conditionExpression="ctx['TASK_GenerateOtherLoginMethodGuiTask']" from="receiveMobilePhoneSignatureResponseTask" to="generateOtherLoginMethodGuiTask" /> <pd:Transition from="receiveMobilePhoneSignatureResponseTask" to="generateIdentityLink" /> <!-- address searching --> - <pd:Transition from="generateAustrianResidenceGuiTask" to="receiveAustrianResidenceGuiResponseTask" /> + <pd:Transition from="generateAustrianResidenceGuiTask" to="receiveAustrianResidenceGuiResponseTask" /> + <pd:Transition conditionExpression="ctx['changeLanguage']" + from="receiveAustrianResidenceGuiResponseTask" to="generateAustrianResidenceGuiTask" /> <pd:Transition conditionExpression="ctx['TASK_GenerateOtherLoginMethodGuiTask']" - from="receiveAustrianResidenceGuiResponseTask" to="generateOtherLoginMethodGuiTask" /> - <pd:Transition conditionExpression="ctx['TASK_CreateNewErnpEntryTask']" - from="receiveAustrianResidenceGuiResponseTask" to="createNewErnpEntryTask" /> + from="receiveAustrianResidenceGuiResponseTask" to="generateOtherLoginMethodGuiTask" /> <pd:Transition from="receiveAustrianResidenceGuiResponseTask" to="generateIdentityLink" /> 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 d82ccec5..40e63a91 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 @@ -26,13 +26,8 @@ <bean id="zmrAddressClient" class="at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrAddressSoapClient" /> - <!-- bean id="ZmrClientForeIDAS" - class="at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr.DummyZmrClient" /--> - - - <bean id="ErnbClientForeIDAS" - class="at.asitplus.eidas.specific.modules.auth.eidas.v2.ernp.DummyErnpClient" /> - + <bean id="ernpClient" + class="at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.ErnpRestClient" /> <bean id="eIDASAuthModule" class="at.asitplus.eidas.specific.modules.auth.eidas.v2.EidasAuthenticationModulImpl"> diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties index 3ccfff19..3942f30a 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties @@ -20,4 +20,15 @@ module.eidasauth.matching.02=Matching failed, because ZMR response contains hist module.eidasauth.matching.03=Matching failed in workflow step: {0} with error: {1} module.eidasauth.matching.04=An error occurred while loading your data from official registers. Please contact the support. +module.eidasauth.matching.11=Matching failed, because of an ERnP communication error. Reason: {0} +module.eidasauth.matching.12=Matching failed, because ERnP response contains historic information which is not supported. + +module.eidasauth.matching.20=Matching be using residence information was canceled. Use another method for matching or create a new Austrian identity. +module.eidasauth.matching.21=Matching be using residence information failed by missing input information. Use another method for matching or create a new Austrian identity. +module.eidasauth.matching.22=Can not find an unique match by using residence information. Provide more or other data, use another method for matching, or create a new Austrian identity. +module.eidasauth.matching.23=Matching be using Austrian Identity was canceled. Use another method for matching or create a new Austrian identity. +module.eidasauth.matching.24=Matching be using Austrian Identity not possible. Use another method for matching or create a new Austrian identity. +module.eidasauth.matching.25=Matching be using alternative eIDAS authentication not possible. Provide more or other data, use another method for matching, or create a new Austrian identity. + module.eidasauth.matching.99=Matching failed, because of an unexpected processing error. Reason: {0} + diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json new file mode 100644 index 00000000..9e09240f --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json @@ -0,0 +1,1940 @@ +{ + "openapi" : "3.0.1", + "info" : { + "title" : "ERNP", + "version" : "1.0.0" + }, + "servers" : [ { + "url" : "https://stportal.bmi.intra.gv.at/at.gv.bmi.erpsrv-p/srv/rest/", + "description" : "Produktion", + "variables" : { } + }, { + "url" : "https://stportal.bmi.intra.gv.at/at.gv.bmi.erpsrv-e/srv/rest/", + "description" : "Entwicklung", + "variables" : { } + }, { + "url" : "https://stportal.bmi.intra.gv.at/at.gv.bmi.erpsrv-t/srv/rest/", + "description" : "Interne Test", + "variables" : { } + }, { + "url" : "https://stportal.bmi.intra.gv.at/at.gv.bmi.erpsrv-a/srv/rest/", + "description" : "Externe Test", + "variables" : { } + }, { + "url" : "https://stportal.bmi.intra.gv.at/at.gv.bmi.erpsrv-b/srv/rest/", + "description" : "Businespartner Test", + "variables" : { } + }, { + "url" : "http://localhost:29200/at.gv.bmi.erpv01-d/srv/rest/", + "description" : "Lokal", + "variables" : { } + }, { + "url" : "http://localhost:29200/at.gv.bmi.erpv01-e/srv/rest/", + "description" : "Entwicklung (kein Portal)", + "variables" : { } + }, { + "url" : "http://localhost:29200/at.gv.bmi.erpv01-t/srv/rest/", + "description" : "Interne Test (kein Portal)", + "variables" : { } + }, { + "url" : "http://localhost:29200/at.gv.bmi.erpv01-a/srv/rest/", + "description" : "Externe Test (kein Portal)", + "variables" : { } + }, { + "url" : "http://localhost:29200/at.gv.bmi.erpv11-a/srv/rest/", + "description" : "Businespartner Test (kein Portal)", + "variables" : { } + } ], + "paths" : { + "/eidas/person/aendern" : { + "post" : { + "operationId" : "aendern", + "parameters" : [ { + "name" : "Client-Request-Time", + "in" : "header", + "description" : "Client-Requestzeit im ISO-8601 Format mit optionaler Zeitzone (zb '2016-10-27T16:36:08.993')", + "schema" : { + "type" : "string", + "format" : "date-time" + } + }, { + "name" : "Client-Request-Id", + "in" : "header", + "description" : "Client-Request ID (um Systemübergreifende Fehlersuche zu vereinfache)", + "schema" : { + "type" : "string" + } + }, { + "name" : "Client-Behkz", + "in" : "header", + "description" : "Client-Behördenkennzeichen", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "Client-Name", + "in" : "header", + "description" : "Client-Name bzw Applikationskürzel und Version des aufrufenden Systems (zb 'ZMR 3.4.5')", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PersonAendern" + } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/PersonAendern" + } + } + } + }, + "responses" : { + "default" : { + "description" : "Erfolgreicher Response hat Status 200 wenn Responsepayload vorhanden, sonst 204", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AendernResponse" + } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/AendernResponse" + } + } + } + }, + "4XX" : { + "description" : "Client Fehler (kann vom Client behoben werden)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + } + } + }, + "5XX" : { + "description" : "Server Fehler (normalerweise nicht vom Client behebbar)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + } + } + } + } + } + }, + "/eidas/person/anlegen" : { + "post" : { + "operationId" : "anlegen", + "parameters" : [ { + "name" : "Client-Request-Time", + "in" : "header", + "description" : "Client-Requestzeit im ISO-8601 Format mit optionaler Zeitzone (zb '2016-10-27T16:36:08.993')", + "schema" : { + "type" : "string", + "format" : "date-time" + } + }, { + "name" : "Client-Request-Id", + "in" : "header", + "description" : "Client-Request ID (um Systemübergreifende Fehlersuche zu vereinfache)", + "schema" : { + "type" : "string" + } + }, { + "name" : "Client-Behkz", + "in" : "header", + "description" : "Client-Behördenkennzeichen", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "Client-Name", + "in" : "header", + "description" : "Client-Name bzw Applikationskürzel und Version des aufrufenden Systems (zb 'ZMR 3.4.5')", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PersonAnlegen" + } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/PersonAnlegen" + } + } + } + }, + "responses" : { + "default" : { + "description" : "Erfolgreicher Response hat Status 200 wenn Responsepayload vorhanden, sonst 204", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AnlegenResponse" + } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/AnlegenResponse" + } + } + } + }, + "4XX" : { + "description" : "Client Fehler (kann vom Client behoben werden)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + } + } + }, + "5XX" : { + "description" : "Server Fehler (normalerweise nicht vom Client behebbar)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + } + } + } + } + } + }, + "/eidas/person/suchen" : { + "post" : { + "operationId" : "suchen", + "parameters" : [ { + "name" : "Client-Request-Time", + "in" : "header", + "description" : "Client-Requestzeit im ISO-8601 Format mit optionaler Zeitzone (zb '2016-10-27T16:36:08.993')", + "schema" : { + "type" : "string", + "format" : "date-time" + } + }, { + "name" : "Client-Request-Id", + "in" : "header", + "description" : "Client-Request ID (um Systemübergreifende Fehlersuche zu vereinfache)", + "schema" : { + "type" : "string" + } + }, { + "name" : "Client-Behkz", + "in" : "header", + "description" : "Client-Behördenkennzeichen", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "Client-Name", + "in" : "header", + "description" : "Client-Name bzw Applikationskürzel und Version des aufrufenden Systems (zb 'ZMR 3.4.5')", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PersonSuchen" + } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/PersonSuchen" + } + } + } + }, + "responses" : { + "default" : { + "description" : "Erfolgreicher Response hat Status 200 wenn Responsepayload vorhanden, sonst 204", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/SuchenResponse" + } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/SuchenResponse" + } + } + } + }, + "4XX" : { + "description" : "Client Fehler (kann vom Client behoben werden)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + } + } + }, + "5XX" : { + "description" : "Server Fehler (normalerweise nicht vom Client behebbar)", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "Fault" : { + "required" : [ "message" ], + "type" : "object", + "properties" : { + "message" : { + "type" : "string", + "xml" : { + "name" : "Message" + } + }, + "faultDetails" : { + "$ref" : "#/components/schemas/FaultDetails" + } + }, + "xml" : { + "name" : "Fault" + } + }, + "FaultDetails" : { + "required" : [ "fault" ], + "type" : "object", + "properties" : { + "faultNumber" : { + "type" : "integer", + "format" : "int32", + "xml" : { + "name" : "FaultNumber" + } + }, + "fault" : { + "type" : "array", + "xml" : { + "name" : "Fault" + }, + "items" : { + "$ref" : "#/components/schemas/FaultDetailsEntry" + } + } + } + }, + "FaultDetailsEntry" : { + "type" : "object", + "properties" : { + "key" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "message" : { + "type" : "string", + "xml" : { + "attribute" : true + } + } + } + }, + "AendernResponse" : { + "required" : [ "person" ], + "type" : "object", + "properties" : { + "person" : { + "$ref" : "#/components/schemas/Person" + } + }, + "xml" : { + "name" : "AendernResponse" + } + }, + "AkademischerGrad" : { + "required" : [ "ebene", "kurzerName", "langerName", "stellung" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "ausgestelltVon" : { + "$ref" : "#/components/schemas/AusgestelltVon" + }, + "ebene" : { + "type" : "string", + "xml" : { + "name" : "Ebene" + }, + "enum" : [ "0", "1", "2", "2/3", "3" ] + }, + "stellung" : { + "type" : "string", + "xml" : { + "name" : "Stellung" + }, + "enum" : [ "Vorangestellt", "Nachgestellt" ] + }, + "langerName" : { + "type" : "string", + "xml" : { + "name" : "LangerName" + } + }, + "kurzerName" : { + "type" : "string", + "xml" : { + "name" : "KurzerName" + } + } + } + }, + "Anschrift" : { + "required" : [ "staat", "strasse", "type" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "staat" : { + "$ref" : "#/components/schemas/Staat" + }, + "gemeinde" : { + "type" : "string", + "xml" : { + "name" : "Gemeinde" + } + }, + "strasse" : { + "type" : "string", + "xml" : { + "name" : "Strasse" + } + }, + "postleitzahl" : { + "type" : "string", + "xml" : { + "name" : "Postleitzahl" + } + }, + "hausnummer" : { + "type" : "string", + "xml" : { + "name" : "Hausnummer" + } + }, + "adresszusatz" : { + "type" : "string", + "xml" : { + "name" : "Adresszusatz" + } + }, + "stiege" : { + "type" : "string", + "xml" : { + "name" : "Stiege" + } + }, + "tuer" : { + "type" : "string", + "xml" : { + "name" : "Tuer" + } + }, + "kontaktinformationen" : { + "$ref" : "#/components/schemas/Kontaktinformationen" + }, + "type" : { + "type" : "string" + } + }, + "discriminator" : { + "propertyName" : "type" + } + }, + "AnschriftInland" : { + "required" : [ "gemeinde", "hausnummer", "ort", "postleitzahl", "staat", "strasse" ], + "type" : "object", + "allOf" : [ { + "$ref" : "#/components/schemas/Anschrift" + }, { + "type" : "object", + "properties" : { + "adressstatus" : { + "type" : "string", + "xml" : { + "name" : "Adressstatus" + } + }, + "ort" : { + "type" : "string", + "xml" : { + "name" : "Ort" + } + }, + "ortZweisprachig" : { + "type" : "string", + "xml" : { + "name" : "OrtZweisprachig" + } + }, + "postort" : { + "type" : "string", + "xml" : { + "name" : "Postort" + } + }, + "codes" : { + "$ref" : "#/components/schemas/Anschriftcodes" + }, + "auskunftssperre" : { + "type" : "boolean", + "xml" : { + "name" : "Auskunftssperre" + } + }, + "wohnsitzqualitaet" : { + "type" : "string", + "xml" : { + "name" : "Wohnsitzqualitaet" + }, + "enum" : [ "H", "N", "O" ] + } + } + } ] + }, + "AnschriftInlandAgs" : { + "required" : [ "gemeinde", "hausnummer", "ort", "postleitzahl", "staat", "strasse" ], + "type" : "object", + "allOf" : [ { + "$ref" : "#/components/schemas/Anschrift" + }, { + "type" : "object", + "properties" : { + "adressstatus" : { + "type" : "string", + "xml" : { + "name" : "Adressstatus" + } + }, + "ort" : { + "type" : "string", + "xml" : { + "name" : "Ort" + } + }, + "ortZweisprachig" : { + "type" : "string", + "xml" : { + "name" : "OrtZweisprachig" + } + }, + "postort" : { + "type" : "string", + "xml" : { + "name" : "Postort" + } + }, + "codes" : { + "$ref" : "#/components/schemas/Anschriftcodes" + }, + "auskunftssperre" : { + "type" : "boolean", + "xml" : { + "name" : "Auskunftssperre" + } + }, + "wohnsitzqualitaet" : { + "type" : "string", + "xml" : { + "name" : "Wohnsitzqualitaet" + }, + "enum" : [ "H", "N", "O" ] + }, + "detailgrad" : { + "type" : "string", + "xml" : { + "name" : "Detailgrad" + } + }, + "nutzungsartCode" : { + "type" : "string", + "xml" : { + "name" : "NutzungsartCode" + } + }, + "gebaeudeeigenschaft" : { + "type" : "string", + "xml" : { + "name" : "Gebaeudeeigenschaft" + } + } + } + } ] + }, + "Anschriftcodes" : { + "type" : "object", + "properties" : { + "adresscode" : { + "type" : "string", + "xml" : { + "name" : "Adresscode", + "attribute" : true + } + }, + "subcode" : { + "type" : "string", + "xml" : { + "name" : "Subcode", + "attribute" : true + } + }, + "ortskennziffer" : { + "type" : "string", + "xml" : { + "name" : "Ortskennziffer", + "attribute" : true + } + }, + "strassenkennziffer" : { + "type" : "string", + "xml" : { + "name" : "Strassenkennziffer", + "attribute" : true + } + }, + "objektnummer" : { + "type" : "string", + "xml" : { + "name" : "Objektnummer", + "attribute" : true + } + }, + "nutzungseinheitlaufnummer" : { + "type" : "string", + "xml" : { + "name" : "Nutzungseinheitlaufnummer", + "attribute" : true + } + }, + "adrRefkey" : { + "type" : "string", + "xml" : { + "name" : "AdrRefkey", + "attribute" : true + } + }, + "gbrRefkey" : { + "type" : "string", + "xml" : { + "name" : "GbrRefkey", + "attribute" : true + } + }, + "gemeindekennziffer" : { + "type" : "string", + "xml" : { + "name" : "Gemeindekennziffer", + "attribute" : true + } + } + } + }, + "AusgestelltVon" : { + "required" : [ "behoerde", "datum", "staat" ], + "type" : "object", + "properties" : { + "datum" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "name" : "Datum" + } + }, + "behoerde" : { + "type" : "string", + "xml" : { + "name" : "Behoerde" + } + }, + "staat" : { + "$ref" : "#/components/schemas/Staat" + } + } + }, + "Benutzer" : { + "required" : [ "benutzer" ], + "type" : "object", + "properties" : { + "benutzer" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "behoerdenkennzeichen" : { + "type" : "string", + "xml" : { + "attribute" : true + } + } + } + }, + "Eidas" : { + "required" : [ "art", "staatscode2", "wert" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "art" : { + "type" : "string", + "xml" : { + "name" : "Art" + } + }, + "wert" : { + "type" : "string", + "xml" : { + "name" : "Wert" + } + }, + "ausstellDatum" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "name" : "AusstellDatum" + } + }, + "ablaufDatum" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "name" : "AblaufDatum" + } + }, + "ausstellBehoerde" : { + "type" : "string", + "xml" : { + "name" : "AusstellBehoerde" + } + }, + "staatscode2" : { + "type" : "string", + "xml" : { + "name" : "Staatscode2" + } + } + } + }, + "Kontaktinformationen" : { + "type" : "object", + "properties" : { + "firmenname1" : { + "type" : "string", + "xml" : { + "name" : "Firmenname1" + } + }, + "firmenname2" : { + "type" : "string", + "xml" : { + "name" : "Firmenname2" + } + }, + "ansprechpartner" : { + "type" : "string", + "xml" : { + "name" : "Ansprechpartner" + } + }, + "telefon" : { + "type" : "string", + "xml" : { + "name" : "Telefon" + } + }, + "mobil" : { + "type" : "string", + "xml" : { + "name" : "Mobil" + } + }, + "fax" : { + "type" : "string", + "xml" : { + "name" : "Fax" + } + }, + "email" : { + "type" : "string", + "xml" : { + "name" : "Email" + } + }, + "postfach" : { + "type" : "string", + "xml" : { + "name" : "Postfach" + } + } + } + }, + "LetzteOperation" : { + "required" : [ "begruendung", "durchgefuehrtVon" ], + "type" : "object", + "properties" : { + "begruendung" : { + "type" : "string", + "xml" : { + "name" : "Begruendung" + } + }, + "durchgefuehrtVon" : { + "$ref" : "#/components/schemas/Benutzer" + }, + "vorgang" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "zeitpunkt" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + } + } + }, + "PartialDate" : { + "required" : [ "jahr" ], + "type" : "object", + "properties" : { + "jahr" : { + "type" : "integer", + "format" : "int32", + "xml" : { + "attribute" : true + } + }, + "monat" : { + "type" : "integer", + "format" : "int32", + "xml" : { + "attribute" : true + } + }, + "tag" : { + "type" : "integer", + "format" : "int32", + "xml" : { + "attribute" : true + } + } + } + }, + "Person" : { + "required" : [ "letzteOperation", "personendaten", "type" ], + "type" : "object", + "properties" : { + "letzteOperation" : { + "$ref" : "#/components/schemas/LetzteOperation" + }, + "personendaten" : { + "$ref" : "#/components/schemas/PersonendatenErgebnis" + }, + "anschrift" : { + "$ref" : "#/components/schemas/Anschrift" + }, + "akademischerGrad" : { + "type" : "array", + "xml" : { + "name" : "AkademischerGrad" + }, + "items" : { + "$ref" : "#/components/schemas/AkademischerGrad" + } + }, + "reisedokument" : { + "type" : "array", + "xml" : { + "name" : "Reisedokument" + }, + "items" : { + "$ref" : "#/components/schemas/Reisedokument" + } + }, + "sonstigesDokument" : { + "type" : "array", + "xml" : { + "name" : "SonstigesDokument" + }, + "items" : { + "$ref" : "#/components/schemas/SonstigesDokument" + } + }, + "staatsangehoerigkeit" : { + "type" : "array", + "xml" : { + "name" : "Staatsangehoerigkeit" + }, + "items" : { + "$ref" : "#/components/schemas/Staatsangehoerigkeit" + } + }, + "eidas" : { + "type" : "array", + "xml" : { + "name" : "Eidas" + }, + "items" : { + "$ref" : "#/components/schemas/Eidas" + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "version" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "type" : { + "type" : "string" + } + }, + "discriminator" : { + "propertyName" : "type" + } + }, + "PersonendatenErgebnis" : { + "required" : [ "basiszahl", "familienname", "geburtsdatum", "vorname" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "familienname" : { + "type" : "string", + "xml" : { + "name" : "Familienname" + } + }, + "nameVorEhe" : { + "type" : "string", + "xml" : { + "name" : "NameVorEhe" + } + }, + "vorname" : { + "type" : "string", + "xml" : { + "name" : "Vorname" + } + }, + "geburtsbundesland" : { + "type" : "string", + "xml" : { + "name" : "Geburtsbundesland" + }, + "enum" : [ "Burgenland", "Kärnten", "Niederösterreich", "Oberösterreich", "Salzburg", "Steiermark", "Tirol", "Vorarlberg", "Wien" ] + }, + "geburtsort" : { + "type" : "string", + "xml" : { + "name" : "Geburtsort" + } + }, + "geburtsstaat" : { + "$ref" : "#/components/schemas/Staat" + }, + "geburtsdatum" : { + "$ref" : "#/components/schemas/PartialDate" + }, + "geschlecht" : { + "type" : "string", + "xml" : { + "name" : "Geschlecht" + }, + "enum" : [ "Männlich", "Weiblich" ] + }, + "basiszahl" : { + "type" : "string", + "xml" : { + "name" : "Basiszahl" + } + }, + "kitquelle" : { + "type" : "string", + "xml" : { + "name" : "Kitquelle" + } + }, + "bpkZp" : { + "type" : "string", + "xml" : { + "name" : "BpkZp" + } + }, + "sterbedatum" : { + "$ref" : "#/components/schemas/PartialDate" + }, + "geprueft" : { + "type" : "boolean", + "xml" : { + "name" : "Geprueft" + } + } + } + }, + "Reisedokument" : { + "required" : [ "art" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "ausgestelltVon" : { + "$ref" : "#/components/schemas/AusgestelltVon" + }, + "art" : { + "type" : "string", + "xml" : { + "name" : "Art" + }, + "enum" : [ "Asylwerber", "Dienstpass", "Elektronisch", "Fremdenpass", "Konventionspass", "Personalausweis", "Reisepass", "Staatenlos", "Sonstiges" ] + }, + "nummer" : { + "type" : "string", + "xml" : { + "name" : "Nummer" + } + } + } + }, + "SonstigesDokument" : { + "required" : [ "art", "nummer" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "ausgestelltVon" : { + "$ref" : "#/components/schemas/AusgestelltVon" + }, + "art" : { + "type" : "string", + "xml" : { + "name" : "Art" + }, + "enum" : [ "Führerschein", "Geburtsurkunde", "Heiratsurkunde", "Sonstiges", "Staatsbürgerschaftsnachweis", "Sterbeurkunde", "Todeserklärung" ] + }, + "lichtbildausweis" : { + "type" : "boolean", + "xml" : { + "name" : "Lichtbildausweis" + } + }, + "nummer" : { + "type" : "string", + "xml" : { + "name" : "Nummer" + } + }, + "name" : { + "type" : "string", + "xml" : { + "name" : "Name" + } + } + } + }, + "Staat" : { + "type" : "object", + "properties" : { + "isoCode3" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "name" : { + "type" : "string", + "xml" : { + "attribute" : true + } + } + } + }, + "Staatsangehoerigkeit" : { + "required" : [ "staat" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "staat" : { + "$ref" : "#/components/schemas/Staat" + } + } + }, + "ZmrPerson" : { + "required" : [ "letzteOperation", "personendaten", "qkz" ], + "type" : "object", + "allOf" : [ { + "$ref" : "#/components/schemas/Person" + }, { + "type" : "object", + "properties" : { + "auskunftssperre" : { + "type" : "boolean", + "xml" : { + "name" : "Auskunftssperre" + } + }, + "qkz" : { + "type" : "array", + "xml" : { + "name" : "Qkz" + }, + "items" : { + "type" : "string" + } + } + } + } ] + }, + "Aendern" : { + "type" : "object", + "properties" : { + "personendaten" : { + "$ref" : "#/components/schemas/Personendaten" + }, + "anschrift" : { + "$ref" : "#/components/schemas/Anschrift" + }, + "akademischerGrad" : { + "type" : "array", + "xml" : { + "name" : "AkademischerGrad" + }, + "items" : { + "$ref" : "#/components/schemas/AkademischerGrad" + } + }, + "reisedokument" : { + "type" : "array", + "xml" : { + "name" : "Reisedokument" + }, + "items" : { + "$ref" : "#/components/schemas/Reisedokument" + } + }, + "sonstigesDokument" : { + "type" : "array", + "xml" : { + "name" : "SonstigesDokument" + }, + "items" : { + "$ref" : "#/components/schemas/SonstigesDokument" + } + }, + "staatsangehoerigkeit" : { + "type" : "array", + "xml" : { + "name" : "Staatsangehoerigkeit" + }, + "items" : { + "$ref" : "#/components/schemas/Staatsangehoerigkeit" + } + }, + "eidas" : { + "type" : "array", + "xml" : { + "name" : "Eidas" + }, + "items" : { + "$ref" : "#/components/schemas/Eidas" + } + } + } + }, + "Anlegen" : { + "type" : "object", + "properties" : { + "anschrift" : { + "$ref" : "#/components/schemas/Anschrift" + }, + "akademischerGrad" : { + "type" : "array", + "xml" : { + "name" : "AkademischerGrad" + }, + "items" : { + "$ref" : "#/components/schemas/AkademischerGrad" + } + }, + "reisedokument" : { + "type" : "array", + "xml" : { + "name" : "Reisedokument" + }, + "items" : { + "$ref" : "#/components/schemas/Reisedokument" + } + }, + "sonstigesDokument" : { + "type" : "array", + "xml" : { + "name" : "SonstigesDokument" + }, + "items" : { + "$ref" : "#/components/schemas/SonstigesDokument" + } + }, + "staatsangehoerigkeit" : { + "type" : "array", + "xml" : { + "name" : "Staatsangehoerigkeit" + }, + "items" : { + "$ref" : "#/components/schemas/Staatsangehoerigkeit" + } + }, + "eidas" : { + "type" : "array", + "xml" : { + "name" : "Eidas" + }, + "items" : { + "$ref" : "#/components/schemas/Eidas" + } + } + } + }, + "Beenden" : { + "type" : "object", + "properties" : { + "entityId" : { + "type" : "array", + "xml" : { + "name" : "EntityId" + }, + "items" : { + "type" : "string", + "xml" : { + "name" : "EntityId" + } + } + } + } + }, + "PersonAendern" : { + "required" : [ "begruendung", "entityId", "version" ], + "type" : "object", + "properties" : { + "begruendung" : { + "type" : "string", + "xml" : { + "name" : "Begruendung" + } + }, + "anlegen" : { + "$ref" : "#/components/schemas/Anlegen" + }, + "aendern" : { + "$ref" : "#/components/schemas/Aendern" + }, + "beenden" : { + "$ref" : "#/components/schemas/Beenden" + }, + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "version" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + } + }, + "xml" : { + "name" : "PersonAendern" + } + }, + "Personendaten" : { + "required" : [ "familienname", "geburtsdatum", "vorname" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "familienname" : { + "type" : "string", + "xml" : { + "name" : "Familienname" + } + }, + "nameVorEhe" : { + "type" : "string", + "xml" : { + "name" : "NameVorEhe" + } + }, + "vorname" : { + "type" : "string", + "xml" : { + "name" : "Vorname" + } + }, + "geburtsbundesland" : { + "type" : "string", + "xml" : { + "name" : "Geburtsbundesland" + }, + "enum" : [ "Burgenland", "Kärnten", "Niederösterreich", "Oberösterreich", "Salzburg", "Steiermark", "Tirol", "Vorarlberg", "Wien" ] + }, + "geburtsort" : { + "type" : "string", + "xml" : { + "name" : "Geburtsort" + } + }, + "geburtsstaat" : { + "$ref" : "#/components/schemas/Staat" + }, + "geburtsdatum" : { + "$ref" : "#/components/schemas/PartialDate" + }, + "geschlecht" : { + "type" : "string", + "xml" : { + "name" : "Geschlecht" + }, + "enum" : [ "Männlich", "Weiblich" ] + } + } + }, + "AnlegenResponse" : { + "required" : [ "person" ], + "type" : "object", + "properties" : { + "person" : { + "$ref" : "#/components/schemas/Person" + } + }, + "xml" : { + "name" : "AnlegenResponse" + } + }, + "PersonAnlegen" : { + "required" : [ "anschrift", "begruendung", "personendaten" ], + "type" : "object", + "properties" : { + "begruendung" : { + "type" : "string", + "xml" : { + "name" : "Begruendung" + } + }, + "personendaten" : { + "$ref" : "#/components/schemas/Personendaten" + }, + "anschrift" : { + "$ref" : "#/components/schemas/Anschrift" + }, + "akademischerGrad" : { + "type" : "array", + "xml" : { + "name" : "AkademischerGrad" + }, + "items" : { + "$ref" : "#/components/schemas/AkademischerGrad" + } + }, + "reisedokument" : { + "type" : "array", + "xml" : { + "name" : "Reisedokument" + }, + "items" : { + "$ref" : "#/components/schemas/Reisedokument" + } + }, + "sonstigesDokument" : { + "type" : "array", + "xml" : { + "name" : "SonstigesDokument" + }, + "items" : { + "$ref" : "#/components/schemas/SonstigesDokument" + } + }, + "staatsangehoerigkeit" : { + "type" : "array", + "xml" : { + "name" : "Staatsangehoerigkeit" + }, + "items" : { + "$ref" : "#/components/schemas/Staatsangehoerigkeit" + } + }, + "eidas" : { + "type" : "array", + "xml" : { + "name" : "Eidas" + }, + "items" : { + "$ref" : "#/components/schemas/Eidas" + } + } + }, + "xml" : { + "name" : "PersonAnlegen" + } + }, + "SuchenResponse" : { + "type" : "object", + "properties" : { + "person" : { + "type" : "array", + "xml" : { + "name" : "Person" + }, + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "xml" : { + "name" : "SuchenResponse" + } + }, + "PersonSuchen" : { + "required" : [ "begruendung", "suchdaten", "suchoptionen" ], + "type" : "object", + "properties" : { + "begruendung" : { + "type" : "string", + "xml" : { + "name" : "Begruendung" + } + }, + "suchoptionen" : { + "$ref" : "#/components/schemas/Suchoptionen" + }, + "suchdaten" : { + "$ref" : "#/components/schemas/Suchdaten" + } + }, + "xml" : { + "name" : "PersonSuchen" + } + }, + "SuchAnschrift" : { + "type" : "object", + "properties" : { + "staat" : { + "$ref" : "#/components/schemas/Staat" + }, + "gemeinde" : { + "type" : "string", + "xml" : { + "name" : "Gemeinde" + } + }, + "strasse" : { + "type" : "string", + "xml" : { + "name" : "Strasse" + } + }, + "ort" : { + "type" : "string", + "xml" : { + "name" : "Ort" + } + }, + "postleitzahl" : { + "type" : "string", + "xml" : { + "name" : "Postleitzahl" + } + }, + "hausnummer" : { + "type" : "string", + "xml" : { + "name" : "Hausnummer" + } + }, + "adresszusatz" : { + "type" : "string", + "xml" : { + "name" : "Adresszusatz" + } + }, + "stiege" : { + "type" : "string", + "xml" : { + "name" : "Stiege" + } + }, + "tuer" : { + "type" : "string", + "xml" : { + "name" : "Tuer" + } + }, + "postfach" : { + "type" : "string", + "xml" : { + "name" : "Postfach" + } + } + } + }, + "SuchAusgestelltVon" : { + "type" : "object", + "properties" : { + "datum" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "name" : "Datum" + } + }, + "behoerde" : { + "type" : "string", + "xml" : { + "name" : "Behoerde" + } + }, + "staat" : { + "$ref" : "#/components/schemas/Staat" + } + } + }, + "SuchEidas" : { + "type" : "object", + "properties" : { + "art" : { + "type" : "string", + "xml" : { + "name" : "Art" + } + }, + "wert" : { + "type" : "string", + "xml" : { + "name" : "Wert" + } + }, + "ausstellDatum" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "name" : "AusstellDatum" + } + }, + "ablaufDatum" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "name" : "AblaufDatum" + } + }, + "ausstellBehoerde" : { + "type" : "string", + "xml" : { + "name" : "AusstellBehoerde" + } + }, + "staatscode2" : { + "type" : "string", + "xml" : { + "name" : "Staatscode2" + } + } + } + }, + "SuchReisedokument" : { + "type" : "object", + "properties" : { + "art" : { + "type" : "string", + "xml" : { + "name" : "Art" + }, + "enum" : [ "Asylwerber", "Dienstpass", "Elektronisch", "Fremdenpass", "Konventionspass", "Personalausweis", "Reisepass", "Staatenlos", "Sonstiges" ] + }, + "ausgestelltVon" : { + "$ref" : "#/components/schemas/SuchAusgestelltVon" + }, + "nummer" : { + "type" : "string", + "xml" : { + "name" : "Nummer" + } + } + } + }, + "SuchStaatsangehoerigkeit" : { + "type" : "object", + "properties" : { + "staat" : { + "$ref" : "#/components/schemas/Staat" + } + } + }, + "Suchdaten" : { + "required" : [ "familienname", "vorname" ], + "type" : "object", + "properties" : { + "basiszahl" : { + "type" : "string", + "xml" : { + "name" : "Basiszahl" + } + }, + "bpkZp" : { + "type" : "string", + "xml" : { + "name" : "BpkZp" + } + }, + "fremdBpkBmiZp" : { + "type" : "string", + "xml" : { + "name" : "FremdBpkBmiZp" + } + }, + "entityId" : { + "type" : "string", + "xml" : { + "name" : "EntityId" + } + }, + "familienname" : { + "type" : "string", + "xml" : { + "name" : "Familienname" + } + }, + "nameVorEhe" : { + "type" : "string", + "xml" : { + "name" : "NameVorEhe" + } + }, + "vorname" : { + "type" : "string", + "xml" : { + "name" : "Vorname" + } + }, + "geburtsdatum" : { + "$ref" : "#/components/schemas/PartialDate" + }, + "geburtsort" : { + "type" : "string", + "xml" : { + "name" : "Geburtsort" + } + }, + "geburtsstaat" : { + "$ref" : "#/components/schemas/Staat" + }, + "geschlecht" : { + "type" : "string", + "xml" : { + "name" : "Geschlecht" + }, + "enum" : [ "Männlich", "Weiblich" ] + }, + "anschrift" : { + "$ref" : "#/components/schemas/SuchAnschrift" + }, + "reisedokument" : { + "$ref" : "#/components/schemas/SuchReisedokument" + }, + "staatsangehoerigkeit" : { + "$ref" : "#/components/schemas/SuchStaatsangehoerigkeit" + }, + "eidas" : { + "type" : "array", + "xml" : { + "name" : "Eidas" + }, + "items" : { + "$ref" : "#/components/schemas/SuchEidas" + } + } + } + }, + "Suchoptionen" : { + "required" : [ "historisch" ], + "type" : "object", + "properties" : { + "historisch" : { + "type" : "string", + "xml" : { + "name" : "Historisch" + }, + "enum" : [ "Aktuell", "AktuellDannHistorisch", "AktuellUndHistorisch" ] + }, + "formalisiert" : { + "type" : "boolean", + "xml" : { + "name" : "Formalisiert" + } + }, + "sucheMitNamensteilen" : { + "type" : "boolean", + "xml" : { + "name" : "SucheMitNamensteilen" + } + }, + "suchwizard" : { + "type" : "boolean", + "xml" : { + "name" : "Suchwizard" + } + }, + "zmr" : { + "type" : "boolean", + "xml" : { + "name" : "Zmr" + } + } + }, + "xml" : { + "name" : "Suchoptionen", + "namespace" : "http://bmi.gv.at/ernp" + } + } + } + } +}
\ No newline at end of file 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..66a426a1 --- /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,460 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.clients; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.junit.Ignore; +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 at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.DeSpecificDetailSearchProcessor; +import at.gv.bmi.namespace.zmr_su.zmr._20040201.PersonSuchenRequest; +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 { + + //private static final String TEST_PREFIX = "XXX_"; + private static final String TEST_PREFIX = ""; + + @Autowired IErnpClient client; + + @Test + @SneakyThrows + public void searchWithPersonalIdentifierServerError() { + String personalIdentifierFirst = "7cEYWithDEElementsasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit"; + personalIdentifierFirst = ""; + final String cc = "DE"; + final SimpleEidasData eidasDataFirst = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName("XXXvon Brandenburg") + .givenName("XXXClaus - Maria") + .dateOfBirth("1994-12-00") + .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 = "CZ"; + final SimpleEidasData eidasDataFirst = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName("DOPISNÍ") + .givenName("DANA") + .dateOfBirth("1996-01-01") + .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()); + checkErnpResult(resp.getPersonResult().get(0), eidasDataFirst, 1); + assertEquals("wrong bpk", "vypyCkyczK7i+cgPWlJasuJphIA=", + resp.getPersonResult().get(0).getBpk()); + + } + + @Test + @SneakyThrows + public void searchWithPersonalIdentifierNoResult() { + final String personalIdentifierFirst = RandomStringUtils.randomAlphanumeric(10); + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName("DOPISNÍ") + .givenName("DANA") + .dateOfBirth("1996-01-01") + .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", 0, resp.getPersonResult().size()); + + } + + + @Test + @SneakyThrows + public void searchWithMdsSuccess() { + final String personalIdentifierFirst = "7cEYWithDEElementsasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit"; + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName("DOPISNÍ") + .givenName("DANA") + .dateOfBirth("1996-01-01") + .personalIdentifier(cc + "/AT/" + personalIdentifierFirst) + .pseudonym(personalIdentifierFirst) + .build(); + + // execute operation + ErnpRegisterResult resp = client.searchWithMds(eidasDataFirst.getGivenName(), eidasDataFirst.getFamilyName(), + eidasDataFirst.getDateOfBirth(), eidasDataFirst.getCitizenCountryCode()); + + // validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + checkErnpResult(resp.getPersonResult().get(0), eidasDataFirst, 1); + assertEquals("wrong bpk", "vypyCkyczK7i+cgPWlJasuJphIA=", + resp.getPersonResult().get(0).getBpk()); + + } + + @Test + @SneakyThrows + public void searchWithMdsNoResult() { + final String personalIdentifierFirst = RandomStringUtils.randomAlphanumeric(10); + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName(RandomStringUtils.randomAlphanumeric(10)) + .givenName(RandomStringUtils.randomAlphanumeric(10)) + .dateOfBirth("1996-10-15") + .personalIdentifier(cc + "/AT/" + personalIdentifierFirst) + .pseudonym(personalIdentifierFirst) + .build(); + + // execute operation + ErnpRegisterResult resp = client.searchWithMds(eidasDataFirst.getGivenName(), eidasDataFirst.getFamilyName(), + eidasDataFirst.getDateOfBirth(), eidasDataFirst.getCitizenCountryCode()); + + // validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 0, resp.getPersonResult().size()); + + } + + @Test + @SneakyThrows + public void addTwiceSameMdsAndMdsSearch() { + // *** add new random first person *** + final String addFirstPersonPersonalIdentifier = RandomStringUtils.randomAlphanumeric(10); + final String cc = "XZ"; + final SimpleEidasData addFirstPersonData = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName(TEST_PREFIX + RandomStringUtils.randomAlphabetic(8)) + .givenName(TEST_PREFIX + RandomStringUtils.randomAlphabetic(8)) + .dateOfBirth("1996-01-01") + .personalIdentifier(cc + "/AT/" + addFirstPersonPersonalIdentifier) + .pseudonym(addFirstPersonPersonalIdentifier) + .build(); + + // add entry + ErnpRegisterResult addFirstPersonResponse = client.add(addFirstPersonData); + + // verify added entry + assertNotNull("no ERnP response", addFirstPersonResponse); + assertEquals("wrong resp size", 1, addFirstPersonResponse.getPersonResult().size()); + checkErnpResult(addFirstPersonResponse.getPersonResult().get(0), addFirstPersonData, 1); + + + // *** add new random second person with same MDS *** + final String addSecondPersonPersonalIdentifier = RandomStringUtils.randomAlphanumeric(10); + final SimpleEidasData addSecondPersonData = addFirstPersonData.toBuilder() + .personalIdentifier(cc + "/AT/" + addSecondPersonPersonalIdentifier) + .pseudonym(addSecondPersonPersonalIdentifier) + .build(); + + // add entry + ErnpRegisterResult addSecondPersonResponse = client.add(addSecondPersonData); + + // verify added entry + assertNotNull("no ERnP response", addSecondPersonResponse); + assertEquals("wrong resp size", 1, addSecondPersonResponse.getPersonResult().size()); + checkErnpResult(addSecondPersonResponse.getPersonResult().get(0), addSecondPersonData, 1); + + + + // search with MDS + ErnpRegisterResult resp = client.searchWithMds(addFirstPersonData.getGivenName(), addFirstPersonData.getFamilyName(), + addFirstPersonData.getDateOfBirth(), cc); + + // validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 2, resp.getPersonResult().size()); + + } + + + + @Test + @SneakyThrows + public void addSearchAndPersonalIdUpdate() { + // *** add new random entry *** + + final String addPersonPersonalIdentifier = RandomStringUtils.randomAlphanumeric(10); + final String cc = "DE"; + final SimpleEidasData addPersonData = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName(TEST_PREFIX + RandomStringUtils.randomAlphabetic(8)) + .givenName(TEST_PREFIX + RandomStringUtils.randomAlphabetic(8)) + .dateOfBirth("1996-01-01") + .personalIdentifier(cc + "/AT/" + addPersonPersonalIdentifier) + .pseudonym(addPersonPersonalIdentifier) + .birthName(RandomStringUtils.randomAlphabetic(8)) + .placeOfBirth(RandomStringUtils.randomAlphabetic(8)) + .build(); + + // add entry + ErnpRegisterResult addPersonResponse = client.add(addPersonData); + + // verify added entry + assertNotNull("no ERnP response", addPersonResponse); + assertEquals("wrong resp size", 1, addPersonResponse.getPersonResult().size()); + checkErnpResult(addPersonResponse.getPersonResult().get(0), addPersonData, 1); + + + // *** search entry by countrySpecifics *** + final String ccPersonPersonalIdentifier = RandomStringUtils.randomAlphanumeric(10); + SimpleEidasData ccSpecificData = addPersonData.toBuilder() + .personalIdentifier(cc + "/AT/" + ccPersonPersonalIdentifier) + .pseudonym(ccPersonPersonalIdentifier) + .build(); + PersonSuchenRequest ccSearchReq = + new DeSpecificDetailSearchProcessor().generateSearchRequest(ccSpecificData); + + // search CC specific + ErnpRegisterResult ccSearchResponse = client.searchCountrySpecific(ccSearchReq, cc); + + // verify cc specific result + assertNotNull("no ERnP response", ccSearchResponse); + assertEquals("wrong resp size", 1, ccSearchResponse.getPersonResult().size()); + RegisterResult ccSearchPersResult = ccSearchResponse.getPersonResult().get(0); + checkErnpResult(ccSearchResponse.getPersonResult().get(0), addPersonData, 1); + assertEquals("wrong bPK", addPersonResponse.getPersonResult().get(0).getBpk(), + ccSearchPersResult.getBpk()); + assertFalse("no PersonalId change detected", ccSpecificData.equalsRegisterData(ccSearchPersResult)); + + + // *** update entry because PersonalId has changed *** + // update ERnP entry + ErnpRegisterResult updateResponse = client.update(ccSearchPersResult, ccSpecificData); + assertNotNull("no ERnP response", updateResponse); + assertEquals("wrong resp size", 1, updateResponse.getPersonResult().size()); + checkErnpResult(updateResponse.getPersonResult().get(0), addPersonData, 2); + assertEquals("wrong bPK", addPersonResponse.getPersonResult().get(0).getBpk(), ccSearchPersResult.getBpk()); + checkPersonalIdentifier(updateResponse.getPersonResult().get(0), addPersonPersonalIdentifier); + checkPersonalIdentifier(updateResponse.getPersonResult().get(0), ccPersonPersonalIdentifier); + + + + // *** search by first personalIdentifier + ErnpRegisterResult persIdSearchFirstResp = client.searchWithPersonIdentifier( + addPersonPersonalIdentifier, cc); + assertNotNull("no ERnP response", persIdSearchFirstResp); + assertEquals("wrong resp size", 1, persIdSearchFirstResp.getPersonResult().size()); + assertEquals("wrong bPK", addPersonResponse.getPersonResult().get(0).getBpk(), ccSearchPersResult.getBpk()); + checkPersonalIdentifier(updateResponse.getPersonResult().get(0), addPersonPersonalIdentifier); + checkPersonalIdentifier(updateResponse.getPersonResult().get(0), ccPersonPersonalIdentifier); + checkErnpResult(updateResponse.getPersonResult().get(0), addPersonData, 2); + + + + // *** search by second personalIdentifier + ErnpRegisterResult persIdSearchSecondResp = client.searchWithPersonIdentifier( + ccPersonPersonalIdentifier, cc); + assertNotNull("no ERnP response", persIdSearchSecondResp); + assertEquals("wrong resp size", 1, persIdSearchSecondResp.getPersonResult().size()); + assertEquals("wrong bPK", addPersonResponse.getPersonResult().get(0).getBpk(), ccSearchPersResult.getBpk()); + checkPersonalIdentifier(updateResponse.getPersonResult().get(0), addPersonPersonalIdentifier); + checkPersonalIdentifier(updateResponse.getPersonResult().get(0), ccPersonPersonalIdentifier); + checkErnpResult(updateResponse.getPersonResult().get(0), addPersonData, 2); + + } + + @Test + @SneakyThrows + public void addSearchAndMdsUpdate() { + // *** add new random entry *** + + final String addPersonPersonalIdentifier = RandomStringUtils.randomAlphanumeric(10); + final String cc = "DE"; + final SimpleEidasData addPersonData = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName(TEST_PREFIX + RandomStringUtils.randomAlphabetic(8)) + .givenName(TEST_PREFIX + RandomStringUtils.randomAlphabetic(8)) + .dateOfBirth("1985-05-05") + .personalIdentifier(cc + "/AT/" + addPersonPersonalIdentifier) + .pseudonym(addPersonPersonalIdentifier) + .birthName(RandomStringUtils.randomAlphabetic(8)) + .placeOfBirth(RandomStringUtils.randomAlphabetic(8)) + .build(); + + // add entry + ErnpRegisterResult addPersonResponse = client.add(addPersonData); + + // verify added entry + assertNotNull("no ERnP response", addPersonResponse); + assertEquals("wrong resp size", 1, addPersonResponse.getPersonResult().size()); + checkErnpResult(addPersonResponse.getPersonResult().get(0), addPersonData, 1); + + + // *** search entry by personalId *** + SimpleEidasData mdsHasChanged = addPersonData.toBuilder() + .givenName(RandomStringUtils.randomAlphanumeric(10)) + .familyName(RandomStringUtils.randomAlphanumeric(10)) + .build(); + + // search by personalId + ErnpRegisterResult personalIdResponse = client.searchWithPersonIdentifier(addPersonPersonalIdentifier, cc); + + // verify personalId result + assertNotNull("no ERnP response", personalIdResponse); + assertEquals("wrong resp size", 1, personalIdResponse.getPersonResult().size()); + RegisterResult persIdSearchResult = personalIdResponse.getPersonResult().get(0); + checkErnpResult(personalIdResponse.getPersonResult().get(0), addPersonData, 1); + assertEquals("wrong bPK", addPersonResponse.getPersonResult().get(0).getBpk(), + persIdSearchResult.getBpk()); + assertFalse("no MDS change detected", mdsHasChanged.equalsRegisterData(persIdSearchResult)); + + + // *** update entry because MDS has changed *** + // update ERnP entry + ErnpRegisterResult updateResponse = client.update(persIdSearchResult, mdsHasChanged); + assertNotNull("no ERnP response", updateResponse); + assertEquals("wrong resp size", 1, updateResponse.getPersonResult().size()); + checkErnpResult(updateResponse.getPersonResult().get(0), mdsHasChanged, 1); + assertEquals("wrong bPK", addPersonResponse.getPersonResult().get(0).getBpk(), persIdSearchResult.getBpk()); + checkPersonalIdentifier(updateResponse.getPersonResult().get(0), addPersonPersonalIdentifier); + + + // *** search by first personalIdentifier + ErnpRegisterResult persIdSearchFirstResp = client.searchWithPersonIdentifier( + addPersonPersonalIdentifier, cc); + assertNotNull("no ERnP response", persIdSearchFirstResp); + assertEquals("wrong resp size", 1, persIdSearchFirstResp.getPersonResult().size()); + assertEquals("wrong bPK", addPersonResponse.getPersonResult().get(0).getBpk(), persIdSearchResult.getBpk()); + checkPersonalIdentifier(updateResponse.getPersonResult().get(0), addPersonPersonalIdentifier); + checkErnpResult(updateResponse.getPersonResult().get(0), mdsHasChanged, 1); + + // *** search by first personalIdentifier + ErnpRegisterResult mdsSearchResp = client.searchWithMds( + mdsHasChanged.getGivenName(), mdsHasChanged.getFamilyName(), mdsHasChanged.getDateOfBirth(), cc); + assertNotNull("no ERnP response", mdsSearchResp); + assertEquals("wrong resp size", 1, mdsSearchResp.getPersonResult().size()); + assertEquals("wrong bPK", addPersonResponse.getPersonResult().get(0).getBpk(), persIdSearchResult.getBpk()); + checkPersonalIdentifier(updateResponse.getPersonResult().get(0), addPersonPersonalIdentifier); + checkErnpResult(updateResponse.getPersonResult().get(0), mdsHasChanged, 1); + + + + } + + + @Ignore + @Test + @SneakyThrows + public void addErnpEntry() { + final String personalIdentifierFirst = "7cEYWithDEElementsasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit"; + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName("DOPISNÍ") + .givenName("DANA") + .dateOfBirth("1996-01-01") + .personalIdentifier(cc + "/AT/" + personalIdentifierFirst) + .pseudonym(personalIdentifierFirst) + .build(); + + // execute operation + ErnpRegisterResult resp = client.add(eidasDataFirst); + + // validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + checkErnpResult(resp.getPersonResult().get(0), eidasDataFirst, 1); + + } + + @Test + @SneakyThrows + public void addRandomErnpEntry() { + final String addPersonPersonalIdentifier = RandomStringUtils.randomAlphanumeric(10); + final String cc = "XZ"; + final SimpleEidasData addPersonData = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName(TEST_PREFIX + RandomStringUtils.randomAlphabetic(8)) + .givenName(TEST_PREFIX + RandomStringUtils.randomAlphabetic(8)) + .dateOfBirth("1985-05-05") + .personalIdentifier(cc + "/AT/" + addPersonPersonalIdentifier) + .pseudonym(addPersonPersonalIdentifier) + .birthName(RandomStringUtils.randomAlphabetic(8)) + .placeOfBirth(RandomStringUtils.randomAlphabetic(8)) + .build(); + + // add entry + ErnpRegisterResult addPersonResponse = client.add(addPersonData); + + // verify added entry + assertNotNull("no ERnP response", addPersonResponse); + assertEquals("wrong resp size", 1, addPersonResponse.getPersonResult().size()); + checkErnpResult(addPersonResponse.getPersonResult().get(0), addPersonData, 1); + + } + + + private void checkErnpResult(RegisterResult registerResult, final SimpleEidasData eidasData, int numOfPseudonyms) { + assertEquals("wrong familyname", eidasData.getFamilyName(), registerResult.getFamilyName()); + assertEquals("wrong givenname", eidasData.getGivenName(), registerResult.getGivenName()); + assertEquals("wrong birthday", eidasData.getDateOfBirth(), registerResult.getDateOfBirth()); + assertEquals("wrong personalId size", numOfPseudonyms, registerResult.getPseudonym().size()); + assertEquals("wrong placeOfBirth", eidasData.getPlaceOfBirth(), registerResult.getPlaceOfBirth()); + assertEquals("wrong birthName", eidasData.getBirthName(), registerResult.getBirthName()); + assertTrue("no bPK", StringUtils.isNotEmpty(registerResult.getBpk())); + checkPersonalIdentifier(registerResult, eidasData.getPseudonym()); + + } + + private void checkPersonalIdentifier(RegisterResult registerResult, String pseudonym) { + assertTrue("wrong or no personalId", registerResult.getPseudonym().stream() + .filter(el -> pseudonym.equals(el)) + .findFirst() + .isPresent()); + + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ErnpRestClientTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ErnpRestClientTest.java new file mode 100644 index 00000000..ab1a502c --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ErnpRestClientTest.java @@ -0,0 +1,1085 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.clients; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import java.net.HttpURLConnection; +import java.util.Arrays; +import java.util.Iterator; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +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 com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummyConfigMap; +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 at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.DeSpecificDetailSearchProcessor; +import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils; +import lombok.SneakyThrows; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import okhttp3.mockwebserver.SocketPolicy; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { + "/SpringTest-context_tasks_test.xml", + "/SpringTest-context_basic_mapConfig.xml" }) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +public class ErnpRestClientTest { + + @Autowired MsConnectorDummyConfigMap basicConfig; + @Autowired IErnpClient client; + + private static ObjectMapper mapper = new ObjectMapper(); + private static MockWebServer mockWebServer; + + /** + * JUnit class initializer. + * + * @throws Exception In case of an OpenSAML3 initialization error + */ + @BeforeClass + @SneakyThrows + public static void classInitializer() { + mockWebServer = new MockWebServer(); + mockWebServer.start(1718); + + } + + @AfterClass + @SneakyThrows + public static void resetTestEnviroment() { + mockWebServer.shutdown(); + + } + + /** + * jUnit test initializer. + * + * @throws InterruptedException in case of an error + */ + @Before + public void initialize() throws InterruptedException { + mockWebServer.takeRequest(2, TimeUnit.MILLISECONDS); + TransactionIdUtils.setTransactionId(UUID.randomUUID().toString()); + + } + + + @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(); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(500) + .setBody("Internal error")); + + // execute operation + EidasSAuthenticationException error = assertThrows("wrong Exception", EidasSAuthenticationException.class, + () -> client.searchWithPersonIdentifier( + eidasDataFirst.getPseudonym(), eidasDataFirst.getCitizenCountryCode())); + + mockWebServer.takeRequest(); + 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(); + + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/ernp_handbook_example.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + + // execute operation + ErnpRegisterResult resp = client.searchWithPersonIdentifier( + eidasDataFirst.getPseudonym(), eidasDataFirst.getCitizenCountryCode()); + + // validate request + final RecordedRequest request = mockWebServer.takeRequest(); + String reqBody = request.getBody().readUtf8(); + assertFalse("no request body", reqBody.isEmpty()); + + // validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + + + } + + @Test + @SneakyThrows + public void searchResidence() { + // execute operation + ErnpRegisterResult resp = client.searchWithResidenceData(null, null, null, null, null, null); + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 0, resp.getPersonResult().size()); + + } + + @Test + @SneakyThrows + public void searchWithMdsNoResponse() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + mockWebServer.enqueue(new MockResponse() + .setSocketPolicy(SocketPolicy.NO_RESPONSE) + .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); + + // execute operation + EidasSAuthenticationException error = assertThrows("wrong Exception", EidasSAuthenticationException.class, + () -> client.searchWithMds(eidasDataFirst.getGivenName(), eidasDataFirst.getFamilyName(), eidasDataFirst.getDateOfBirth(), cc)); + assertEquals("wrong errorCode", "module.eidasauth.matching.11", error.getErrorId()); + mockWebServer.takeRequest(); + + + } + + @Test + @SneakyThrows + public void searchWithMdsErrorResponse() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(400) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/error_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + EidasSAuthenticationException error = assertThrows("wrong Exception", EidasSAuthenticationException.class, + () -> client.searchWithMds(eidasDataFirst.getGivenName(), eidasDataFirst.getFamilyName(), eidasDataFirst.getDateOfBirth(), cc)); + assertEquals("wrong errorCode", "module.eidasauth.matching.11", error.getErrorId()); + mockWebServer.takeRequest(); + + } + + @Test + @SneakyThrows + public void searchWithMdsNoResult() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/ernp_empty_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + ErnpRegisterResult resp = client.searchWithMds(eidasDataFirst.getGivenName(), eidasDataFirst.getFamilyName(), eidasDataFirst.getDateOfBirth(), cc); + + // validate request + final RecordedRequest request = mockWebServer.takeRequest(); + String reqBody = request.getBody().readUtf8(); + assertFalse("no request body", reqBody.isEmpty()); + JsonNode reqJson = mapper.readTree(reqBody); + checkSearchOptions(reqJson, "Searching with MDS only"); + JsonNode person = getJsonObject(reqJson, "suchdaten"); + checkJsonElement(person, "familienname", eidasDataFirst.getFamilyName()); + checkJsonElement(person, "vorname", eidasDataFirst.getGivenName()); + checkPersonDateOfBirth(person, eidasDataFirst.getDateOfBirth()); + + // validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 0, resp.getPersonResult().size()); + + } + + @Test + @SneakyThrows + public void searchWithMdsSingleResult() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/3_search_with_mds_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + ErnpRegisterResult resp = client.searchWithMds(eidasDataFirst.getGivenName(), eidasDataFirst.getFamilyName(), eidasDataFirst.getDateOfBirth(), cc); + + // validate state + mockWebServer.takeRequest(); + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + RegisterResult persInfo = resp.getPersonResult().get(0); + assertEquals("wrong familyname", "DOPISNÍ", persInfo.getFamilyName()); + assertEquals("wrong givenName", "DANA", persInfo.getGivenName()); + assertEquals("wrong dateOfBirth", "1996-01-01", persInfo.getDateOfBirth()); + assertEquals("wrong bpk", "vypyCkyczK7i+cgPWlJasuJphIA=", persInfo.getBpk()); + assertEquals("wrong pseudonym", "7cEYWithDEElementsasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit", persInfo.getPseudonym().get(0)); + assertNull("placeOfBirth", persInfo.getPlaceOfBirth()); + assertNull("birthName", persInfo.getBirthName()); + + } + + @Test + @SneakyThrows + public void searchWithMdsMultiResult() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/4_search_with_mds_multi_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + ErnpRegisterResult resp = client.searchWithMds(eidasDataFirst.getGivenName(), eidasDataFirst.getFamilyName(), eidasDataFirst.getDateOfBirth(), cc); + + // validate state + mockWebServer.takeRequest(); + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 2, resp.getPersonResult().size()); + + } + + + @Test + @SneakyThrows + public void searchWithPersonalIdNoResponse() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + mockWebServer.enqueue(new MockResponse() + .setSocketPolicy(SocketPolicy.NO_RESPONSE) + .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); + + // execute operation + EidasSAuthenticationException error = assertThrows("wrong Exception", EidasSAuthenticationException.class, + () -> client.searchWithPersonIdentifier(eidasDataFirst.getPseudonym(), cc)); + assertEquals("wrong errorCode", "module.eidasauth.matching.11", error.getErrorId()); + mockWebServer.takeRequest(); + + } + + @Test + @SneakyThrows + public void searchWithPersonalIdErrorResponse() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(400) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/error_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + EidasSAuthenticationException error = assertThrows("wrong Exception", EidasSAuthenticationException.class, + () -> client.searchWithPersonIdentifier(eidasDataFirst.getPseudonym(), cc)); + assertEquals("wrong errorCode", "module.eidasauth.matching.11", error.getErrorId()); + mockWebServer.takeRequest(); + + } + + @Test + @SneakyThrows + public void searchWithPersonalIdNoResult() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/ernp_empty_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + ErnpRegisterResult resp = client.searchWithPersonIdentifier(eidasDataFirst.getPseudonym(), cc); + + // validate request + final RecordedRequest request = mockWebServer.takeRequest(); + String reqBody = request.getBody().readUtf8(); + assertFalse("no request body", reqBody.isEmpty()); + JsonNode reqJson = mapper.readTree(reqBody); + checkSearchOptions(reqJson, "Searching PersonIdentifier"); + JsonNode person = getJsonObject(reqJson, "suchdaten"); + checkEidasDocument(person, "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", cc, eidasDataFirst.getPseudonym()); + + // validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 0, resp.getPersonResult().size()); + + } + + @Test + @SneakyThrows + public void searchWithPersonalIdSingleResult() { + final String cc = "DE"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/1_search_with_personalId_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + ErnpRegisterResult resp = client.searchWithPersonIdentifier(eidasDataFirst.getPseudonym(), cc); + + // validate state + mockWebServer.takeRequest(); + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + RegisterResult persInfo = resp.getPersonResult().get(0); + assertEquals("wrong familyname", "CtKKrtUe", persInfo.getFamilyName()); + assertEquals("wrong givenName", "dUeYzUFg", persInfo.getGivenName()); + assertEquals("wrong dateOfBirth", "1985-05-05", persInfo.getDateOfBirth()); + assertEquals("wrong bpk", "+OQnljn0Son1W2rkM73nP/VMsvc=", persInfo.getBpk()); + assertEquals("wrong pseudonym", "Y8ADWaeh0h", persInfo.getPseudonym().get(0)); + assertEquals("wrong placeOfBirth", "hrFevCfP", persInfo.getPlaceOfBirth()); + assertEquals("wrong birthName", "sNUEAhEr", persInfo.getBirthName()); + + } + + @Test + @SneakyThrows + public void searchWithPersonalIdSingleResultCountryNoMatch() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/1_search_with_personalId_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + ErnpRegisterResult resp = client.searchWithPersonIdentifier(eidasDataFirst.getPseudonym(), cc); + + // validate state + mockWebServer.takeRequest(); + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + RegisterResult persInfo = resp.getPersonResult().get(0); + assertEquals("wrong familyname", "CtKKrtUe", persInfo.getFamilyName()); + assertEquals("wrong givenName", "dUeYzUFg", persInfo.getGivenName()); + assertEquals("wrong dateOfBirth", "1985-05-05", persInfo.getDateOfBirth()); + assertEquals("wrong bpk", "+OQnljn0Son1W2rkM73nP/VMsvc=", persInfo.getBpk()); + assertTrue("pseudonym", persInfo.getPseudonym().isEmpty()); + assertNull("placeOfBirth", persInfo.getPlaceOfBirth()); + assertNull("birthName", persInfo.getBirthName()); + + } + + + @Test + @SneakyThrows + public void searchWithPersonalIdMultiResult() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/4_search_with_mds_multi_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + EidasSAuthenticationException error = assertThrows("wrong Exception", EidasSAuthenticationException.class, + () -> client.searchWithPersonIdentifier(eidasDataFirst.getPseudonym(), cc)); + assertEquals("wrong errorCode", "module.eidasauth.matching.03", error.getErrorId()); + mockWebServer.takeRequest(); + + } + + + @Test + @SneakyThrows + public void searchWithCcspecificsNoResponse() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + mockWebServer.enqueue(new MockResponse() + .setSocketPolicy(SocketPolicy.NO_RESPONSE) + .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); + + // execute operation + EidasSAuthenticationException error = assertThrows("wrong Exception", EidasSAuthenticationException.class, + () -> client.searchCountrySpecific(new DeSpecificDetailSearchProcessor().generateSearchRequest(eidasDataFirst), cc)); + assertEquals("wrong errorCode", "module.eidasauth.matching.11", error.getErrorId()); + mockWebServer.takeRequest(); + + } + + @Test + @SneakyThrows + public void searchWithCcspecificsErrorResponse() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(400) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/error_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + EidasSAuthenticationException error = assertThrows("wrong Exception", EidasSAuthenticationException.class, + () -> client.searchCountrySpecific(new DeSpecificDetailSearchProcessor().generateSearchRequest(eidasDataFirst), cc)); + assertEquals("wrong errorCode", "module.eidasauth.matching.11", error.getErrorId()); + mockWebServer.takeRequest(); + + } + + @Test + @SneakyThrows + public void searchWithCcspecificsNoResult() { + final String cc = "DE"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc).toBuilder() + .birthName(RandomStringUtils.randomAlphabetic(5)) + .placeOfBirth(RandomStringUtils.randomAlphabetic(5)) + .build(); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/ernp_empty_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + ErnpRegisterResult resp = client.searchCountrySpecific( + new DeSpecificDetailSearchProcessor().generateSearchRequest(eidasDataFirst), cc); + + // validate request + final RecordedRequest request = mockWebServer.takeRequest(); + String reqBody = request.getBody().readUtf8(); + assertFalse("no request body", reqBody.isEmpty()); + JsonNode reqJson = mapper.readTree(reqBody); + checkSearchOptions(reqJson, "Searching DE specific"); + JsonNode person = getJsonObject(reqJson, "suchdaten"); + checkJsonElement(person, "familienname", eidasDataFirst.getFamilyName()); + checkJsonElement(person, "vorname", eidasDataFirst.getGivenName()); + checkPersonDateOfBirth(person, eidasDataFirst.getDateOfBirth()); + checkEidasDocument(person, "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", cc, eidasDataFirst.getPlaceOfBirth()); + checkEidasDocument(person, "http://eidas.europa.eu/attributes/naturalperson/BirthName", cc, eidasDataFirst.getBirthName()); + + // validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 0, resp.getPersonResult().size()); + + } + + @Test + @SneakyThrows + public void searchWithCcspecificsSingleResult() { + final String cc = "DE"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/1_search_with_personalId_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + ErnpRegisterResult resp = client.searchCountrySpecific( + new DeSpecificDetailSearchProcessor().generateSearchRequest(eidasDataFirst), cc); + + // validate state + mockWebServer.takeRequest(); + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + RegisterResult persInfo = resp.getPersonResult().get(0); + assertEquals("wrong familyname", "CtKKrtUe", persInfo.getFamilyName()); + assertEquals("wrong givenName", "dUeYzUFg", persInfo.getGivenName()); + assertEquals("wrong dateOfBirth", "1985-05-05", persInfo.getDateOfBirth()); + assertEquals("wrong bpk", "+OQnljn0Son1W2rkM73nP/VMsvc=", persInfo.getBpk()); + assertEquals("wrong pseudonym", "Y8ADWaeh0h", persInfo.getPseudonym().get(0)); + assertEquals("wrong placeOfBirth", "hrFevCfP", persInfo.getPlaceOfBirth()); + assertEquals("wrong birthName", "sNUEAhEr", persInfo.getBirthName()); + + } + + @Test + @SneakyThrows + public void searchWithCcspecificsSingleResultCountryNoMatch() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/1_search_with_personalId_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + ErnpRegisterResult resp = client.searchCountrySpecific( + new DeSpecificDetailSearchProcessor().generateSearchRequest(eidasDataFirst), cc); + + // validate state + mockWebServer.takeRequest(); + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + RegisterResult persInfo = resp.getPersonResult().get(0); + assertEquals("wrong familyname", "CtKKrtUe", persInfo.getFamilyName()); + assertEquals("wrong givenName", "dUeYzUFg", persInfo.getGivenName()); + assertEquals("wrong dateOfBirth", "1985-05-05", persInfo.getDateOfBirth()); + assertEquals("wrong bpk", "+OQnljn0Son1W2rkM73nP/VMsvc=", persInfo.getBpk()); + assertTrue("pseudonym", persInfo.getPseudonym().isEmpty()); + assertNull("placeOfBirth", persInfo.getPlaceOfBirth()); + assertNull("birthName", persInfo.getBirthName()); + + } + + + @Test + @SneakyThrows + public void searchWithCcspecificsMultiResult() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/4_search_with_mds_multi_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + EidasSAuthenticationException error = assertThrows("wrong Exception", EidasSAuthenticationException.class, + () -> client.searchCountrySpecific(new DeSpecificDetailSearchProcessor().generateSearchRequest(eidasDataFirst), cc)); + assertEquals("wrong errorCode", "module.eidasauth.matching.03", error.getErrorId()); + mockWebServer.takeRequest(); + + } + + + @Test + @SneakyThrows + public void addPersonNoResponse() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + mockWebServer.enqueue(new MockResponse() + .setSocketPolicy(SocketPolicy.NO_RESPONSE) + .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)); + + // execute operation + EidasSAuthenticationException error = assertThrows("wrong Exception", EidasSAuthenticationException.class, + () -> client.add(eidasDataFirst)); + assertEquals("wrong errorCode", "module.eidasauth.matching.11", error.getErrorId()); + mockWebServer.takeRequest(); + + } + + @Test + @SneakyThrows + public void addPersonSimpleSuccess() { + final String cc = "CZ"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/2_add_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + // execute operation + ErnpRegisterResult resp = client.add(eidasDataFirst); + + // validate request + final RecordedRequest request = mockWebServer.takeRequest(); + String reqBody = request.getBody().readUtf8(); + assertFalse("no request body", reqBody.isEmpty()); + JsonNode reqJson = mapper.readTree(reqBody); + checkJsonElement(reqJson, "begruendung", "Add new person"); + JsonNode person = getJsonObject(reqJson, "personendaten"); + checkJsonElement(person, "familienname", eidasDataFirst.getFamilyName()); + checkJsonElement(person, "vorname", eidasDataFirst.getGivenName()); + checkPersonDateOfBirth(person, eidasDataFirst.getDateOfBirth()); + checkEidasDocument(reqJson, "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", cc, eidasDataFirst.getPseudonym()); + checkEidasDocument(reqJson, "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", cc); + checkEidasDocument(reqJson, "http://eidas.europa.eu/attributes/naturalperson/BirthName", cc); + + + // validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + RegisterResult persInfo = resp.getPersonResult().get(0); + assertEquals("wrong familyname", "mRjMKAQc", persInfo.getFamilyName()); + assertEquals("wrong givenName", "vdqZZIaA", persInfo.getGivenName()); + assertEquals("wrong dateOfBirth", "1996-01-01", persInfo.getDateOfBirth()); + assertEquals("wrong bpk", "TBGoMlirU881e2jMGETa9WLx1+A=", persInfo.getBpk()); + + } + + @Test + @SneakyThrows + public void addPersonSimpleComplexe() { + final String cc = "DE"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc).toBuilder() + .birthName(RandomStringUtils.randomAlphabetic(5)) + .placeOfBirth(RandomStringUtils.randomAlphabetic(5)) + .build(); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/2_add_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute operation + // execute operation + ErnpRegisterResult resp = client.add(eidasDataFirst); + + // validate request + final RecordedRequest request = mockWebServer.takeRequest(); + String reqBody = request.getBody().readUtf8(); + assertFalse("no request body", reqBody.isEmpty()); + JsonNode reqJson = mapper.readTree(reqBody); + checkJsonElement(reqJson, "begruendung", "Add new person"); + JsonNode person = getJsonObject(reqJson, "personendaten"); + checkJsonElement(person, "familienname", eidasDataFirst.getFamilyName()); + checkJsonElement(person, "vorname", eidasDataFirst.getGivenName()); + checkPersonDateOfBirth(person, eidasDataFirst.getDateOfBirth()); + checkEidasDocument(reqJson, "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", cc, eidasDataFirst.getPseudonym()); + checkEidasDocument(reqJson, "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", cc, eidasDataFirst.getPlaceOfBirth()); + checkEidasDocument(reqJson, "http://eidas.europa.eu/attributes/naturalperson/BirthName", cc, eidasDataFirst.getBirthName()); + + // validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + RegisterResult persInfo = resp.getPersonResult().get(0); + assertEquals("wrong familyname", "mRjMKAQc", persInfo.getFamilyName()); + assertEquals("wrong givenName", "vdqZZIaA", persInfo.getGivenName()); + assertEquals("wrong dateOfBirth", "1996-01-01", persInfo.getDateOfBirth()); + assertEquals("wrong bpk", "TBGoMlirU881e2jMGETa9WLx1+A=", persInfo.getBpk()); + assertEquals("wrong pseudonym", "88hvWzUaIX", persInfo.getPseudonym().get(0)); + assertEquals("wrong placeOfBirth", "VRNCAylF", persInfo.getPlaceOfBirth()); + assertEquals("wrong birthName", "miEklFHC", persInfo.getBirthName()); + + } + + @Test + @SneakyThrows + public void updateNoLatestVersion() { + final String cc = "DE"; + final SimpleEidasData eidasDataFirst = generateRandomEidasData(cc).toBuilder() + .birthName(RandomStringUtils.randomAlphabetic(5)) + .placeOfBirth(RandomStringUtils.randomAlphabetic(5)) + .build(); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/ernp_empty_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + RegisterResult ernpResult = RegisterResult.builder() + .familyName(eidasDataFirst.getFamilyName()) + .givenName(eidasDataFirst.getGivenName()) + .dateOfBirth(eidasDataFirst.getDateOfBirth()) + .bpk("") + .pseudonym(Arrays.asList(eidasDataFirst.getPseudonym())) + .build(); + + // execute operation + EidasSAuthenticationException error = assertThrows("wrong Exception", EidasSAuthenticationException.class, + () -> client.update(ernpResult, eidasDataFirst)); + assertEquals("wrong errorCode", "module.eidasauth.matching.03", error.getErrorId()); + mockWebServer.takeRequest(); + + + } + + + @Test + @SneakyThrows + public void updateNoUpdateRequired() { + final String cc = "DE"; + final String personalIdentifierFirst = "Y8ADWaeh0h"; + final SimpleEidasData eidasDataFirst = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName("CtKKrtUe") + .givenName("dUeYzUFg") + .dateOfBirth("1985-05-05") + .personalIdentifier(cc + "/AT/" + personalIdentifierFirst) + .pseudonym(personalIdentifierFirst) + .build(); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/1_kitt_search_latest_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + RegisterResult ernpResult = RegisterResult.builder() + .familyName(eidasDataFirst.getFamilyName()) + .givenName(eidasDataFirst.getGivenName()) + .dateOfBirth(eidasDataFirst.getDateOfBirth()) + .bpk("+OQnljn0Son1W2rkM73nP/VMsvc=") + .pseudonym(Arrays.asList(eidasDataFirst.getPseudonym())) + .birthName("sNUEAhEr") + .placeOfBirth("hrFevCfP") + .build(); + + // execute operation + ErnpRegisterResult resp = client.update(ernpResult, eidasDataFirst); + + // validate request + final RecordedRequest request = mockWebServer.takeRequest(); + String reqBody = request.getBody().readUtf8(); + assertFalse("no request body", reqBody.isEmpty()); + JsonNode reqJson = mapper.readTree(reqBody); + checkSearchOptions(reqJson, "KITT get-latest-version"); + JsonNode person = getJsonObject(reqJson, "suchdaten"); + checkJsonElement(person, "familienname", ernpResult.getFamilyName()); + checkJsonElement(person, "vorname", ernpResult.getGivenName()); + checkJsonElement(person, "bpkZp", ernpResult.getBpk()); + checkPersonDateOfBirth(person, ernpResult.getDateOfBirth()); + + //validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + RegisterResult persInfo = resp.getPersonResult().get(0); + assertEquals("wrong familyname", ernpResult.getFamilyName(), persInfo.getFamilyName()); + assertEquals("wrong givenName", ernpResult.getGivenName(), persInfo.getGivenName()); + assertEquals("wrong dateOfBirth", ernpResult.getDateOfBirth(), persInfo.getDateOfBirth()); + assertEquals("wrong bpk", ernpResult.getBpk(), persInfo.getBpk()); + assertEquals("wrong pseudonym", ernpResult.getPseudonym().get(0), persInfo.getPseudonym().get(0)); + assertEquals("wrong placeOfBirth", "hrFevCfP", persInfo.getPlaceOfBirth()); + assertEquals("wrong birthName", "sNUEAhEr", persInfo.getBirthName()); + + } + + @Test + @SneakyThrows + public void updateUpdateRequiredMds() { + final String cc = "DE"; + final String personalIdentifierFirst = "Y8ADWaeh0h"; + final SimpleEidasData eidasDataFirst = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName("mVzTMpig6r") + .givenName("Jb2vj1Xpql") + .dateOfBirth("1985-05-05") + .personalIdentifier(cc + "/AT/" + personalIdentifierFirst) + .pseudonym(personalIdentifierFirst) + .placeOfBirth("hrFevCfP") + .birthName("sNUEAhEr") + .build(); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/1_kitt_search_latest_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/1_kitt_update_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + RegisterResult ernpResult = RegisterResult.builder() + .familyName("CtKKrtUe") + .givenName("dUeYzUFg") + .dateOfBirth("1985-05-05") + .bpk("+OQnljn0Son1W2rkM73nP/VMsvc=") + .pseudonym(Arrays.asList("Y8ADWaeh0h")) + .birthName("sNUEAhEr") + .placeOfBirth("hrFevCfP") + .build(); + + // execute operation + ErnpRegisterResult resp = client.update(ernpResult, eidasDataFirst); + + // validate request + // check get-latest-version request + final RecordedRequest request = mockWebServer.takeRequest(); + String reqBody = request.getBody().readUtf8(); + assertFalse("no request body", reqBody.isEmpty()); + JsonNode reqJson = mapper.readTree(reqBody); + checkSearchOptions(reqJson, "KITT get-latest-version"); + JsonNode person = getJsonObject(reqJson, "suchdaten"); + checkJsonElement(person, "familienname", ernpResult.getFamilyName()); + checkJsonElement(person, "vorname", ernpResult.getGivenName()); + checkJsonElement(person, "bpkZp", ernpResult.getBpk()); + checkPersonDateOfBirth(person, ernpResult.getDateOfBirth()); + + // check update request + final RecordedRequest requestKitt = mockWebServer.takeRequest(); + String reqBodyKitt = requestKitt.getBody().readUtf8(); + assertFalse("no request body", reqBodyKitt.isEmpty()); + JsonNode reqJsonKitt = mapper.readTree(reqBodyKitt); + checkJsonElement(reqJsonKitt, "begruendung", "KITT update dataset"); + checkJsonElement(reqJsonKitt, "entityId", "1933000000000475"); + checkJsonElement(reqJsonKitt, "version", "2022-03-03T10:07:28.885Z"); + JsonNode personChange = getJsonObject(reqJsonKitt, "aendern"); + JsonNode personKitt = getJsonObject(personChange, "personendaten"); + checkJsonElement(personKitt, "familienname", eidasDataFirst.getFamilyName()); + checkJsonElement(personKitt, "vorname", eidasDataFirst.getGivenName()); + checkPersonDateOfBirth(personKitt, eidasDataFirst.getDateOfBirth()); + + assertFalse("find 'aendern' element", reqJsonKitt.has("anlegen")); + assertFalse("find 'aendern' element", personChange.has("eidas")); + + + //validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + RegisterResult persInfo = resp.getPersonResult().get(0); + assertEquals("wrong familyname", eidasDataFirst.getFamilyName(), persInfo.getFamilyName()); + assertEquals("wrong givenName", eidasDataFirst.getGivenName(), persInfo.getGivenName()); + assertEquals("wrong dateOfBirth", ernpResult.getDateOfBirth(), persInfo.getDateOfBirth()); + assertEquals("wrong bpk", ernpResult.getBpk(), persInfo.getBpk()); + assertEquals("wrong pseudonym", ernpResult.getPseudonym().get(0), persInfo.getPseudonym().get(0)); + assertEquals("wrong placeOfBirth", "hrFevCfP", persInfo.getPlaceOfBirth()); + assertEquals("wrong birthName", "sNUEAhEr", persInfo.getBirthName()); + + } + + @Test + @SneakyThrows + public void updateUpdateRequiredEidasDocs() { + final String cc = "DE"; + final String personalIdentifierFirst = "nj1m79jm9z"; + final SimpleEidasData eidasDataFirst = SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName("mRjMKAQc") + .givenName("vdqZZIaA") + .dateOfBirth("1996-01-01") + .personalIdentifier(cc + "/AT/" + personalIdentifierFirst) + .pseudonym(personalIdentifierFirst) + .birthName(RandomStringUtils.randomAlphabetic(10)) + .build(); + + // set ERnP response + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/2_kitt_search_latest_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/2_kitt_update_resp.json"), + "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + RegisterResult ernpResult = RegisterResult.builder() + .familyName("mRjMKAQc") + .givenName("vdqZZIaA") + .dateOfBirth("1996-01-01") + .bpk("TBGoMlirU881e2jMGETa9WLx1+A=") + .pseudonym(Arrays.asList("88hvWzUaIX")) + .birthName("VRNCAylF") + .placeOfBirth("miEklFHC") + .build(); + + // execute operation + ErnpRegisterResult resp = client.update(ernpResult, eidasDataFirst); + + // validate request + // check get-latest-version request + final RecordedRequest request = mockWebServer.takeRequest(); + String reqBody = request.getBody().readUtf8(); + assertFalse("no request body", reqBody.isEmpty()); + JsonNode reqJson = mapper.readTree(reqBody); + checkSearchOptions(reqJson, "KITT get-latest-version"); + JsonNode person = getJsonObject(reqJson, "suchdaten"); + checkJsonElement(person, "familienname", ernpResult.getFamilyName()); + checkJsonElement(person, "vorname", ernpResult.getGivenName()); + checkJsonElement(person, "bpkZp", ernpResult.getBpk()); + checkPersonDateOfBirth(person, ernpResult.getDateOfBirth()); + + // check update request + final RecordedRequest requestKitt = mockWebServer.takeRequest(); + String reqBodyKitt = requestKitt.getBody().readUtf8(); + assertFalse("no request body", reqBodyKitt.isEmpty()); + JsonNode reqJsonKitt = mapper.readTree(reqBodyKitt); + checkJsonElement(reqJsonKitt, "begruendung", "KITT update dataset"); + checkJsonElement(reqJsonKitt, "entityId", "1933000000000498"); + checkJsonElement(reqJsonKitt, "version", "2022-03-03T10:14:59.712Z"); + JsonNode personChange = getJsonObject(reqJsonKitt, "anlegen"); + checkEidasDocument(personChange, "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", cc, eidasDataFirst.getPseudonym()); + assertFalse("find 'aendern' element", reqJsonKitt.has("aendern")); + + //validate state + assertNotNull("no ERnP response", resp); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + RegisterResult persInfo = resp.getPersonResult().get(0); + assertEquals("wrong familyname", eidasDataFirst.getFamilyName(), persInfo.getFamilyName()); + assertEquals("wrong givenName", eidasDataFirst.getGivenName(), persInfo.getGivenName()); + assertEquals("wrong dateOfBirth", ernpResult.getDateOfBirth(), persInfo.getDateOfBirth()); + assertEquals("wrong bpk", ernpResult.getBpk(), persInfo.getBpk()); + assertEquals("wrong pseudonym", ernpResult.getPseudonym().get(0), persInfo.getPseudonym().get(0)); + assertEquals("wrong pseudonym", eidasDataFirst.getPseudonym(), persInfo.getPseudonym().get(1)); + assertEquals("wrong placeOfBirth", "VRNCAylF", persInfo.getPlaceOfBirth()); + assertEquals("wrong birthName", "miEklFHC", persInfo.getBirthName()); + + } + + + private SimpleEidasData generateRandomEidasData(String cc) { + final String personalIdentifierFirst = RandomStringUtils.randomAlphanumeric(10); + return SimpleEidasData.builder() + .citizenCountryCode(cc) + .familyName(RandomStringUtils.randomAlphanumeric(10)) + .givenName(RandomStringUtils.randomAlphanumeric(10)) + .dateOfBirth("1996-10-15") + .personalIdentifier(cc + "/AT/" + personalIdentifierFirst) + .pseudonym(personalIdentifierFirst) + .build(); + + } + + private void checkEidasDocument(JsonNode person, String art, String cc, String expected) { + assertTrue("no element: eidas", person.has("eidas")); + assertTrue("wrong type element: eidas", person.get("eidas").isArray()); + + boolean found = false; + Iterator<JsonNode> docs = person.get("eidas").elements(); + while (docs.hasNext() && !found) { + JsonNode el = docs.next(); + assertTrue("art", el.has("art")); + assertTrue("wert", el.has("wert")); + assertTrue("cc", el.has("staatscode2")); + found = art.equals(el.get("art").asText()) && cc.equals(el.get("staatscode2").asText()) + && expected.equals(el.get("wert").asText()); + + } + assertTrue("Missing eidas document", found); + + } + + private void checkEidasDocument(JsonNode person, String art, String cc) { + assertTrue("no element: eidas", person.has("eidas")); + assertTrue("wrong type element: eidas", person.get("eidas").isArray()); + + boolean found = false; + Iterator<JsonNode> docs = person.get("eidas").elements(); + while (docs.hasNext() && !found) { + JsonNode el = docs.next(); + assertTrue("art", el.has("art")); + assertTrue("wert", el.has("wert")); + assertTrue("cc", el.has("staatscode2")); + found = art.equals(el.get("art").asText()) && cc.equals(el.get("staatscode2").asText()); + + } + assertFalse("Missing eidas document", found); + + } + + private void checkPersonDateOfBirth(JsonNode person, String dateOfBirth) { + JsonNode birthDay = getJsonObject(person, "geburtsdatum"); + String[] el = dateOfBirth.split("-"); + checkJsonElement(birthDay, "jahr", Integer.parseInt(el[0])); + checkJsonElement(birthDay, "monat", Integer.parseInt(el[1])); + checkJsonElement(birthDay, "tag", Integer.parseInt(el[2])); + + } + + private void checkSearchOptions(JsonNode json, String reason) { + checkJsonElement(json, "begruendung", reason); + JsonNode options = getJsonObject(json, "suchoptionen"); + checkJsonElement(options, "historisch", "AktuellUndHistorisch"); + checkJsonElement(options, "sucheMitNamensteilen", false); + checkJsonElement(options, "suchwizard", false); + checkJsonElement(options, "zmr", false); + + } + + private JsonNode getJsonObject(JsonNode json, String key) { + assertTrue("no element: " + key, json.has(key)); + assertTrue("wrong type element: " + key, json.get(key).isObject()); + return json.get(key); + + } + + private void checkJsonElement(JsonNode json, String key, int expected) { + assertTrue("no element: " + key, json.has(key)); + assertTrue("wong element-type: " + key, json.get(key).isInt()); + assertEquals("wong element-value: " + key, expected, json.get(key).asInt()); + + } + + private void checkJsonElement(JsonNode json, String key, String expected) { + assertTrue("no element: " + key, json.has(key)); + assertTrue("wong element-type: " + key, json.get(key).isTextual()); + assertEquals("wong element-value: " + key, expected, json.get(key).asText()); + + } + + private void checkJsonElement(JsonNode json, String key, boolean expected) { + assertTrue("no element: " + key, json.has(key)); + assertTrue("wong element-type: " + key, json.get(key).isBoolean()); + assertEquals("wong element-value: " + key, expected, json.get(key).asBoolean()); + + } + + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/SzrClientProductionTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/SzrClientProductionTest.java index a5b83b13..fb52a729 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/SzrClientProductionTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/SzrClientProductionTest.java @@ -23,16 +23,8 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.clients; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.szr.SzrClient; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.SzrCommunicationException; -import at.gv.egiz.eaaf.core.api.data.EaafConstants; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; -import at.gv.egiz.eaaf.core.exceptions.EaafParserException; -import at.gv.egiz.eaaf.core.impl.idp.auth.data.SimpleIdentityLinkAssertionParser; +import java.util.List; + import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.bouncycastle.util.encoders.Base64; @@ -47,10 +39,14 @@ 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 org.w3c.dom.Element; -import szrservices.IdentityLinkType; -import java.util.List; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.szr.SzrClient; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.SzrCommunicationException; +import at.gv.egiz.eaaf.core.api.data.EaafConstants; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; @IfProfileValue(name = "spring.profiles.active", value = "devEnvironment") @@ -78,13 +74,6 @@ public class SzrClientProductionTest { } @Test - public void getVsz() throws EidasSAuthenticationException { - String vsz = szrClient.getEncryptedStammzahl(getEidData()); - Assert.assertNotNull("vsz", vsz); - - } - - @Test public void getEidasBind() throws EidasSAuthenticationException { String vsz = RandomStringUtils.randomAlphanumeric(10); String bindingPubKey = Base64.toBase64String(RandomStringUtils.random(20).getBytes()); @@ -96,52 +85,6 @@ public class SzrClientProductionTest { } - - @Test - public void getIdentityLinkRawMode() throws EaafParserException, EidasSAuthenticationException { - log.debug("Starting connecting SZR Gateway"); - final IdentityLinkType result = szrClient.getIdentityLinkInRawMode(getEidData()); - - final Element idlFromSzr = (Element) result.getAssertion(); - final IIdentityLink identityLink = new SimpleIdentityLinkAssertionParser(idlFromSzr).parseIdentityLink(); - - if (identityLink == null) { - throw new SzrCommunicationException("ernb.00", new Object[] { "NO IDL object" }); - } - - System.out.println(identityLink.getSerializedSamlAssertion()); - - if (StringUtils.isEmpty(identityLink.getFamilyName())) { - throw new SzrCommunicationException("ernb.00", new Object[] { "NO FamilyName from IDL" }); - } - - if (StringUtils.isEmpty(identityLink.getGivenName())) { - throw new SzrCommunicationException("ernb.00", new Object[] { "NO GivenName from IDL" }); - } - - if (StringUtils.isEmpty(identityLink.getDateOfBirth())) { - throw new SzrCommunicationException("ernb.00", new Object[] { "NO DateOfBirthName from IDL" }); - } - - if (StringUtils.isEmpty(identityLink.getIdentificationType())) { - throw new SzrCommunicationException("ernb.00", new Object[] { "NO baseIdType from IDL" }); - } - - if (StringUtils.isEmpty(identityLink.getIdentificationValue())) { - throw new SzrCommunicationException("ernb.00", new Object[] { "NO baseId from IDL" }); - } - - if (StringUtils.isEmpty(identityLink.getSerializedSamlAssertion())) { - throw new SzrCommunicationException("ernb.00", new Object[] { "NO serialized IDL" }); - } - - if (identityLink.getSamlAssertion() == null) { - throw new SzrCommunicationException("ernb.00", new Object[] { "NO raw IDL" }); - } - - } - - @Ignore @Test public void getBpkTest() throws EidasSAuthenticationException { diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/SzrClientTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/SzrClientTest.java index ee1ecf9f..c47c4fb0 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/SzrClientTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/SzrClientTest.java @@ -34,7 +34,6 @@ import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.parsers.ParserConfigurationException; -import javax.xml.ws.soap.SOAPFaultException; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomStringUtils; @@ -63,15 +62,9 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.SzrCommunicationException; import at.gv.egiz.eaaf.core.api.data.EaafConstants; -import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; -import at.gv.egiz.eaaf.core.exceptions.EaafParserException; -import at.gv.egiz.eaaf.core.impl.idp.auth.data.SimpleIdentityLinkAssertionParser; import at.gv.egiz.eaaf.core.impl.utils.DomUtils; import lombok.extern.slf4j.Slf4j; -import szrservices.GetBPKFromStammzahlEncryptedResponse; -import szrservices.GetBPKFromStammzahlEncryptedResponseType; import szrservices.GetIdentityLinkEidasResponse; -import szrservices.IdentityLinkType; import szrservices.PersonInfoType; import szrservices.SZR; import szrservices.SZRException_Exception; @@ -110,33 +103,6 @@ public class SzrClientTest { } - - - - @Test - public void getStammzahlenEcryptedTest() throws SZRException_Exception, SzrCommunicationException { - final GetBPKFromStammzahlEncryptedResponse szrResponse = new GetBPKFromStammzahlEncryptedResponse(); - final GetBPKFromStammzahlEncryptedResponseType result1 = new GetBPKFromStammzahlEncryptedResponseType(); - szrResponse.getOut().add(result1); - - result1.setKey(RandomStringUtils.randomAlphanumeric(20)); - - // when(szrMock.getBPKFromStammzahlEncrypted(anyList())) - // .thenReturn(Arrays.asList(result1)); - when(szrMock.getStammzahlEncrypted(any(), any())).thenReturn(result1.getKey()); - - String stammzahlEncrypted = szrClient.getEncryptedStammzahl(getEidData()); - - Assert.assertEquals("bcBind not match", result1.getKey(), stammzahlEncrypted); - - when(szrMock.getStammzahlEncrypted(any(), any())).thenReturn(null); - try { - szrClient.getEncryptedStammzahl(getEidData()); - } catch (SzrCommunicationException e) { - Assert.assertTrue("Not correct error", e.getMessage().contains("ernb.01")); - } - } - @Test public void getEidasBindRealSzrResponse() throws SZRException_Exception, SzrCommunicationException, IOException { final SignContentResponse szrResponse = new SignContentResponse(); @@ -254,63 +220,6 @@ public class SzrClientTest { } - @Test - public void getIdentityLinkRawModeValidResponse() - throws SZRException_Exception, EaafParserException, JAXBException { - setSzrResponseIdentityLink("/data/szr/szr_resp_valid_1.xml"); - - try { - log.debug("Starting connecting SZR Gateway"); - final IdentityLinkType result = szrClient.getIdentityLinkInRawMode(getEidData()); - - Assert.assertNotNull(result); - Assert.assertNotNull(result.getAssertion()); - - final IIdentityLink identityLink = new SimpleIdentityLinkAssertionParser((Element) result.getAssertion()) - .parseIdentityLink(); - Assert.assertNotNull(identityLink); - - System.out.println(identityLink.getSerializedSamlAssertion()); - - checkElement("Mustermann", identityLink.getFamilyName()); - checkElement("Hans", identityLink.getGivenName()); - checkElement("1989-05-05", identityLink.getDateOfBirth()); - checkElement("urn:publicid:gv.at:baseid", identityLink.getIdentificationType()); - checkElement("k+zDM1BVpN1WJO4x7ZQ3ng==", identityLink.getIdentificationValue()); - Assert.assertNotNull(identityLink.getSerializedSamlAssertion()); - Assert.assertNotNull(identityLink.getSamlAssertion()); - - } catch (final SzrCommunicationException e) { - Assert.fail(); - - } - - } - - @Test - public void getIdentityLinkRawModeErrorTravelerDocExists() - throws SZRException_Exception, IOException, ParserConfigurationException, SAXException { - setSzrExceptionIdentityLink("/data/szr/szr_resp_error_travelerdocexists.xml"); - - try { - log.debug("Starting connecting SZR Gateway"); - szrClient.getIdentityLinkInRawMode(getEidData()); - Assert.fail(); - - } catch (final SzrCommunicationException e) { - checkElement("ernb.02", e.getErrorId()); - Assert.assertNotNull(e.getCause()); - org.springframework.util.Assert.isInstanceOf(SOAPFaultException.class, e.getCause()); - Assert.assertNotNull(((SOAPFaultException) e.getCause()).getFault()); - checkElement("p344:F455", ((SOAPFaultException) e.getCause()).getFault().getFaultCode()); - checkElement( - "The travel document you sent to insert a person already exists for another person. " + "Either check the document or have the person altered accordingly", - ((SOAPFaultException) e.getCause()).getFault().getFaultString()); - - } - - } - @Ignore @Test public void getBpkTest() throws EidasSAuthenticationException { diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientTest.java index beedfda0..2ff9f0cb 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientTest.java @@ -41,6 +41,7 @@ import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummyCo import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient.ZmrRegisterResult; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController.AdresssucheOutput; 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; @@ -605,6 +606,168 @@ public class ZmrClientTest { @Test @SneakyThrows + public void searchResidenceEmpty() { + BigInteger processId = new BigInteger(RandomStringUtils.randomNumeric(6)); + + final String cc = "DE"; + String familyName = RandomStringUtils.randomAlphabetic(10); + String givenName = RandomStringUtils.randomAlphabetic(10); + String dateOfBirth = RandomStringUtils.randomAlphabetic(10); + AdresssucheOutput addressInfo = AdresssucheOutput.builder() + .municipality(RandomStringUtils.randomAlphabetic(10)) + .number(RandomStringUtils.randomAlphabetic(10)) + .postleitzahl(RandomStringUtils.randomAlphabetic(10)) + .street(RandomStringUtils.randomAlphabetic(10)) + .village(RandomStringUtils.randomAlphabetic(10)) + .build(); + + + final ArgumentCaptor<RequestType> zmrReq = ArgumentCaptor.forClass(RequestType.class); + + // inject response + when(zmrMock.service(zmrReq.capture(), any())).thenReturn( + loadResponseFromFile("/data/zmr/empty_zmr_result.xml")); + + // execute operation + ZmrRegisterResult resp = client.searchWithResidenceData(processId, + givenName, familyName, dateOfBirth, cc, addressInfo); + + // validate state + assertNotNull("no ZMR response", resp); + assertEquals("wrong processId", "367100000000079", resp.getProcessId().toString()); + assertEquals("wrong resp size", 0, resp.getPersonResult().size()); + + // validate request + assertEquals("wrong number of req.", 1, zmrReq.getAllValues().size()); + assertNotNull("Personensuche req.", zmrReq.getValue().getPersonSuchenRequest()); + checkBasicRequestParameters(zmrReq.getValue(), PROCESS_TASK_SEARCH, processId, "jUnit123456"); + PersonSuchenRequest pSuche = zmrReq.getValue().getPersonSuchenRequest(); + checkSearchParameters(pSuche.getPersonensucheInfo()); + + assertNotNull("mds", pSuche.getNatuerlichePerson()); + assertEquals("req. givenName", givenName, pSuche.getNatuerlichePerson().getPersonenName().getVorname()); + assertEquals("req. familyName", familyName, pSuche.getNatuerlichePerson().getPersonenName().getFamilienname()); + assertEquals("req. dateOfBirth", dateOfBirth, pSuche.getNatuerlichePerson().getGeburtsdatum()); + + assertEquals("req. Municipality", addressInfo.getMunicipality(), pSuche.getPostAdresse().getGemeinde()); + assertEquals("req. Postleitzahl", addressInfo.getPostleitzahl(), pSuche.getPostAdresse().getPostleitzahl()); + assertEquals("req. Village", addressInfo.getVillage(), pSuche.getPostAdresse().getOrtschaft()); + assertEquals("req. Street", addressInfo.getStreet(), pSuche.getPostAdresse().getZustelladresse().getStrassenname()); + assertEquals("req. Number", addressInfo.getNumber(), pSuche.getPostAdresse().getZustelladresse().getOrientierungsnummer()); + + } + + @Test + @SneakyThrows + public void searchResidenceMoreThanOneResult() { + BigInteger processId = new BigInteger(RandomStringUtils.randomNumeric(6)); + + final String cc = "DE"; + String familyName = RandomStringUtils.randomAlphabetic(10); + String givenName = RandomStringUtils.randomAlphabetic(10); + String dateOfBirth = RandomStringUtils.randomAlphabetic(10); + AdresssucheOutput addressInfo = AdresssucheOutput.builder() + .municipality(RandomStringUtils.randomAlphabetic(10)) + .postleitzahl(RandomStringUtils.randomAlphabetic(10)) + .street(RandomStringUtils.randomAlphabetic(10)) + .build(); + + final ArgumentCaptor<RequestType> zmrReq = ArgumentCaptor.forClass(RequestType.class); + + // inject response + when(zmrMock.service(zmrReq.capture(), any())).thenReturn( + loadResponseFromFile("/data/zmr/search_with_personalId_only_resp_moreThanOne.xml")); + + // execute operation + ZmrRegisterResult resp = client.searchWithResidenceData(processId, + givenName, familyName, dateOfBirth, cc, addressInfo); + + // validate state + assertNotNull("no ZMR response", resp); + assertEquals("wrong processId", "367100000000079", resp.getProcessId().toString()); + assertEquals("wrong resp size", 2, resp.getPersonResult().size()); + + // validate request + assertEquals("wrong number of req.", 1, zmrReq.getAllValues().size()); + assertNotNull("Personensuche req.", zmrReq.getValue().getPersonSuchenRequest()); + checkBasicRequestParameters(zmrReq.getValue(), PROCESS_TASK_SEARCH, processId, "jUnit123456"); + PersonSuchenRequest pSuche = zmrReq.getValue().getPersonSuchenRequest(); + assertEquals("req. Municipality", addressInfo.getMunicipality(), pSuche.getPostAdresse().getGemeinde()); + assertEquals("req. Postleitzahl", addressInfo.getPostleitzahl(), pSuche.getPostAdresse().getPostleitzahl()); + assertNull("req. Village", pSuche.getPostAdresse().getOrtschaft()); + assertEquals("req. Street", addressInfo.getStreet(), pSuche.getPostAdresse().getZustelladresse().getStrassenname()); + assertNull("req. Number", pSuche.getPostAdresse().getZustelladresse().getOrientierungsnummer()); + + } + + @Test + @SneakyThrows + public void searchResidenceSuccess() { + 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(); + + BigInteger processId = new BigInteger(RandomStringUtils.randomNumeric(6)); + + String familyName = RandomStringUtils.randomAlphabetic(10); + String givenName = RandomStringUtils.randomAlphabetic(10); + String dateOfBirth = RandomStringUtils.randomAlphabetic(10); + AdresssucheOutput addressInfo = AdresssucheOutput.builder() + .municipality(RandomStringUtils.randomAlphabetic(10)) + .postleitzahl(RandomStringUtils.randomAlphabetic(10)) + .build(); + + final ArgumentCaptor<RequestType> zmrReq = ArgumentCaptor.forClass(RequestType.class); + + // inject response + when(zmrMock.service(zmrReq.capture(), any())).thenReturn( + loadResponseFromFile("/data/zmr/search_with_personalId_only_resp.xml")); + + // execute operation + ZmrRegisterResult resp = client.searchWithResidenceData(processId, + givenName, familyName, dateOfBirth, cc, addressInfo); + + // validate state + assertNotNull("no ZMR response", resp); + assertEquals("wrong processId", "367100000000079", resp.getProcessId().toString()); + assertEquals("wrong resp size", 1, resp.getPersonResult().size()); + + RegisterResult persInfo = resp.getPersonResult().get(0); + assertEquals("bPK", "UgeknNsc26lVuB7U/uYGVmWtnnA=", persInfo.getBpk()); + assertEquals("dateOfBirth", eidasDataFirst.getDateOfBirth(), persInfo.getDateOfBirth()); + assertEquals("familyName", eidasDataFirst.getFamilyName(), persInfo.getFamilyName()); + assertEquals("givenName", eidasDataFirst.getGivenName(), persInfo.getGivenName()); + assertEquals("placeOfBirth", "Hintergigritzpotschn", persInfo.getPlaceOfBirth()); + assertEquals("birthName", "XXXvon Heuburg", persInfo.getBirthName()); + assertEquals("num. stored eIDAS identifiers", 2, persInfo.getPseudonym().size()); + assertEquals("stored eIDAS identifiers", "7cEYWithDEElementsasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit", + persInfo.getPseudonym().get(0)); + assertEquals("stored eIDAS identifiers", + "7cEYWithDEElementsasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit_second_one", + persInfo.getPseudonym().get(1)); + + // validate request + assertEquals("wrong number of req.", 1, zmrReq.getAllValues().size()); + assertNotNull("Personensuche req.", zmrReq.getValue().getPersonSuchenRequest()); + checkBasicRequestParameters(zmrReq.getValue(), PROCESS_TASK_SEARCH, processId, "jUnit123456"); + PersonSuchenRequest pSuche = zmrReq.getValue().getPersonSuchenRequest(); + assertEquals("req. Municipality", addressInfo.getMunicipality(), pSuche.getPostAdresse().getGemeinde()); + assertEquals("req. Postleitzahl", addressInfo.getPostleitzahl(), pSuche.getPostAdresse().getPostleitzahl()); + assertNull("req. Village", pSuche.getPostAdresse().getOrtschaft()); + assertNull("req. Number", pSuche.getPostAdresse().getZustelladresse()); + + } + + + @Test + @SneakyThrows public void updateProcessNoLatestVersionResult() { BigInteger processId = new BigInteger(RandomStringUtils.randomNumeric(6)); @@ -777,13 +940,19 @@ public class ZmrClientTest { assertEquals("2 req. tech. Ref. date", "2020-02-05T13:07:06.311", secondpSuche.getPersonReferenz().getTechnisch().getLetzteAenderung().toString()); - assertEquals("eidas Docs. size", 3, secondpSuche.getEidasIdentitaetAnlage().size()); + assertEquals("eidas Docs. size", 6, secondpSuche.getEidasIdentitaetAnlage().size()); checkEidasDocumentAdd(secondpSuche.getEidasIdentitaetAnlage(), "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", cc, eidasData.getPlaceOfBirth()); checkEidasDocumentAdd(secondpSuche.getEidasIdentitaetAnlage(), "http://eidas.europa.eu/attributes/naturalperson/BirthName", cc, eidasData.getBirthName()); checkEidasDocumentAdd(secondpSuche.getEidasIdentitaetAnlage(), - "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", cc, eidasData.getPseudonym()); + "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", cc, eidasData.getPseudonym()); + checkEidasDocumentAdd(secondpSuche.getEidasIdentitaetAnlage(), + "http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName", cc, eidasData.getGivenName()); + checkEidasDocumentAdd(secondpSuche.getEidasIdentitaetAnlage(), + "http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName", cc, eidasData.getFamilyName()); + checkEidasDocumentAdd(secondpSuche.getEidasIdentitaetAnlage(), + "http://eidas.europa.eu/attributes/naturalperson/DateOfBirth", cc, eidasData.getDateOfBirth()); // validate state @@ -947,8 +1116,7 @@ public class ZmrClientTest { assertEquals("eidas Docs. size", 1, secondpSuche.getEidasIdentitaetAnlage().size()); checkEidasDocumentAdd(secondpSuche.getEidasIdentitaetAnlage(), "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", cc, eidasData.getPseudonym()); - - + // validate state assertNotNull("no ZMR response", resp); assertEquals("wrong processId", "366200000000082", resp.getProcessId().toString()); @@ -978,7 +1146,7 @@ public class ZmrClientTest { return req; } - + private void addIfAvailable(List<EidasSuchdatenType> eidasSuchdaten, String cc, String attrName, String attrValue) { if (StringUtils.isNotEmpty(attrValue)) { diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java index 63266cf6..3814c632 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java @@ -35,7 +35,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -49,12 +49,13 @@ import org.springframework.web.context.request.ServletRequestAttributes; import com.github.skjolber.mockito.soap.SoapServiceRule; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +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.clients.zmr.IZmrClient; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient.ZmrRegisterResult; 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.ernp.IErnpClient; 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.WorkflowException; @@ -70,6 +71,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils; import at.gv.bmi.namespace.zmr_su.base._20040201.RequestType; import at.gv.bmi.namespace.zmr_su.base._20040201.ResponseType; import at.gv.bmi.namespace.zmr_su.base._20040201_.ServicePort; +import at.gv.bmi.namespace.zmr_su.zmr._20040201.EidasIdentitaetAnlageType; import at.gv.bmi.namespace.zmr_su.zmr._20040201.EidasSuchdatenType; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; @@ -407,7 +409,10 @@ public class AlternativeSearchTaskWithRegisterTest { when(zmrMock.service(zmrReq.capture(), any())) .thenReturn(loadResponseFromFile("/data/zmr/seq_1-8_search_with_personalId_only_resp.xml")) .thenThrow(new RuntimeException("This request is not needed any more")); - + + Mockito.when(ernpClient.searchWithPersonIdentifier(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + // execute task TaskExecutionException exception = assertThrows(TaskExecutionException.class, () -> task.execute(pendingReq, executionContext)); @@ -470,6 +475,13 @@ public class AlternativeSearchTaskWithRegisterTest { .thenReturn(loadResponseFromFile("/data/zmr/seq_3-8_kitt_get_latest_version_resp.xml")) .thenThrow(new RuntimeException("This request is not needed any more")); + Mockito.when(ernpClient.searchWithPersonIdentifier(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(any(), any(), any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + // execute task task.execute(pendingReq, executionContext); @@ -498,7 +510,16 @@ public class AlternativeSearchTaskWithRegisterTest { assertNotNull("PersonAender KITT req.", zmrReq.getAllValues().get(2).getPersonAendernRequest()); checkBasicRequestParameters(zmrReq.getAllValues().get(2), ZmrClientTest.PROCESS_TASK_UPDATE, new BigInteger("367100000000079"), "jUnit123456"); - + + assertEquals("wrong number of eIDAS Docs to Add", 4, + zmrReq.getAllValues().get(2).getPersonAendernRequest().getEidasIdentitaetAnlage().size()); + checkEidasDocumentAdd(zmrReq.getAllValues().get(2).getPersonAendernRequest().getEidasIdentitaetAnlage(), + "http://eidas.europa.eu/attributes/naturalperson/DateOfBirth", "DE", "1994-12-31"); + checkEidasDocumentAdd(zmrReq.getAllValues().get(2).getPersonAendernRequest().getEidasIdentitaetAnlage(), + "http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName", "DE", "XXXKlaus - Maria"); + checkEidasDocumentAdd(zmrReq.getAllValues().get(2).getPersonAendernRequest().getEidasIdentitaetAnlage(), + "http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName", "DE", "XXXvon Brandenburg"); + assertNotNull("Personensuche KITT req.", zmrReq.getAllValues().get(3).getPersonSuchenRequest()); checkBasicRequestParameters(zmrReq.getAllValues().get(3), ZmrClientTest.PROCESS_TASK_SEARCH, new BigInteger("367100000000079"), "jUnit123456"); @@ -549,6 +570,15 @@ public class AlternativeSearchTaskWithRegisterTest { .thenReturn(loadResponseFromFile("/data/zmr/seq_3-10_kitt_update_resp.xml")) .thenThrow(new RuntimeException("This request is not needed any more")); + Mockito.when(ernpClient.searchWithPersonIdentifier(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchCountrySpecific(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(any(), any(), any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + // execute task task.execute(pendingReq, executionContext); @@ -636,6 +666,9 @@ public class AlternativeSearchTaskWithRegisterTest { .thenReturn(loadResponseFromFile("/data/zmr/empty_zmr_result.xml")) .thenThrow(new RuntimeException("This request is not needed any more")); + Mockito.when(ernpClient.searchWithPersonIdentifier(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + // execute task task.execute(pendingReq, executionContext); @@ -697,6 +730,13 @@ public class AlternativeSearchTaskWithRegisterTest { .thenReturn(loadResponseFromFile("/data/zmr/search_with_personalId_only_resp_moreThanOne.xml")) .thenThrow(new RuntimeException("This request is not needed any more")); + Mockito.when(ernpClient.searchWithPersonIdentifier(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(any(), any(), any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + // execute task TaskExecutionException exception = assertThrows(TaskExecutionException.class, () -> task.execute(pendingReq, executionContext)); @@ -769,6 +809,14 @@ public class AlternativeSearchTaskWithRegisterTest { .thenReturn(loadResponseFromFile("/data/zmr/empty_zmr_result.xml")) .thenThrow(new RuntimeException("This request is not needed any more")); + Mockito.when(ernpClient.searchWithPersonIdentifier("7cEYasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit", "DE")) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchCountrySpecific(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + + // execute task task.execute(pendingReq, executionContext); @@ -777,6 +825,9 @@ public class AlternativeSearchTaskWithRegisterTest { assertNull("final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); assertEquals("wrong executionContextFlag 'alternative eIDAS result'", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.25", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + // validate request @@ -971,5 +1022,21 @@ public class AlternativeSearchTaskWithRegisterTest { } + private void checkEidasDocumentAdd(List<EidasIdentitaetAnlageType> list, String type, String cc, String value) { + Optional<EidasIdentitaetAnlageType> eidasDoc = list.stream() + .filter(el -> type.equals(el.getEidasArt())) + .findFirst(); + + assertTrue("eidas doc: " + type, eidasDoc.isPresent()); + assertEquals("eIDAS docType", type, eidasDoc.get().getEidasArt()); + assertEquals("eIDAS docValue", value, eidasDoc.get().getEidasWert()); + assertEquals("eIDAS docCC", cc, eidasDoc.get().getStaatscode2()); + } + + @NotNull + private ErnpRegisterResult emptyErnpRegisterResult() { + return new ErnpRegisterResult(Collections.emptyList()); + } + } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java index e3757c0d..dbcc62dc 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java @@ -133,6 +133,7 @@ public class CreateIdentityLinkTaskEidNewTest { private static ObjectMapper mapper = new ObjectMapper(); private AuthenticationResponse response; + private MatchedPersonResult matchingInfos; @Rule public final SoapServiceRule soap = SoapServiceRule.newInstance(); @@ -168,7 +169,14 @@ public class CreateIdentityLinkTaskEidNewTest { final SimpleEidasData eidData = eidPostProcessor.postProcess(eidasAttributes); MatchingTaskUtils.storeInitialEidasData(pendingReq, eidData); - MatchingTaskUtils.storeFinalMatchingResult(pendingReq, null); + matchingInfos = MatchedPersonResult.builder() + .bpk(RandomStringUtils.randomAlphabetic(5)) + .givenName(eidData.getGivenName()) + .familyName(eidData.getFamilyName()) + .dateOfBirth(eidData.getDateOfBirth()) + .countryCode(eidData.getCitizenCountryCode()) + .build(); + MatchingTaskUtils.storeFinalMatchingResult(pendingReq, matchingInfos); pendingReq.setSpConfig(oaParam); pendingReq.setPendingReqId(at.gv.egiz.eaaf.core.impl.utils.Random.nextProcessReferenceValue()); @@ -187,13 +195,23 @@ public class CreateIdentityLinkTaskEidNewTest { //initialize test response = buildDummyAuthResponse(true); pendingReq.getSessionData(AuthProcessDataWrapper.class) - .setGenericDataToSession(Constants.DATA_FULL_EIDAS_RESPONSE, response); - MatchingTaskUtils.storeInitialEidasData(pendingReq, eidPostProcessor.postProcess( - convertEidasAttrToSimpleMap(response.getAttributes().getAttributeMap()))); + .setGenericDataToSession(Constants.DATA_FULL_EIDAS_RESPONSE, response); + SimpleEidasData eidData = eidPostProcessor.postProcess( + convertEidasAttrToSimpleMap(response.getAttributes().getAttributeMap())); + MatchingTaskUtils.storeInitialEidasData(pendingReq, eidData); + + matchingInfos = MatchedPersonResult.builder() + .bpk(RandomStringUtils.randomAlphabetic(5)) + .givenName(eidData.getGivenName()) + .familyName(eidData.getFamilyName()) + .dateOfBirth(eidData.getDateOfBirth()) + .countryCode(eidData.getCitizenCountryCode()) + .build(); + MatchingTaskUtils.storeFinalMatchingResult(pendingReq, matchingInfos); String vsz = RandomStringUtils.randomNumeric(10); when(szrMock.getStammzahlEncrypted(any(), any())).thenReturn(vsz); - val signContentResp = new SignContentResponseType(); + SignContentResponseType signContentResp = new SignContentResponseType(); final SignContentEntry signContentEntry = new SignContentEntry(); signContentEntry.setValue(RandomStringUtils.randomAlphanumeric(10)); signContentResp.getOut().add(signContentEntry); @@ -251,7 +269,7 @@ public class CreateIdentityLinkTaskEidNewTest { verify(szrMock, times(1)).getStammzahlEncrypted(argument4.capture(), argument5.capture()); Boolean param5 = argument5.getValue(); - Assert.assertTrue("insertERnP flag", param5); + Assert.assertFalse("insertERnP flag", param5); PersonInfoType person = argument4.getValue(); Assert.assertEquals("FamilyName", response.getAttributes().getAttributeValuesByFriendlyName("FamilyName").getFirstValue( @@ -267,23 +285,9 @@ public class CreateIdentityLinkTaskEidNewTest { .toString().split("T")[0], person.getPerson().getDateOfBirth()); - Assert.assertEquals("PlaceOfBirth", - response.getAttributes().getAttributeValuesByFriendlyName("PlaceOfBirth").getFirstValue( - response.getAttributes().getDefinitionsByFriendlyName("PlaceOfBirth").iterator().next()), - person.getPerson().getPlaceOfBirth()); - Assert.assertEquals("BirthName", - response.getAttributes().getAttributeValuesByFriendlyName("BirthName").getFirstValue( - response.getAttributes().getDefinitionsByFriendlyName("BirthName").iterator().next()), - person.getPerson().getAlternativeName().getFamilyName()); - - Assert.assertEquals("CitizenCountry", "LU", person.getTravelDocument().getIssuingCountry()); - Assert.assertEquals("DocumentType", "ELEKTR_DOKUMENT", person.getTravelDocument().getDocumentType()); - - Assert.assertEquals("Identifier", - response.getAttributes().getAttributeValuesByFriendlyName("PersonIdentifier").getFirstValue( - response.getAttributes().getDefinitionsByFriendlyName("PersonIdentifier").iterator().next()) - .toString().split("/")[2], - person.getTravelDocument().getDocumentNumber()); + Assert.assertNull("PlaceOfBirth", person.getPerson().getPlaceOfBirth()); + Assert.assertNull("BirthName", person.getPerson().getAlternativeName()); + Assert.assertNull("TravelDocument", person.getTravelDocument()); // check bcBind singing request ArgumentCaptor<Boolean> argument1 = ArgumentCaptor.forClass(Boolean.class); @@ -329,27 +333,16 @@ public class CreateIdentityLinkTaskEidNewTest { //initialize test String vsz = RandomStringUtils.randomNumeric(10); when(szrMock.getStammzahlEncrypted(any(), any())).thenReturn(vsz); - val signContentResp = new SignContentResponseType(); + SignContentResponseType signContentResp = new SignContentResponseType(); final SignContentEntry signContentEntry = new SignContentEntry(); signContentEntry.setValue(RandomStringUtils.randomAlphanumeric(10)); signContentResp.getOut().add(signContentEntry); when(szrMock.signContent(any(), any(), any())).thenReturn(signContentResp); - String randomTestSp = RandomStringUtils.randomAlphabetic(10); String bindingPubKey = RandomStringUtils.randomAlphabetic(10); pendingReq.setRawDataToTransaction(MsEidasNodeConstants.DATA_REQUESTERID, randomTestSp); - - MatchedPersonResult matchingInfos = MatchedPersonResult.builder() - .bpk(RandomStringUtils.randomAlphabetic(5)) - .givenName(RandomStringUtils.randomAlphabetic(5)) - .familyName(RandomStringUtils.randomAlphabetic(5)) - .dateOfBirth(RandomStringUtils.randomAlphabetic(5)) - .countryCode(RandomStringUtils.randomAlphabetic(2).toUpperCase()) - .build(); - MatchingTaskUtils.storeFinalMatchingResult(pendingReq, matchingInfos); - pendingReq.setRawDataToTransaction(MsEidasNodeConstants.EID_BINDING_PUBLIC_KEY_NAME, bindingPubKey); @@ -467,7 +460,7 @@ public class CreateIdentityLinkTaskEidNewTest { verify(szrMock, times(1)).getStammzahlEncrypted(argument4.capture(), argument5.capture()); Boolean param5 = argument5.getValue(); - Assert.assertTrue("insertERnP flag", param5); + Assert.assertFalse("insertERnP flag", param5); PersonInfoType person = argument4.getValue(); Assert.assertEquals("FamilyName", response.getAttributes().getAttributeValuesByFriendlyName("FamilyName").getFirstValue( @@ -485,15 +478,7 @@ public class CreateIdentityLinkTaskEidNewTest { Assert.assertNull("PlaceOfBirth", person.getPerson().getPlaceOfBirth()); Assert.assertNull("BirthName", person.getPerson().getAlternativeName()); - - Assert.assertEquals("CitizenCountry", "LU", person.getTravelDocument().getIssuingCountry()); - Assert.assertEquals("DocumentType", "ELEKTR_DOKUMENT", person.getTravelDocument().getDocumentType()); - - Assert.assertEquals("Identifier", - response.getAttributes().getAttributeValuesByFriendlyName("PersonIdentifier").getFirstValue( - response.getAttributes().getDefinitionsByFriendlyName("PersonIdentifier").iterator().next()) - .toString().split("/")[2], - person.getTravelDocument().getDocumentNumber()); + Assert.assertNull("TravelDocument", person.getTravelDocument()); } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskTest.java index 7513501e..4986d5a7 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskTest.java @@ -105,6 +105,7 @@ public class CreateIdentityLinkTaskTest { private DummySpConfiguration oaParam; private SZR szrMock; + private MatchedPersonResult matchingInfos; private AuthenticationResponse response; private Map<String, String> spConfig; @@ -143,7 +144,14 @@ public class CreateIdentityLinkTaskTest { pendingReq.getSessionData(AuthProcessDataWrapper.class) .setGenericDataToSession(Constants.DATA_FULL_EIDAS_RESPONSE, response); - MatchingTaskUtils.storeFinalMatchingResult(pendingReq, null); + matchingInfos = MatchedPersonResult.builder() + .bpk(RandomStringUtils.randomAlphabetic(5)) + .givenName(eidData.getGivenName()) + .familyName(eidData.getFamilyName()) + .dateOfBirth(eidData.getDateOfBirth()) + .countryCode(eidData.getCitizenCountryCode()) + .build(); + MatchingTaskUtils.storeFinalMatchingResult(pendingReq, matchingInfos); pendingReq.setSpConfig(oaParam); pendingReq.setPendingReqId(at.gv.egiz.eaaf.core.impl.utils.Random.nextProcessReferenceValue()); @@ -447,41 +455,6 @@ public class CreateIdentityLinkTaskTest { authProcessData.getGenericDataFromSession(PvpAttributeDefinitions.BPK_NAME)); } - @Test - public void buildDummyIdl() throws Exception { - //initialize test - String randomTestSp = RandomStringUtils.randomAlphabetic(10); - pendingReq.setRawDataToTransaction(MsEidasNodeConstants.DATA_REQUESTERID, randomTestSp); - - basicConfig.putConfigValue("eidas.ms.auth.eIDAS.szrclient.debug.useDummySolution", "true"); - - - //perform test - task.execute(pendingReq, executionContext); - - - //validate state - // check if pendingRequest was stored - IRequest storedPendingReq = requestStorage.getPendingRequest(pendingReq.getPendingRequestId()); - Assert.assertNotNull("pendingReq not stored", storedPendingReq); - - //check data in session - final AuthProcessDataWrapper authProcessData = storedPendingReq.getSessionData(AuthProcessDataWrapper.class); - Assert.assertNotNull("AuthProcessData", authProcessData); - Assert.assertNull("eidasBind", authProcessData.getGenericDataFromSession(Constants.EIDAS_BIND, String.class)); - - String authBlock = authProcessData.getGenericDataFromSession(Constants.SZR_AUTHBLOCK, String.class); - Assert.assertNull("AuthBlock", authBlock); - - Assert.assertFalse("EID process", authProcessData.isEidProcess()); - Assert.assertTrue("foreigner process", authProcessData.isForeigner()); - Assert.assertEquals("EID-ISSUING_NATION", "LU", - authProcessData.getGenericDataFromSession(PvpAttributeDefinitions.EID_ISSUING_NATION_NAME, String.class)); - - Assert.assertNotNull("IDL", authProcessData.getIdentityLink()); - - } - private void setSzrResponseIdentityLink(String responseXmlPath) throws JAXBException, SZRException_Exception { final JAXBContext jaxbContext = JAXBContext .newInstance(szrservices.ObjectFactory.class, org.w3._2001._04.xmldsig_more.ObjectFactory.class, 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> 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; + + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateOtherLoginMethodGuiTaskTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateOtherLoginMethodGuiTaskTest.java index f17f69c3..ff994061 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateOtherLoginMethodGuiTaskTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateOtherLoginMethodGuiTaskTest.java @@ -1,15 +1,13 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.tasks; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SelectedLoginMethod; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.GenerateOtherLoginMethodGuiTask; -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 com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.json.JsonMapper; -import lombok.SneakyThrows; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.UnsupportedEncodingException; +import java.text.MessageFormat; +import java.util.Locale; + import org.apache.commons.lang3.RandomStringUtils; import org.junit.Assert; import org.junit.Before; @@ -26,12 +24,17 @@ import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; -import java.io.UnsupportedEncodingException; -import java.text.MessageFormat; -import java.util.Locale; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SelectedLoginMethod; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.GenerateOtherLoginMethodGuiTask; +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 = { @@ -82,8 +85,9 @@ public class GenerateOtherLoginMethodGuiTaskTest { @Test @SneakyThrows public void jsonResponse() throws TaskExecutionException, UnsupportedEncodingException { - + String reason = RandomStringUtils.randomAlphabetic(5); executionContext.put(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); + executionContext.put(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON, reason); httpReq.addHeader("Accept", "application/json"); task.execute(pendingReq, executionContext); @@ -98,20 +102,44 @@ public class GenerateOtherLoginMethodGuiTaskTest { assertNotNull("response body is null", json); assertNotNull("advancedMatchFailed", json.get(Constants.HTML_FORM_ADVANCED_MATCHING_FAILED)); assertTrue("advancedMatchFailed", json.get(Constants.HTML_FORM_ADVANCED_MATCHING_FAILED).asBoolean()); - + assertNotNull("advancedMatchingFailedReason", json.get(Constants.HTML_FORM_ADVANCED_MATCHING_FAILED_REASON)); + assertEquals("advancedMatchingFailedReason", reason, + json.get(Constants.HTML_FORM_ADVANCED_MATCHING_FAILED_REASON).asText()); + } @Test public void advancedMatchingFailedMsg() throws TaskExecutionException, UnsupportedEncodingException { - executionContext.put(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); task.execute(pendingReq, executionContext); + + String html = doBasicValidation(); + Assert.assertTrue("Missing eIDAS infos", + html.contains(MessageFormat.format(TEST_PATTER_REQ_PARAM, SelectedLoginMethod.ADD_ME_AS_NEW))); + Assert.assertTrue("missing errorfield", + html.contains("<div id=\"matchingError\"")); + + } - doBasicValidation(); + @Test + public void advancedMatchingFailedMsgWithDetails() throws TaskExecutionException, UnsupportedEncodingException { + String reason = RandomStringUtils.randomAlphabetic(5); + executionContext.put(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); + executionContext.put(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON, reason); + + task.execute(pendingReq, executionContext); + String html = doBasicValidation(); + Assert.assertTrue("Missing eIDAS infos", + html.contains(MessageFormat.format(TEST_PATTER_REQ_PARAM, SelectedLoginMethod.ADD_ME_AS_NEW))); + Assert.assertTrue("missing errorfield", + html.contains("<div id=\"matchingError\"")); + Assert.assertTrue("missing errorfield", + html.contains(reason)); + } - + @Test public void validHtmlResponseWithOutLocale() throws TaskExecutionException, UnsupportedEncodingException { @@ -153,7 +181,7 @@ public class GenerateOtherLoginMethodGuiTaskTest { } - private void doBasicValidation() throws UnsupportedEncodingException { + private String doBasicValidation() throws UnsupportedEncodingException { Assert.assertEquals("Wrong http StatusCode", 200, httpResp.getStatus()); Assert.assertEquals("Wrong http ContentType", "text/html;charset=UTF-8", httpResp.getContentType()); @@ -165,11 +193,15 @@ public class GenerateOtherLoginMethodGuiTaskTest { html.contains(MessageFormat.format(TEST_PATTER_REQ_PARAM, SelectedLoginMethod.MOBILE_PHONE_SIGNATURE_LOGIN))); Assert.assertTrue("Missing residence infos", html.contains(MessageFormat.format(TEST_PATTER_REQ_PARAM, SelectedLoginMethod.NO_OTHER_LOGIN))); - + Assert.assertTrue("Missing eIDAS infos", + html.contains(MessageFormat.format(TEST_PATTER_REQ_PARAM, SelectedLoginMethod.EIDAS_LOGIN))); + Assert.assertTrue("No language selector with pendingRequestId", html.contains("/otherLoginMethod?pendingid=" + pendingReq.getPendingRequestId())); Assert.assertTrue("No country-selection form", html.contains("<form method=\"post\" action=\"/otherLoginMethod\">")); + + return html; } } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskTest.java index e5ba2e07..74ac065e 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskTest.java @@ -23,15 +23,59 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.tasks; +import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; + +import java.math.BigInteger; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.xml.namespace.QName; + +import org.apache.commons.lang3.RandomStringUtils; +import org.jetbrains.annotations.NotNull; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +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.Constants; +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.clients.zmr.IZmrClient; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient.ZmrRegisterResult; 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.ernp.IErnpClient; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.*; +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.EidasSAuthenticationException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.WorkflowException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.ZmrCommunicationException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.CountrySpecificDetailSearchProcessor; import at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.GenericEidProcessor; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.ICcSpecificEidProcessingService; @@ -52,36 +96,6 @@ import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; import eu.eidas.auth.commons.attribute.PersonType; import eu.eidas.auth.commons.light.impl.LightRequest; import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse; -import org.apache.commons.lang3.RandomStringUtils; -import org.jetbrains.annotations.NotNull; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.springframework.beans.factory.annotation.Autowired; -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 javax.xml.namespace.QName; -import java.math.BigInteger; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.*; - -import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; -import static org.junit.Assert.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { @@ -166,16 +180,25 @@ public class InitialSearchTaskTest { @DirtiesContext public void singlePersonalIdMatchUpdateNecessary_Zmr() throws Exception { String oldGivenName = randomAlphabetic(10); + String placeOfBirth = randomAlphabetic(10); + RegisterResult firstZmrResult = randomRegisterResult(oldGivenName, randomBpk, placeOfBirth); Mockito.when(zmrClient.searchWithPersonIdentifier(null, randomPseudonym, DE)) - .thenReturn(zmrRegisterResult(randomRegisterResult(oldGivenName, randomBpk))); + .thenReturn(zmrRegisterResult(firstZmrResult)); Mockito.when(zmrClient.searchCountrySpecific(any(), any(), any())) .thenThrow(new IllegalStateException("CountrySpecific search search should not be neccessary")); Mockito.when(zmrClient.searchWithMds(any(), any(), any(), any(), any())) .thenThrow(new IllegalStateException("MDS search should not be neccessary")); Mockito.when(zmrClient.update(any(), any(), any())) - .thenThrow(new IllegalStateException("ZMR update should not be neccessary")); + .thenReturn(zmrRegisterResult(firstZmrResult)); + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(any(), any(), any(), any())) + .thenThrow(new IllegalStateException("MDS search should not be neccessary")); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + // execute test task.execute(pendingReq, executionContext); @@ -186,23 +209,38 @@ public class InitialSearchTaskTest { } /** - * TODO: include again if ERnP update is implementet. Maybe we can update MDS based on ERnP. - * <p> + * * One match, but register update needed. * * @throws EidasSAuthenticationException */ - @Ignore @Test @DirtiesContext public void singlePersonalIdMatchUpdateNecessary_Ernp() throws TaskExecutionException, EidasSAuthenticationException { Mockito.when(zmrClient.searchWithPersonIdentifier(null, randomPseudonym, DE)) .thenReturn(emptyZmrRegisterResult()); - + Mockito.when(zmrClient.searchCountrySpecific(any(), any(), any())) + .thenThrow(new IllegalStateException("CountrySpecific search search should not be neccessary")); + Mockito.when(zmrClient.searchWithMds(any(), any(), any(), any(), any())) + .thenThrow(new IllegalStateException("MDS search should not be neccessary")); + Mockito.when(zmrClient.update(any(), any(), any())) + .thenThrow(new IllegalStateException("ZMR update should not be neccessary")); + String oldRandomGivenName = randomAlphabetic(10); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_DE)) - .thenReturn(Collections.singletonList(randomRegisterResult(oldRandomGivenName, randomBpk))); - + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(ernpRegisterResult(randomRegisterResult(oldRandomGivenName, randomBpk))); + Mockito.when(ernpClient.searchCountrySpecific(any(), any())) + .thenThrow(new IllegalStateException("CountrySpecific search search should not be neccessary")); + Mockito.when(ernpClient.searchWithMds(any(), any(), any(), any())) + .thenThrow(new IllegalStateException("MDS search should not be neccessary")); + Mockito.when(ernpClient.update(any(), any())) + .thenReturn(ernpRegisterResult(RegisterResult.builder() + .bpk(randomBpk) + .dateOfBirth(randomBirthDate) + .givenName(randomGivenName) + .familyName(randomFamilyName) + .build())); + // execute test task.execute(pendingReq, executionContext); @@ -210,11 +248,8 @@ public class InitialSearchTaskTest { checkMatchingSuccessState(pendingReq, randomBpk, randomFamilyName, randomGivenName, randomBirthDate, DE); } - @NotNull - private ZmrSoapClient.ZmrRegisterResult emptyZmrRegisterResult() { - return new ZmrRegisterResult(Collections.emptyList(), generateRandomProcessId()); - } + /** * Two matches by PersonalId found in ZMR * @@ -226,8 +261,8 @@ public class InitialSearchTaskTest { String newRandomGivenName = randomAlphabetic(10); Mockito.when(zmrClient.searchWithPersonIdentifier(null, randomPseudonym, DE)) .thenReturn(new ZmrRegisterResult(Arrays.asList(randomRegisterResult(), randomRegisterResult(newRandomGivenName, randomBpk)), generateRandomProcessId())); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_DE)) - .thenReturn(Collections.emptyList()); + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(emptyErnpRegisterResult()); // execute task TaskExecutionException exception = assertThrows(TaskExecutionException.class, @@ -251,8 +286,8 @@ public class InitialSearchTaskTest { public void withErrorFromZmr() throws EidasSAuthenticationException { Mockito.when(zmrClient.searchWithPersonIdentifier(null, randomPseudonym, DE)) .thenThrow(new ZmrCommunicationException("jUnit ZMR error", null)); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_DE)) - .thenReturn(Collections.emptyList()); + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(emptyErnpRegisterResult()); // execute task TaskExecutionException exception = assertThrows(TaskExecutionException.class, @@ -277,8 +312,9 @@ public class InitialSearchTaskTest { Mockito.when(zmrClient.searchWithPersonIdentifier(null, randomPseudonym, DE)) .thenReturn(emptyZmrRegisterResult()); String newRandomGivenName = randomAlphabetic(10); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_DE)) - .thenReturn(Arrays.asList(randomRegisterResult(), randomRegisterResult(newRandomGivenName, randomBpk))); + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(ernpRegisterResult( + Arrays.asList(randomRegisterResult(), randomRegisterResult(newRandomGivenName, randomBpk)))); // execute task TaskExecutionException exception = assertThrows(TaskExecutionException.class, @@ -301,9 +337,8 @@ public class InitialSearchTaskTest { public void multiPersonalIdMatch_ErnpAndZmr() throws EidasSAuthenticationException { Mockito.when(zmrClient.searchWithPersonIdentifier(null, randomPseudonym, DE)) .thenReturn(zmrRegisterResult(randomRegisterResult())); - String newRandomGivenName = randomAlphabetic(10); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_DE)) - .thenReturn(Collections.singletonList(randomRegisterResult())); + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(ernpRegisterResult(randomRegisterResult())); // execute task TaskExecutionException exception = assertThrows(TaskExecutionException.class, @@ -324,8 +359,13 @@ public class InitialSearchTaskTest { public void singlePersonalIdMatchNoUpdate_Ernp() throws Exception { Mockito.when(zmrClient.searchWithPersonIdentifier(null, randomPseudonym, DE)) .thenReturn(emptyZmrRegisterResult()); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_DE)) - .thenReturn(Collections.singletonList(randomRegisterResult())); + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(ernpRegisterResult(randomRegisterResult())); + + Mockito.when(zmrClient.update(any(), any(), any())) + .thenThrow(new IllegalStateException("ZMR update should not be neccessary")); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); // execute test task.execute(pendingReq, executionContext); @@ -342,10 +382,13 @@ public class InitialSearchTaskTest { public void singlePersonalIdMatchNoUpdate_Zmr() throws Exception { Mockito.when(zmrClient.searchWithPersonIdentifier(null, randomPseudonym, DE)) .thenReturn(zmrRegisterResult(randomRegisterResult())); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_DE)) - .thenReturn(Collections.emptyList()); + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(zmrClient.update(any(), any(), any())) .thenThrow(new IllegalStateException("ZMR update should not be neccessary")); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); // execute test task.execute(pendingReq, executionContext); @@ -394,9 +437,17 @@ public class InitialSearchTaskTest { Mockito.when(zmrClient.searchWithMds(any(), any(), any(), any(), any())) .thenThrow(new IllegalStateException("MDS search should not be neccessary")); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_DE)) - .thenReturn(Collections.emptyList()); - + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchCountrySpecific(any(), eq(DE))) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(any(), any(), any(), eq(DE))) + .thenThrow(new IllegalStateException("ERnP MDS search should not be neccessary")); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + Mockito.when(ernpClient.add(any())) + .thenThrow(new IllegalStateException("ERnP add-entity should not be neccessary")); + // execute test task.execute(pendingReq1, executionContext); @@ -444,8 +495,12 @@ public class InitialSearchTaskTest { Mockito.when(zmrClient.searchCountrySpecific(eq(zmrProcessId), any(PersonSuchenRequest.class), eq(DE))) .thenReturn(new ZmrRegisterResult(Arrays.asList(randomResult1, randomResult2), zmrProcessId)); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_DE)) - .thenReturn(Collections.emptyList()); + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchCountrySpecific(any(), eq(DE))) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); // execute task TaskExecutionException exception = assertThrows(TaskExecutionException.class, @@ -459,6 +514,89 @@ public class InitialSearchTaskTest { } /** + * Multiple matches found in ZMR and ERnP by country specifics. + */ + @Test + @DirtiesContext + public void multiplePersonFindWithCountySpecifics_ZmrAndErnp() throws Exception { + final AuthenticationResponse response = buildDummyAuthResponseDE(randomGivenName, randomFamilyName, + randomPersonalIdentifier_DE, + randomBirthDate, randomPlaceOfBirth, randomBirthName); + TestRequestImpl pendingReq1 = new TestRequestImpl(); + pendingReq1.getSessionData(AuthProcessDataWrapper.class) + .setGenericDataToSession(Constants.DATA_FULL_EIDAS_RESPONSE, response); + + BigInteger zmrProcessId = generateRandomProcessId(); + Mockito.when(zmrClient.searchWithPersonIdentifier(null, randomPseudonym, DE)) + .thenReturn(new ZmrRegisterResult(Collections.emptyList(), zmrProcessId)); + RegisterResult randomResult1 = RegisterResult.builder() + .bpk(randomBpk) + .pseudonym(Collections.singletonList(randomPseudonym)) + .givenName(randomGivenName) + .familyName(randomFamilyName) + .dateOfBirth(randomBirthDate) + .placeOfBirth(randomPlaceOfBirth) + .birthName(randomBirthName) + .build(); + Mockito.when(zmrClient.searchCountrySpecific(eq(zmrProcessId), any(PersonSuchenRequest.class), eq(DE))) + .thenReturn(new ZmrRegisterResult(Arrays.asList(randomResult1), zmrProcessId)); + + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchCountrySpecific(any(), eq(DE))) + .thenReturn(ernpRegisterResult(randomRegisterResult())); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + + // execute task + TaskExecutionException exception = assertThrows(TaskExecutionException.class, + () -> task.execute(pendingReq1, executionContext)); + + // validate state + assertTrue("Wrong exception", (exception.getOriginalException() instanceof WorkflowException)); + assertTrue("Wrong flag 'manualFixNeeded'", + ((WorkflowException) exception.getOriginalException()).isRequiresManualFix()); + + } + + /** + * Multiple matches found in ERnP by country specifics. + */ + @Test + @DirtiesContext + public void multiplePersonFindWithCountySpecifics_Ernp() throws Exception { + final AuthenticationResponse response = buildDummyAuthResponseDE(randomGivenName, randomFamilyName, + randomPersonalIdentifier_DE, + randomBirthDate, randomPlaceOfBirth, randomBirthName); + TestRequestImpl pendingReq1 = new TestRequestImpl(); + pendingReq1.getSessionData(AuthProcessDataWrapper.class) + .setGenericDataToSession(Constants.DATA_FULL_EIDAS_RESPONSE, response); + + BigInteger zmrProcessId = generateRandomProcessId(); + Mockito.when(zmrClient.searchWithPersonIdentifier(null, randomPseudonym, DE)) + .thenReturn(new ZmrRegisterResult(Collections.emptyList(), zmrProcessId)); + Mockito.when(zmrClient.searchCountrySpecific(eq(zmrProcessId), any(PersonSuchenRequest.class), eq(DE))) + .thenReturn(new ZmrRegisterResult(Arrays.asList(), zmrProcessId)); + + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchCountrySpecific(any(), eq(DE))) + .thenReturn(ernpRegisterResult(Arrays.asList(randomRegisterResult(), randomRegisterResult()))); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + + // execute task + TaskExecutionException exception = assertThrows(TaskExecutionException.class, + () -> task.execute(pendingReq1, executionContext)); + + // validate state + assertTrue("Wrong exception", (exception.getOriginalException() instanceof WorkflowException)); + assertTrue("Wrong flag 'manualFixNeeded'", + ((WorkflowException) exception.getOriginalException()).isRequiresManualFix()); + + } + + /** * NO match found in ZMR and ErnP with Initial and MDS search * * @throws EidasSAuthenticationException @@ -480,9 +618,12 @@ public class InitialSearchTaskTest { Mockito.when(zmrClient.update(any(), any(), any())) .thenThrow(new IllegalStateException("ZMR update should not be neccessary")); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_EE)) - .thenReturn(Collections.emptyList()); - + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, EE)) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(randomGivenName, randomFamilyName, randomBirthDate, EE)) + .thenReturn(new ErnpRegisterResult(Collections.emptyList())); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ZMR update should not be neccessary")); // execute task task.execute(pendingReq, executionContext); @@ -519,10 +660,10 @@ public class InitialSearchTaskTest { Mockito.when(zmrClient.searchWithMds(zmrProcessId, randomGivenName, randomFamilyName, randomBirthDate, EE)) .thenReturn(new ZmrRegisterResult(Collections.emptyList(), zmrProcessId)); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_EE)) - .thenReturn(Collections.emptyList()); - Mockito.when(ernpClient.searchWithMds(randomGivenName, randomFamilyName, randomBirthDate)) - .thenReturn(Collections.singletonList(randomRegisterResult())); + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, EE)) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(randomGivenName, randomFamilyName, randomBirthDate, EE)) + .thenReturn(ernpRegisterResult(randomRegisterResult())); // execute test task.execute(pendingReq, executionContext); @@ -546,8 +687,14 @@ public class InitialSearchTaskTest { Mockito.when(zmrClient.update(any(), any(), any())) .thenThrow(new IllegalStateException("ZMR update should not be neccessary")); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_DE)).thenReturn(Collections.emptyList()); + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)).thenReturn( + emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(randomGivenName, randomFamilyName, randomBirthDate, DE)) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + // execute test task.execute(pendingReq, executionContext); @@ -558,6 +705,37 @@ public class InitialSearchTaskTest { } /** + * Find matches with MDS search in ZMR and ERnP. + */ + @Test + @DirtiesContext + public void resultByMdsSearch_ZmrAndErnp() throws TaskExecutionException, EidasSAuthenticationException { + BigInteger zmrProcessId = generateRandomProcessId(); + Mockito.when(zmrClient.searchWithPersonIdentifier(null, randomPseudonym, DE)) + .thenReturn(new ZmrRegisterResult(Collections.emptyList(), zmrProcessId)); + Mockito.when(zmrClient.searchWithMds(zmrProcessId, randomGivenName, randomFamilyName, randomBirthDate, DE)) + .thenReturn(zmrRegisterResult(randomRegisterResult(), zmrProcessId)); + Mockito.when(zmrClient.update(any(), any(), any())) + .thenThrow(new IllegalStateException("ZMR update should not be neccessary")); + + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)).thenReturn( + emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(randomGivenName, randomFamilyName, randomBirthDate, DE)) + .thenReturn(ernpRegisterResult(randomRegisterResult())); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + + + + // execute test + task.execute(pendingReq, executionContext); + + // validate state + checkIntermediateResult(2); + + } + + /** * resultByMdsSearch */ @Test @@ -573,10 +751,10 @@ public class InitialSearchTaskTest { Mockito.when(zmrClient.update(any(), any(), any())) .thenThrow(new IllegalStateException("ZMR update should not be neccessary")); - Mockito.when(ernpClient.searchWithPersonIdentifier(randomPersonalIdentifier_DE)) - .thenReturn(Collections.emptyList()); - Mockito.when(ernpClient.searchWithMds(randomGivenName, randomFamilyName, randomBirthDate)) - .thenReturn(Arrays.asList(randomRegisterResult(), randomRegisterResult(randomBpk + "1"))); + Mockito.when(ernpClient.searchWithPersonIdentifier(randomPseudonym, DE)) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(randomGivenName, randomFamilyName, randomBirthDate, DE)) + .thenReturn(ernpRegisterResult(Arrays.asList(randomRegisterResult(), randomRegisterResult(randomBpk + "1")))); // execute test task.execute(pendingReq, executionContext); @@ -587,6 +765,16 @@ public class InitialSearchTaskTest { } @NotNull + private ZmrSoapClient.ZmrRegisterResult emptyZmrRegisterResult() { + return new ZmrRegisterResult(Collections.emptyList(), generateRandomProcessId()); + } + + @NotNull + private ErnpRegisterResult emptyErnpRegisterResult() { + return new ErnpRegisterResult(Collections.emptyList()); + } + + @NotNull private ZmrRegisterResult zmrRegisterResult(RegisterResult registerResult, BigInteger processId) { return new ZmrRegisterResult(Collections.singletonList(registerResult), processId); } @@ -597,6 +785,16 @@ public class InitialSearchTaskTest { } @NotNull + private ErnpRegisterResult ernpRegisterResult(RegisterResult registerResult) { + return new ErnpRegisterResult(Collections.singletonList(registerResult)); + } + + @NotNull + private ErnpRegisterResult ernpRegisterResult(List<RegisterResult> registerResult) { + return new ErnpRegisterResult(registerResult); + } + + @NotNull private RegisterResult randomRegisterResult() { return randomRegisterResult(randomGivenName, randomBpk); } @@ -618,6 +816,18 @@ public class InitialSearchTaskTest { } @NotNull + private RegisterResult randomRegisterResult(String randomGivenName, String randomBpk, String placeOfBirth) { + return RegisterResult.builder() + .bpk(randomBpk) + .pseudonym(Collections.singletonList(randomPseudonym)) + .givenName(randomGivenName) + .familyName(randomFamilyName) + .dateOfBirth(randomBirthDate) + .placeOfBirth(placeOfBirth) + .build(); + } + + @NotNull private AuthenticationResponse buildDummyAuthResponseRandomPerson() throws URISyntaxException { return buildDummyAuthResponse(randomGivenName, randomFamilyName, DE_ST + randomPseudonym, randomBirthDate); } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java index 14ad3519..6d0e7c31 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java @@ -45,8 +45,10 @@ import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.namespace.QName; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomStringUtils; import org.jetbrains.annotations.NotNull; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; @@ -54,8 +56,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -69,12 +69,12 @@ import org.springframework.web.context.request.ServletRequestAttributes; import com.github.skjolber.mockito.soap.SoapServiceRule; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.IErnpClient; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.IZmrClient; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient.ZmrRegisterResult; 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.ernp.IErnpClient; 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.EidasSAuthenticationException; @@ -85,6 +85,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.ICcSpecificEidPr import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService.RegisterStatusResults; import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.InitialSearchTask; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.clients.ErnpRestClientTest; import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.clients.ZmrClientTest; import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils; import at.gv.bmi.namespace.zmr_su.base._20040201.RequestType; @@ -103,6 +104,8 @@ import eu.eidas.auth.commons.attribute.PersonType; import eu.eidas.auth.commons.light.impl.LightRequest; import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse; import lombok.SneakyThrows; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { @@ -119,14 +122,16 @@ public class InitialSearchTaskWithRegistersTest { @Rule public SoapServiceRule soap = SoapServiceRule.newInstance(); - @Mock private IErnpClient ernpClient; - - @Autowired private IZmrClient zmrClient; - @Autowired private List<CountrySpecificDetailSearchProcessor> handlers; + @Autowired IErnpClient ernpClient; + @Autowired IZmrClient zmrClient; + @Autowired List<CountrySpecificDetailSearchProcessor> handlers; + private RegisterSearchService registerSearchService; private ServicePort zmrMock = null; + private static MockWebServer mockWebServer; + private final ICcSpecificEidProcessingService eidPostProcessor = createEidPostProcessor(); private InitialSearchTask task; @@ -144,13 +149,24 @@ public class InitialSearchTaskWithRegistersTest { at.gv.bmi.namespace.zmr_su.zmr._20040201.ObjectFactory.class, at.gv.bmi.namespace.zmr_su.gis._20070725.ObjectFactory.class, at.gv.bmi.namespace.zmr_su.base._20040201.ObjectFactory.class); + + mockWebServer = new MockWebServer(); + mockWebServer.start(1718); + } + @AfterClass + @SneakyThrows + public static void resetTestEnviroment() { + mockWebServer.shutdown(); + + } /** * jUnit test set-up. */ @Before + @SneakyThrows public void setUp() throws URISyntaxException, EaafStorageException { if (zmrMock == null) { zmrMock = soap.mock(ServicePort.class, "http://localhost:1234/demozmr"); @@ -166,15 +182,18 @@ public class InitialSearchTaskWithRegistersTest { RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); pendingReq = new TestRequestImpl(); - + } /** * One match, but register update needed + * <p> + * <b>Check if ZMR update request is NOT executed in case of MDS change!</b> + * </p> */ @Test @DirtiesContext - public void singlePersonalIdMatchUpdateNecessary_Zmr() throws Exception { + public void singlePersonalIdMatchUpdateNecessary_ZmrNotDone() throws Exception { String oldGivenName = "XXXClaus - Maria"; @@ -189,8 +208,17 @@ public class InitialSearchTaskWithRegistersTest { // inject response when(zmrMock.service(zmrReq.capture(), any())) .thenReturn(loadResponseFromFile("/data/zmr/seq_1-8_search_with_personalId_only_resp.xml")) - .thenThrow(new RuntimeException("This request is not needed any more")); + + //perform prepair-update request + .thenReturn(loadResponseFromFile("/data/zmr/seq_1-8_search_with_personalId_only_resp.xml")) + //do not make an update because, MDS update is not allowed and no other data has been changed + .thenThrow(new RuntimeException("This request is not needed any more")); + + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody("{}") + .setHeader("Content-Type", "application/json;charset=utf-8")); + // execute test task.execute(pendingReq, executionContext); @@ -201,13 +229,71 @@ public class InitialSearchTaskWithRegistersTest { oldGivenName, "1994-12-31", DE); // validate request - assertEquals("wrong number of req.", 1, zmrReq.getAllValues().size()); + assertEquals("wrong number of req.", 2, zmrReq.getAllValues().size()); assertNotNull("Personensuche req.", zmrReq.getValue().getPersonSuchenRequest()); - checkBasicRequestParameters(zmrReq.getValue(), ZmrClientTest.PROCESS_TASK_SEARCH, null, "jUnit123456"); + checkBasicRequestParameters(zmrReq.getValue(), ZmrClientTest.PROCESS_TASK_SEARCH, + new BigInteger("367100000000079"), "jUnit123456"); } + /** + * One match, but register update needed + * <p> + * <b>Check if ZMR update request is executed in case of other data than MDS change!</b> + * </p> + */ + @Test + @DirtiesContext + public void singlePersonalIdMatchUpdateNecessary_ZmrDone() throws Exception { + + String oldGivenName = "XXXClaus - Maria"; + String placeOfBirth = RandomStringUtils.randomAlphabetic(5); + + //inject eIDAS data + pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession( + Constants.DATA_FULL_EIDAS_RESPONSE, + buildDummyAuthResponse(oldGivenName, "XXXvon Brandenburg", + "DE/AT/7cEYWithDEElementsasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit", "1994-12-31", null, placeOfBirth, null)); + + final ArgumentCaptor<RequestType> zmrReq = ArgumentCaptor.forClass(RequestType.class); + + // inject response + when(zmrMock.service(zmrReq.capture(), any())) + .thenReturn(loadResponseFromFile("/data/zmr/seq_1-8_search_with_personalId_only_resp_no_additional_attributes.xml")) + + //perform prepair-update request + .thenReturn(loadResponseFromFile("/data/zmr/seq_1-8_search_with_personalId_only_resp_no_additional_attributes.xml")) + + //do make an update because, MDS DOES NOT change, but additional attribute was available + .thenReturn(loadResponseFromFile("/data/zmr/seq_3-6_kitt_update_resp.xml")); + + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody("{}") + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute test + task.execute(pendingReq, executionContext); + + // validate state + //INFO: has to be the old givenName because ZMR allows no update of MDS information + checkMatchingSuccessState(pendingReq, "UgeknNsc26lVuB7U/uYGVmWtnnA=", "XXXvon Brandenburg", + oldGivenName, "1994-12-31", DE); + + // validate request + assertEquals("wrong number of req.", 3, zmrReq.getAllValues().size()); + assertNotNull("Personensuche req.", zmrReq.getAllValues().get(0).getPersonSuchenRequest()); + checkBasicRequestParameters(zmrReq.getAllValues().get(0), ZmrClientTest.PROCESS_TASK_SEARCH, null, "jUnit123456"); + assertNotNull("Personenupdate req.", zmrReq.getAllValues().get(2).getPersonAendernRequest()); + checkBasicRequestParameters(zmrReq.getAllValues().get(2), ZmrClientTest.PROCESS_TASK_UPDATE, + new BigInteger("367100000000079"), "jUnit123456"); + assertEquals("eIDAS attribute to add", 4, + zmrReq.getAllValues().get(2).getPersonAendernRequest().getEidasIdentitaetAnlage().size()); + assertNull("ZMR update MDS", zmrReq.getAllValues().get(2).getPersonAendernRequest().getPersonAenderung()); + + } + + /** * Two matches by PersonalId found in ZMR * @@ -239,6 +325,58 @@ public class InitialSearchTaskWithRegistersTest { } + /** + * Find single person in ZMR by country specifics. + */ + @Test + @DirtiesContext + public void singlePersonFindWithCountySpecifics_Ernp() throws Exception { + //inject eIDAS data + pendingReq.getSessionData(AuthProcessDataWrapper.class).setGenericDataToSession( + Constants.DATA_FULL_EIDAS_RESPONSE, + buildDummyAuthResponse("vdqZZIaA", "mRjMKAQc", + "DE/AT/nj1m79jm9z", "1996-01-01", + null, "VRNCAylF", "miEklFHC")); + + final ArgumentCaptor<RequestType> zmrReq = ArgumentCaptor.forClass(RequestType.class); + BigInteger processId = new BigInteger("367100000000079"); + + // inject response + when(zmrMock.service(zmrReq.capture(), any())) + .thenReturn(loadResponseFromFile("/data/zmr/empty_zmr_result.xml")) //personalId search + .thenReturn(loadResponseFromFile("/data/zmr/empty_zmr_result.xml")) //CC specific search + .thenThrow(new RuntimeException("This request is not needed any more")); + + mockWebServer.enqueue(new MockResponse().setResponseCode(200) //personalId search + .setBody("{}") + .setHeader("Content-Type", "application/json;charset=utf-8")); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) //CC specific search + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/2_search_with_cc_specific_resp.json"), "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) //KITT search + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/2_kitt_search_latest_resp.json"), "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) //KITT update + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/2_kitt_update_resp.json"), "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute test + task.execute(pendingReq, executionContext); + + // validate state + checkMatchingSuccessState(pendingReq, "TBGoMlirU881e2jMGETa9WLx1+A=", "mRjMKAQc", + "vdqZZIaA", "1996-01-01", DE); + + // validate request + assertEquals("wrong number of req.", 2, zmrReq.getAllValues().size()); + checkBasicRequestParameters(zmrReq.getAllValues().get(0), ZmrClientTest.PROCESS_TASK_SEARCH, null, "jUnit123456"); + checkBasicRequestParameters(zmrReq.getAllValues().get(1), ZmrClientTest.PROCESS_TASK_SEARCH, processId, "jUnit123456"); + + } + /** * Find single person in ZMR by country specifics. @@ -264,6 +402,15 @@ public class InitialSearchTaskWithRegistersTest { .thenReturn(loadResponseFromFile("/data/zmr/seq_1-6_kitt_update_resp.xml")) //KITT update .thenThrow(new RuntimeException("This request is not needed any more")); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody("{}") + .setHeader("Content-Type", "application/json;charset=utf-8")); + + mockWebServer.enqueue(new MockResponse().setResponseCode(200) //CC specific search + .setBody("{}") + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute test task.execute(pendingReq, executionContext); @@ -302,7 +449,13 @@ public class InitialSearchTaskWithRegistersTest { //CC-specific will be ignored because CC is DE but BirthName and PlaceOfBirth is 'null' .thenReturn(loadResponseFromFile("/data/zmr/seq_1-2_search_with_mds_resp.xml")) //MDS specific search .thenThrow(new RuntimeException("This request is not needed any more")); - + + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody("{}") + .setHeader("Content-Type", "application/json;charset=utf-8")); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) //MDS specific search + .setBody("{}") + .setHeader("Content-Type", "application/json;charset=utf-8")); // execute test task.execute(pendingReq, executionContext); @@ -342,11 +495,23 @@ public class InitialSearchTaskWithRegistersTest { .thenThrow(new RuntimeException("This request is not needed any more")); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody("{}") + .setHeader("Content-Type", "application/json;charset=utf-8")); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) //CC specific search + .setBody("{}") + .setHeader("Content-Type", "application/json;charset=utf-8")); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) //MDS specific search + .setBody(IOUtils.toString( + ErnpRestClientTest.class.getResourceAsStream("/data/ernp/3_search_with_mds_resp.json"), "UTF-8")) + .setHeader("Content-Type", "application/json;charset=utf-8")); + + // execute test task.execute(pendingReq, executionContext); // validate state - checkIntermediateResult(2); + checkIntermediateResult(3); // validate request assertEquals("wrong number of req.", 3, zmrReq.getAllValues().size()); diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskRegisterTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskRegisterTest.java new file mode 100644 index 00000000..4f1ff61b --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskRegisterTest.java @@ -0,0 +1,337 @@ +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.assertNull; +import static org.junit.Assert.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import org.apache.commons.lang3.RandomStringUtils; +import org.jetbrains.annotations.NotNull; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +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 com.github.skjolber.mockito.soap.SoapServiceRule; +import com.google.common.collect.Lists; + +import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummyConfigMap; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController.AdresssucheOutput; +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.service.RegisterSearchService; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService.RegisterOperationStatus; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService.RegisterStatusResults; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.test.clients.ZmrClientTest; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils; +import at.gv.bmi.namespace.zmr_su.base._20040201.ResponseType; +import at.gv.bmi.namespace.zmr_su.base._20040201_.ServicePort; +import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; +import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; +import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper; +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" +}) +public class ReceiveAustrianResidenceGuiResponseTaskRegisterTest { + + @Autowired + protected MsConnectorDummyConfigMap authConfig; + + @Autowired + private RegisterSearchService registerSearchService; + + @Rule + public SoapServiceRule soap = SoapServiceRule.newInstance(); + private ServicePort zmrMock = null; + private static JAXBContext jaxbContext; + + private ReceiveAustrianResidenceGuiResponseTask task; + private ExecutionContext executionContext; + private MockHttpServletRequest httpReq; + private MockHttpServletResponse httpResp; + private TestRequestImpl pendingReq; + + + /** + * Initialize jUnit class. + */ + @BeforeClass + @SneakyThrows + public static void classInitializer() { + jaxbContext = JAXBContext.newInstance( + at.gv.bmi.namespace.zmr_su.zmr._20040201.ObjectFactory.class, + at.gv.bmi.namespace.zmr_su.gis._20070725.ObjectFactory.class, + at.gv.bmi.namespace.zmr_su.base._20040201.ObjectFactory.class); + + } + + /** + * jUnit test set-up. + * + * @throws Exception In case of an set-up error + */ + @Before + public void setUp() throws Exception { + if (zmrMock == null) { + zmrMock = soap.mock(ServicePort.class, "http://localhost:1234/demozmr"); + + } + + executionContext = new ExecutionContextImpl(); + task = new ReceiveAustrianResidenceGuiResponseTask(registerSearchService); + + httpReq = new MockHttpServletRequest("POST", "https://localhost/ms_connector"); + httpResp = new MockHttpServletResponse(); + RequestContextHolder.resetRequestAttributes(); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); + + pendingReq = new TestRequestImpl(); + pendingReq.setAuthUrl("https://localhost/ms_connector"); + pendingReq.setPendingReqId(RandomStringUtils.randomAlphanumeric(10)); + + LocaleContextHolder.resetLocaleContext(); + } + + @Test + public void canceledByUser() throws Exception { + AdresssucheOutput userInput = setupUserInput(); + SimpleEidasData eidasData = setupEidasData(); + RegisterStatusResults registerSearchResult = buildEmptyResult(); + MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); + httpReq.setParameter(ReceiveAustrianResidenceGuiResponseTask.HTTP_PARAM_NO_RESIDENCE, "true"); + + task.execute(pendingReq, executionContext); + + assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.20", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + + } + + @Test + public void noRegisterResult() throws Exception { + setupUserInput(); + setupEidasData(); + RegisterStatusResults registerSearchResult = buildEmptyResult(); + MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); + + // inject ZMR response + when(zmrMock.service(any(), any())) + .thenReturn(loadResponseFromFile("/data/zmr/empty_zmr_result.xml")); + + // execute task + task.execute(pendingReq, executionContext); + + // validate state + assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.22", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + + } + + @Test + public void exactlyOneRegisterResult_Update() throws Exception { + setupUserInput(); + SimpleEidasData eidasData = setupEidasData(); + RegisterStatusResults registerSearchResult = buildResultWithOneMatch(buildMatchingRegisterResult(eidasData)); + MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); + + // inject ZMR response + when(zmrMock.service(any(), any())) + .thenReturn(loadResponseFromFile("/data/zmr/search_with_personalId_only_resp.xml")) + .thenReturn(loadResponseFromFile("/data/zmr/seq_3-4_kitt_get_latest_version_resp.xml")) + .thenReturn(loadResponseFromFile("/data/zmr/seq_3-6_kitt_update_resp.xml")); + + task.execute(pendingReq, executionContext); + + // validate state + assertNull("Transition To S9", executionContext.get(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK)); + MatchedPersonResult matchingResult = MatchingTaskUtils.getFinalMatchingResult(pendingReq); + assertNotNull("no final matching result", matchingResult); + + } + + @Test + public void exactlyOneRegisterResult_UpdateFailedByZmrError() throws Exception { + setupUserInput(); + SimpleEidasData eidasData = setupEidasData(); + RegisterStatusResults registerSearchResult = buildResultWithOneMatch(buildMatchingRegisterResult(eidasData)); + MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); + + // inject ZMR response + when(zmrMock.service(any(), any())) + .thenReturn(loadResponseFromFile("/data/zmr/search_with_personalId_only_resp.xml")) + .thenReturn(loadResponseFromFile("/data/zmr/seq_3-4_kitt_get_latest_version_resp.xml")) + .thenThrow(new RuntimeException("ZMR update should fail for that test")); + + TaskExecutionException error = assertThrows("wrong exception", TaskExecutionException.class, + () -> task.execute(pendingReq, executionContext)); + + assertEquals("wrong errorId", "module.eidasauth.matching.04", ((EaafException) error.getOriginalException()).getErrorId()); + + } + + @Test + public void zmrError() throws Exception { + setupUserInput(); + setupEidasData(); + RegisterStatusResults registerSearchResult = buildResultWithTwoMatches(); + MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); + + TaskExecutionException error = assertThrows("wrong exception", TaskExecutionException.class, + () -> task.execute(pendingReq, executionContext)); + + assertEquals("wrong errorId", "module.eidasauth.matching.03", ((EaafException) error.getOriginalException()).getErrorId()); + + } + + @SneakyThrows + private void validateMatchedPerson(MatchedPersonResult current, + RegisterStatusResults registerUpdateResult) { + RegisterResult expected = registerUpdateResult.getResult(); + assertEquals("familyName", expected.getFamilyName(), current.getFamilyName()); + assertEquals("givenName", expected.getGivenName(), current.getGivenName()); + assertEquals("birthday", expected.getDateOfBirth(), current.getDateOfBirth()); + assertEquals("bpk", expected.getBpk(), current.getBpk()); + + } + + @NotNull + private RegisterStatusResults buildEmptyResult() { + return new RegisterStatusResults(new RegisterOperationStatus(generateRandomProcessId()), + Collections.emptyList(), Collections.emptyList()); + + } + + private BigInteger generateRandomProcessId() { + return new BigInteger(RandomStringUtils.randomNumeric(10)); + + } + + @NotNull + private RegisterStatusResults buildResultWithOneMatch(RegisterResult registerResult) { + return new RegisterStatusResults(new RegisterOperationStatus(generateRandomProcessId()), + Collections.singletonList(registerResult), Collections.emptyList()); + + } + + @NotNull + private RegisterStatusResults buildResultWithTwoMatches() { + List<RegisterResult> results = Lists.newArrayList(buildRandomRegisterResult(), buildRandomRegisterResult()); + return new RegisterStatusResults(new RegisterOperationStatus(generateRandomProcessId()), + results, Collections.emptyList()); + + } + + @NotNull + private RegisterResult buildRandomRegisterResult() { + return RegisterResult.builder() + .pseudonym(Arrays.asList(RandomStringUtils.randomAlphabetic(8))) + .givenName(RandomStringUtils.randomAlphabetic(8)) + .familyName(RandomStringUtils.randomAlphabetic(8)) + .dateOfBirth(RandomStringUtils.randomAlphabetic(8)) + .bpk(RandomStringUtils.randomAlphabetic(8)) + .build(); + + } + + private RegisterResult buildMatchingRegisterResult(SimpleEidasData eidData) { + return RegisterResult.builder() + .pseudonym(Arrays.asList(eidData.getPseudonym())) + .givenName(eidData.getGivenName()) + .familyName(eidData.getFamilyName()) + .dateOfBirth(eidData.getDateOfBirth()) + .bpk(RandomStringUtils.randomAlphabetic(8)) + .build(); + + } + + private RegisterResult buildNotMatchingRegisterResult(SimpleEidasData eidData) { + return RegisterResult.builder() + .pseudonym(Arrays.asList(eidData.getPseudonym() + RandomStringUtils.randomAlphabetic(8))) + .givenName(eidData.getGivenName()) + .familyName(eidData.getFamilyName()) + .dateOfBirth(eidData.getDateOfBirth()) + .bpk(RandomStringUtils.randomAlphabetic(8)) + .build(); + + } + + private void setHttpParameters(AdresssucheOutput input) { + httpReq.setParameter(AdresssucheController.PARAM_STREET, input.getStreet()); + httpReq.setParameter(AdresssucheController.PARAM_MUNIPICALITY, input.getMunicipality()); + httpReq.setParameter(AdresssucheController.PARAM_NUMBER, input.getNumber()); + httpReq.setParameter(AdresssucheController.PARAM_VILLAGE, input.getVillage()); + httpReq.setParameter(AdresssucheController.PARAM_POSTLEITZAHL, input.getPostleitzahl()); + + } + + @NotNull + private SimpleEidasData setupEidasData() throws EaafStorageException { + SimpleEidasData result = SimpleEidasData.builder() + .pseudonym(RandomStringUtils.randomAlphabetic(8)) + .familyName(RandomStringUtils.randomAlphabetic(8)) + .givenName(RandomStringUtils.randomAlphabetic(8)) + .dateOfBirth("1970-01-01") + .build(); + AuthProcessDataWrapper authProcessDataWrapper = pendingReq.getSessionData(AuthProcessDataWrapper.class); + authProcessDataWrapper.setGenericDataToSession(Constants.DATA_SIMPLE_EIDAS, result); + return result; + } + + @NotNull + private AdresssucheOutput setupUserInput() { + AdresssucheOutput result = new AdresssucheOutput( + RandomStringUtils.randomAlphabetic(8), + RandomStringUtils.randomAlphabetic(8), + RandomStringUtils.randomAlphabetic(8), + RandomStringUtils.randomAlphabetic(8), + RandomStringUtils.randomAlphabetic(8)); + setHttpParameters(result); + return result; + } + + private ResponseType loadResponseFromFile(String filepath) throws JAXBException { + final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + JAXBElement<?> resp = (JAXBElement<?>) unmarshaller.unmarshal(ZmrClientTest.class.getResourceAsStream( + filepath)); + return (ResponseType) resp.getValue(); + + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskTest.java index 64bb0d48..7758e021 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskTest.java @@ -1,14 +1,9 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.tasks; -import static at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask.PARAM_CITY; -import static at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask.PARAM_FORMER_RESIDENCE_AVAILABLE; -import static at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask.PARAM_STREET; -import static at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask.PARAM_ZIPCODE; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.eq; -import static org.springframework.util.Assert.isInstanceOf; import java.math.BigInteger; import java.util.Arrays; @@ -21,7 +16,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.i18n.LocaleContextHolder; @@ -36,21 +30,22 @@ import com.google.common.collect.Lists; import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummyConfigMap; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController.AdresssucheOutput; +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.ManualFixNecessaryException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService.RegisterOperationStatus; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService.RegisterStatusResults; import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask.UserInput; 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.auth.data.AuthProcessDataWrapper; 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 = { @@ -67,7 +62,7 @@ public class ReceiveAustrianResidenceGuiResponseTaskTest { private ReceiveAustrianResidenceGuiResponseTask task; - private final ExecutionContext executionContext = new ExecutionContextImpl(); + private ExecutionContext executionContext; private MockHttpServletRequest httpReq; private MockHttpServletResponse httpResp; private TestRequestImpl pendingReq; @@ -79,8 +74,9 @@ public class ReceiveAustrianResidenceGuiResponseTaskTest { */ @Before public void setUp() throws Exception { + executionContext = new ExecutionContextImpl(); task = new ReceiveAustrianResidenceGuiResponseTask(registerSearchService); - + httpReq = new MockHttpServletRequest("POST", "https://localhost/ms_connector"); httpResp = new MockHttpServletResponse(); RequestContextHolder.resetRequestAttributes(); @@ -94,8 +90,40 @@ public class ReceiveAustrianResidenceGuiResponseTaskTest { } @Test + public void canceledByUser() throws Exception { + AdresssucheOutput userInput = setupUserInput(); + SimpleEidasData eidasData = setupEidasData(); + RegisterStatusResults registerSearchResult = buildEmptyResult(); + mockRegisterSearch(userInput, registerSearchResult, eidasData); + MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); + httpReq.setParameter(ReceiveAustrianResidenceGuiResponseTask.HTTP_PARAM_NO_RESIDENCE, "true"); + + task.execute(pendingReq, executionContext); + + assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.20", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + + } + + @Test + public void noInputData() throws Exception { + RegisterStatusResults registerSearchResult = buildEmptyResult(); + MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); + + task.execute(pendingReq, executionContext); + + assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.21", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + + } + + @Test public void noRegisterResult() throws Exception { - UserInput userInput = setupUserInput(); + AdresssucheOutput userInput = setupUserInput(); SimpleEidasData eidasData = setupEidasData(); RegisterStatusResults registerSearchResult = buildEmptyResult(); mockRegisterSearch(userInput, registerSearchResult, eidasData); @@ -103,56 +131,86 @@ public class ReceiveAustrianResidenceGuiResponseTaskTest { task.execute(pendingReq, executionContext); - assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK)); + assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.22", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + } @Test - public void exactlyOneRegisterResult_Matching() throws Exception { - UserInput userInput = setupUserInput(); + public void exactlyOneRegisterResult_NoUpdate() throws Exception { + AdresssucheOutput userInput = setupUserInput(); SimpleEidasData eidasData = setupEidasData(); RegisterStatusResults registerSearchResult = buildResultWithOneMatch(buildMatchingRegisterResult(eidasData)); MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); mockRegisterSearch(userInput, registerSearchResult, eidasData); task.execute(pendingReq, executionContext); - + + // validate state assertNull("Transition To S9", executionContext.get(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK)); - Mockito.verify(registerSearchService).step7aKittProcess(eq(registerSearchResult), eq(eidasData)); - + MatchedPersonResult matchingResult = MatchingTaskUtils.getFinalMatchingResult(pendingReq); + assertNotNull("no final matching result", matchingResult); + validateMatchedPerson(matchingResult, registerSearchResult); + } @Test - public void exactlyOneRegisterResult_NotMatching() throws Exception { - UserInput userInput = setupUserInput(); + public void exactlyOneRegisterResult_UpdateRequired() throws Exception { + AdresssucheOutput userInput = setupUserInput(); SimpleEidasData eidasData = setupEidasData(); RegisterStatusResults registerSearchResult = buildResultWithOneMatch(buildNotMatchingRegisterResult(eidasData)); + RegisterStatusResults registerUpdateResult = buildResultWithOneMatch(buildRandomRegisterResult()); MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); mockRegisterSearch(userInput, registerSearchResult, eidasData); - + Mockito.when(registerSearchService.step7aKittProcess(eq(registerSearchResult), eq(eidasData))) + .thenReturn(registerUpdateResult); + + // perform test task.execute(pendingReq, executionContext); - assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK)); + // validate state + assertNull("Transition To S9", executionContext.get(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK)); + + MatchedPersonResult matchingResult = MatchingTaskUtils.getFinalMatchingResult(pendingReq); + assertNotNull("no final matching result", matchingResult); + validateMatchedPerson(matchingResult, registerUpdateResult); + } @Test public void moreThanOneRegisterResult() throws Exception { - UserInput userInput = setupUserInput(); + AdresssucheOutput userInput = setupUserInput(); SimpleEidasData eidasData = setupEidasData(); RegisterStatusResults registerSearchResult = buildResultWithTwoMatches(); MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); mockRegisterSearch(userInput, registerSearchResult, eidasData); - TaskExecutionException e = assertThrows(TaskExecutionException.class, - () -> task.execute(pendingReq, executionContext)); + task.execute(pendingReq, executionContext); - assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); - isInstanceOf(ManualFixNecessaryException.class, e.getOriginalException()); - assertNull("Transition To S16", executionContext.get(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK)); + assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.22", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + } - private void mockRegisterSearch(UserInput userInput, RegisterStatusResults registerSearchResult, SimpleEidasData eidasData ) { + @SneakyThrows + private void validateMatchedPerson(MatchedPersonResult current, + RegisterStatusResults registerUpdateResult) { + RegisterResult expected = registerUpdateResult.getResult(); + assertEquals("familyName", expected.getFamilyName(), current.getFamilyName()); + assertEquals("givenName", expected.getGivenName(), current.getGivenName()); + assertEquals("birthday", expected.getDateOfBirth(), current.getDateOfBirth()); + assertEquals("bpk", expected.getBpk(), current.getBpk()); + + } + + @SneakyThrows + private void mockRegisterSearch(AdresssucheOutput userInput, RegisterStatusResults registerSearchResult, SimpleEidasData eidasData ) { Mockito.when(registerSearchService.searchWithResidence(eq(registerSearchResult.getOperationStatus()), eq(eidasData), - eq(userInput.getZipcode()), eq(userInput.getCity()), eq(userInput.getStreet()))).thenReturn(registerSearchResult); + eq(userInput))).thenReturn(registerSearchResult); } @NotNull @@ -216,11 +274,13 @@ public class ReceiveAustrianResidenceGuiResponseTaskTest { } - private void setHttpParameters(UserInput input) { - httpReq.setParameter(PARAM_FORMER_RESIDENCE_AVAILABLE, String.valueOf(input.isFormerResidenceAvailable())); - httpReq.setParameter(PARAM_STREET, input.getStreet()); - httpReq.setParameter(PARAM_CITY, input.getCity()); - httpReq.setParameter(PARAM_ZIPCODE, input.getZipcode()); + private void setHttpParameters(AdresssucheOutput input) { + httpReq.setParameter(AdresssucheController.PARAM_STREET, input.getStreet()); + httpReq.setParameter(AdresssucheController.PARAM_MUNIPICALITY, input.getMunicipality()); + httpReq.setParameter(AdresssucheController.PARAM_NUMBER, input.getNumber()); + httpReq.setParameter(AdresssucheController.PARAM_VILLAGE, input.getVillage()); + httpReq.setParameter(AdresssucheController.PARAM_POSTLEITZAHL, input.getPostleitzahl()); + } @NotNull @@ -237,8 +297,13 @@ public class ReceiveAustrianResidenceGuiResponseTaskTest { } @NotNull - private UserInput setupUserInput() { - UserInput result = new UserInput(true, RandomStringUtils.randomAlphabetic(8), RandomStringUtils.randomAlphabetic(8), RandomStringUtils.randomAlphabetic(8)); + private AdresssucheOutput setupUserInput() { + AdresssucheOutput result = new AdresssucheOutput( + RandomStringUtils.randomAlphabetic(8), + RandomStringUtils.randomAlphabetic(8), + RandomStringUtils.randomAlphabetic(8), + RandomStringUtils.randomAlphabetic(8), + RandomStringUtils.randomAlphabetic(8)); setHttpParameters(result); return result; } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseTaskTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseTaskTest.java index d5400695..b9133392 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseTaskTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseTaskTest.java @@ -282,7 +282,10 @@ public class ReceiveMobilePhoneSignatureResponseTaskTest { task.execute(pendingReq, executionContext); - assertEquals("Transition To S16", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_GUI_QUERY_AUSTRIAN_RESIDENCE_TASK)); + assertEquals("Transition To S16", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.23", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); } @@ -326,7 +329,10 @@ public class ReceiveMobilePhoneSignatureResponseTaskTest { task.execute(pendingReq, executionContext); assertEquals("Next task", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); - assertEquals("advancedMatchingError flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.24", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + } //TODO: implement new test that this test makes no sense any more diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties index be716e95..d84777f3 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties @@ -8,9 +8,9 @@ eidas.ms.context.use.clustermode=true eidas.ms.monitoring.eIDASNode.metadata.url= -eidas.ms.client.http.connection.timeout.socket=1 -eidas.ms.client.http.connection.timeout.connection=1 -eidas.ms.client.http.connection.timeout.request=1 +eidas.ms.client.http.connection.timeout.socket=5 +eidas.ms.client.http.connection.timeout.connection=5 +eidas.ms.client.http.connection.timeout.request=5 ##Specific logger configuration @@ -100,6 +100,19 @@ eidas.ms.auth.eIDAS.zmrclient.req.organisation.behoerdennr=jUnit123456 eidas.ms.auth.eIDAS.zmrclient.req.update.reason.code=EIDAS-KITT + +# ERnP communication +eidas.ms.auth.eIDAS.ernpclient.endpoint=http://localhost:1718/demoernp +eidas.ms.auth.eIDAS.ernpclient.req.organisation.behoerdennr=jUnit123456 +eidas.ms.auth.eIDAS.client.common.ssl.keyStore.type=jks +eidas.ms.auth.eIDAS.client.common.ssl.keyStore.path=../keystore/junit_test.jks +eidas.ms.auth.eIDAS.client.common.ssl.keyStore.password=password +eidas.ms.auth.eIDAS.client.common.ssl.key.alias=meta +eidas.ms.auth.eIDAS.client.common.ssl.key.password=password + + + +#### SP End-Points ##### ## PVP2 S-Profile end-point configuration eidas.ms.pvp2.keystore.path=keys/..... eidas.ms.pvp2.keystore.password= diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1_springboot.properties b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1_springboot.properties index 224e1b1f..0cc89a4a 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1_springboot.properties +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1_springboot.properties @@ -57,7 +57,18 @@ eidas.ms.auth.eIDAS.zmrclient.req.organisation.behoerdennr=jUnit123456 eidas.ms.auth.eIDAS.zmrclient.req.update.reason.code=EIDAS-KITT eidas.ms.auth.eIDAS.zmrclient.req.update.reason.text=KITT for eIDAS Matching +# ERnP communication +eidas.ms.auth.eIDAS.ernpclient.endpoint=http://localhost:1718/demoernp +eidas.ms.auth.eIDAS.ernpclient.req.organisation.behoerdennr=jUnit123456 +eidas.ms.auth.eIDAS.client.common.ssl.keyStore.type=jks +eidas.ms.auth.eIDAS.client.common.ssl.keyStore.path=../keystore/junit_test.jks +eidas.ms.auth.eIDAS.client.common.ssl.keyStore.password=password +eidas.ms.auth.eIDAS.client.common.ssl.key.alias=meta +eidas.ms.auth.eIDAS.client.common.ssl.key.password=password + + +#### SP End-Points ##### ## PVP2 S-Profile end-point configuration eidas.ms.pvp2.keystore.type=jks eidas.ms.pvp2.keystore.path=keys/junit.jks diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_add_req.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_add_req.json new file mode 100644 index 00000000..4f823c60 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_add_req.json @@ -0,0 +1,30 @@ +{ + "begruendung": "Add new person", + "personendaten": { + "familienname": "CtKKrtUe", + "vorname": "dUeYzUFg", + "geburtsdatum": { + "jahr": 1985, + "monat": 5, + "tag": 5 + } + }, + "anschrift": null, + "eidas": [ + { + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "wert": "Y8ADWaeh0h", + "staatscode2": "DE" + }, + { + "art": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", + "wert": "hrFevCfP", + "staatscode2": "DE" + }, + { + "art": "http://eidas.europa.eu/attributes/naturalperson/BirthName", + "wert": "sNUEAhEr", + "staatscode2": "DE" + } + ] +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_add_resp.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_add_resp.json new file mode 100644 index 00000000..139483cf --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_add_resp.json @@ -0,0 +1,60 @@ +{ + "person": { + "type": "Person", + "eidas": [ + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000486", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "staatscode2": "DE", + "wert": "Y8ADWaeh0h" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000488", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "staatscode2": "DE", + "wert": "hrFevCfP" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/BirthName", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000490", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "staatscode2": "DE", + "wert": "sNUEAhEr" + } + ], + "entityId": "1933000000000475", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "letzteOperation": { + "begruendung": "Add new person", + "durchgefuehrtVon": { + "behoerdenkennzeichen": "380630", + "benutzer": "eidtapp@bmi.gv.at" + }, + "vorgang": "PersonAnlegen", + "zeitpunkt": "2022-03-03T11:07:28.885+01:00" + }, + "personendaten": { + "basiszahl": "000482591530", + "bpkZp": "+OQnljn0Son1W2rkM73nP/VMsvc=", + "entityId": "1933000000000475", + "familienname": "CtKKrtUe", + "geburtsdatum": { + "jahr": 1985, + "monat": 5, + "tag": 5 + }, + "geprueft": false, + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "vorname": "dUeYzUFg" + }, + "version": "2022-03-03T11:07:28.885+01:00" + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_search_latest_req.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_search_latest_req.json new file mode 100644 index 00000000..2538ebac --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_search_latest_req.json @@ -0,0 +1,19 @@ +{ + "begruendung": "KITT get-latest-version", + "suchoptionen": { + "historisch": "AktuellUndHistorisch", + "sucheMitNamensteilen": false, + "suchwizard": false, + "zmr": false + }, + "suchdaten": { + "bpkZp": "+OQnljn0Son1W2rkM73nP/VMsvc=", + "familienname": "CtKKrtUe", + "vorname": "dUeYzUFg", + "geburtsdatum": { + "jahr": 1985, + "monat": 5, + "tag": 5 + } + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_search_latest_resp.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_search_latest_resp.json new file mode 100644 index 00000000..588153cd --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_search_latest_resp.json @@ -0,0 +1,62 @@ +{ + "person": [ + { + "type": "Person", + "eidas": [ + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000486", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "staatscode2": "DE", + "wert": "Y8ADWaeh0h" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000488", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "staatscode2": "DE", + "wert": "hrFevCfP" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/BirthName", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000490", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "staatscode2": "DE", + "wert": "sNUEAhEr" + } + ], + "entityId": "1933000000000475", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "letzteOperation": { + "begruendung": "Add new person", + "durchgefuehrtVon": { + "behoerdenkennzeichen": "380630", + "benutzer": "eidtapp@bmi.gv.at" + }, + "vorgang": "PersonAnlegen", + "zeitpunkt": "2022-03-03T11:07:28.885+01:00" + }, + "personendaten": { + "basiszahl": "000482591530", + "bpkZp": "+OQnljn0Son1W2rkM73nP/VMsvc=", + "entityId": "1933000000000475", + "familienname": "CtKKrtUe", + "geburtsdatum": { + "jahr": 1985, + "monat": 5, + "tag": 5 + }, + "geprueft": false, + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "vorname": "dUeYzUFg" + }, + "version": "2022-03-03T11:07:28.885+01:00" + } + ] +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_update_req.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_update_req.json new file mode 100644 index 00000000..194fba1d --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_update_req.json @@ -0,0 +1,17 @@ +{ + "begruendung": "KITT update dataset", + "aendern": { + "personendaten": { + "entityId": "1933000000000475", + "familienname": "mVzTMpig6r", + "vorname": "Jb2vj1Xpql", + "geburtsdatum": { + "jahr": 1985, + "monat": 5, + "tag": 5 + } + } + }, + "entityId": "1933000000000475", + "version": "2022-03-03T10:07:28.885Z" +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_update_resp.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_update_resp.json new file mode 100644 index 00000000..7fe9210a --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_update_resp.json @@ -0,0 +1,60 @@ +{ + "person": { + "type": "Person", + "eidas": [ + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000486", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "staatscode2": "DE", + "wert": "Y8ADWaeh0h" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000488", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "staatscode2": "DE", + "wert": "hrFevCfP" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/BirthName", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000490", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "staatscode2": "DE", + "wert": "sNUEAhEr" + } + ], + "entityId": "1933000000000475", + "gueltigAb": "2022-03-03T11:07:29.751+01:00", + "letzteOperation": { + "begruendung": "KITT update dataset", + "durchgefuehrtVon": { + "behoerdenkennzeichen": "380630", + "benutzer": "eidtapp@bmi.gv.at" + }, + "vorgang": "PersonAendern", + "zeitpunkt": "2022-03-03T11:07:29.751+01:00" + }, + "personendaten": { + "basiszahl": "000482591530", + "bpkZp": "+OQnljn0Son1W2rkM73nP/VMsvc=", + "entityId": "1933000000000475", + "familienname": "mVzTMpig6r", + "geburtsdatum": { + "jahr": 1985, + "monat": 5, + "tag": 5 + }, + "geprueft": false, + "gueltigAb": "2022-03-03T11:07:29.751+01:00", + "vorname": "Jb2vj1Xpql" + }, + "version": "2022-03-03T11:07:29.751+01:00" + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_search_with_personalId_req.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_search_with_personalId_req.json new file mode 100644 index 00000000..d7344f08 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_search_with_personalId_req.json @@ -0,0 +1,20 @@ +{ + "begruendung": "Searching PersonIdentifier", + "suchoptionen": { + "historisch": "AktuellUndHistorisch", + "sucheMitNamensteilen": false, + "suchwizard": false, + "zmr": false + }, + "suchdaten": { + "familienname": null, + "vorname": null, + "eidas": [ + { + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "wert": "Y8ADWaeh0h", + "staatscode2": "DE" + } + ] + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_search_with_personalId_resp.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_search_with_personalId_resp.json new file mode 100644 index 00000000..588153cd --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_search_with_personalId_resp.json @@ -0,0 +1,62 @@ +{ + "person": [ + { + "type": "Person", + "eidas": [ + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000486", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "staatscode2": "DE", + "wert": "Y8ADWaeh0h" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000488", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "staatscode2": "DE", + "wert": "hrFevCfP" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/BirthName", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000490", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "staatscode2": "DE", + "wert": "sNUEAhEr" + } + ], + "entityId": "1933000000000475", + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "letzteOperation": { + "begruendung": "Add new person", + "durchgefuehrtVon": { + "behoerdenkennzeichen": "380630", + "benutzer": "eidtapp@bmi.gv.at" + }, + "vorgang": "PersonAnlegen", + "zeitpunkt": "2022-03-03T11:07:28.885+01:00" + }, + "personendaten": { + "basiszahl": "000482591530", + "bpkZp": "+OQnljn0Son1W2rkM73nP/VMsvc=", + "entityId": "1933000000000475", + "familienname": "CtKKrtUe", + "geburtsdatum": { + "jahr": 1985, + "monat": 5, + "tag": 5 + }, + "geprueft": false, + "gueltigAb": "2022-03-03T11:07:28.885+01:00", + "vorname": "dUeYzUFg" + }, + "version": "2022-03-03T11:07:28.885+01:00" + } + ] +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_add_req.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_add_req.json new file mode 100644 index 00000000..35e52c10 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_add_req.json @@ -0,0 +1,30 @@ +{ + "begruendung": "Add new person", + "personendaten": { + "familienname": "mRjMKAQc", + "vorname": "vdqZZIaA", + "geburtsdatum": { + "jahr": 1996, + "monat": 1, + "tag": 1 + } + }, + "anschrift": null, + "eidas": [ + { + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "wert": "88hvWzUaIX", + "staatscode2": "DE" + }, + { + "art": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", + "wert": "VRNCAylF", + "staatscode2": "DE" + }, + { + "art": "http://eidas.europa.eu/attributes/naturalperson/BirthName", + "wert": "miEklFHC", + "staatscode2": "DE" + } + ] +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_add_resp.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_add_resp.json new file mode 100644 index 00000000..7f85a143 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_add_resp.json @@ -0,0 +1,60 @@ +{ + "person": { + "type": "Person", + "eidas": [ + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000509", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "staatscode2": "DE", + "wert": "88hvWzUaIX" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000511", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "staatscode2": "DE", + "wert": "VRNCAylF" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/BirthName", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000513", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "staatscode2": "DE", + "wert": "miEklFHC" + } + ], + "entityId": "1933000000000498", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "letzteOperation": { + "begruendung": "Add new person", + "durchgefuehrtVon": { + "behoerdenkennzeichen": "380630", + "benutzer": "eidtapp@bmi.gv.at" + }, + "vorgang": "PersonAnlegen", + "zeitpunkt": "2022-03-03T11:14:59.712+01:00" + }, + "personendaten": { + "basiszahl": "000951265372", + "bpkZp": "TBGoMlirU881e2jMGETa9WLx1+A=", + "entityId": "1933000000000498", + "familienname": "mRjMKAQc", + "geburtsdatum": { + "jahr": 1996, + "monat": 1, + "tag": 1 + }, + "geprueft": false, + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "vorname": "vdqZZIaA" + }, + "version": "2022-03-03T11:14:59.712+01:00" + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_search_latest_req.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_search_latest_req.json new file mode 100644 index 00000000..d3dd0658 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_search_latest_req.json @@ -0,0 +1,19 @@ +{ + "begruendung": "KITT get-latest-version", + "suchoptionen": { + "historisch": "AktuellUndHistorisch", + "sucheMitNamensteilen": false, + "suchwizard": false, + "zmr": false + }, + "suchdaten": { + "bpkZp": "TBGoMlirU881e2jMGETa9WLx1+A=", + "familienname": "mRjMKAQc", + "vorname": "vdqZZIaA", + "geburtsdatum": { + "jahr": 1996, + "monat": 1, + "tag": 1 + } + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_search_latest_resp.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_search_latest_resp.json new file mode 100644 index 00000000..24009e64 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_search_latest_resp.json @@ -0,0 +1,62 @@ +{ + "person": [ + { + "type": "Person", + "eidas": [ + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000509", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "staatscode2": "DE", + "wert": "88hvWzUaIX" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000511", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "staatscode2": "DE", + "wert": "VRNCAylF" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/BirthName", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000513", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "staatscode2": "DE", + "wert": "miEklFHC" + } + ], + "entityId": "1933000000000498", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "letzteOperation": { + "begruendung": "Add new person", + "durchgefuehrtVon": { + "behoerdenkennzeichen": "380630", + "benutzer": "eidtapp@bmi.gv.at" + }, + "vorgang": "PersonAnlegen", + "zeitpunkt": "2022-03-03T11:14:59.712+01:00" + }, + "personendaten": { + "basiszahl": "000951265372", + "bpkZp": "TBGoMlirU881e2jMGETa9WLx1+A=", + "entityId": "1933000000000498", + "familienname": "mRjMKAQc", + "geburtsdatum": { + "jahr": 1996, + "monat": 1, + "tag": 1 + }, + "geprueft": false, + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "vorname": "vdqZZIaA" + }, + "version": "2022-03-03T11:14:59.712+01:00" + } + ] +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_update_req.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_update_req.json new file mode 100644 index 00000000..0e4a9b21 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_update_req.json @@ -0,0 +1,14 @@ +{ + "begruendung": "KITT update dataset", + "anlegen": { + "eidas": [ + { + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "wert": "nj1m79jm9z", + "staatscode2": "DE" + } + ] + }, + "entityId": "1933000000000498", + "version": "2022-03-03T10:14:59.712Z" +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_update_resp.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_update_resp.json new file mode 100644 index 00000000..23dc74f3 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_update_resp.json @@ -0,0 +1,69 @@ +{ + "person": { + "type": "Person", + "eidas": [ + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000509", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "staatscode2": "DE", + "wert": "88hvWzUaIX" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000511", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "staatscode2": "DE", + "wert": "VRNCAylF" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/BirthName", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000513", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "staatscode2": "DE", + "wert": "miEklFHC" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933100000000607", + "gueltigAb": "2022-03-03T11:15:00.762+01:00", + "staatscode2": "DE", + "wert": "nj1m79jm9z" + } + ], + "entityId": "1933000000000498", + "gueltigAb": "2022-03-03T11:15:00.762+01:00", + "letzteOperation": { + "begruendung": "KITT update dataset", + "durchgefuehrtVon": { + "behoerdenkennzeichen": "380630", + "benutzer": "eidtapp@bmi.gv.at" + }, + "vorgang": "PersonAendern", + "zeitpunkt": "2022-03-03T11:15:00.762+01:00" + }, + "personendaten": { + "basiszahl": "000951265372", + "bpkZp": "TBGoMlirU881e2jMGETa9WLx1+A=", + "entityId": "1933000000000498", + "familienname": "mRjMKAQc", + "geburtsdatum": { + "jahr": 1996, + "monat": 1, + "tag": 1 + }, + "geprueft": false, + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "vorname": "vdqZZIaA" + }, + "version": "2022-03-03T11:15:00.762+01:00" + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_search_with_cc_specific_req.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_search_with_cc_specific_req.json new file mode 100644 index 00000000..d80b0d2e --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_search_with_cc_specific_req.json @@ -0,0 +1,30 @@ +{ + "begruendung": "Searching DE specific", + "suchoptionen": { + "historisch": "AktuellUndHistorisch", + "sucheMitNamensteilen": false, + "suchwizard": false, + "zmr": false + }, + "suchdaten": { + "familienname": "mRjMKAQc", + "vorname": "vdqZZIaA", + "geburtsdatum": { + "jahr": 1996, + "monat": 1, + "tag": 1 + }, + "eidas": [ + { + "art": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", + "wert": "VRNCAylF", + "staatscode2": "DE" + }, + { + "art": "http://eidas.europa.eu/attributes/naturalperson/BirthName", + "wert": "miEklFHC", + "staatscode2": "DE" + } + ] + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_search_with_cc_specific_resp.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_search_with_cc_specific_resp.json new file mode 100644 index 00000000..24009e64 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_search_with_cc_specific_resp.json @@ -0,0 +1,62 @@ +{ + "person": [ + { + "type": "Person", + "eidas": [ + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000509", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "staatscode2": "DE", + "wert": "88hvWzUaIX" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PlaceOfBirth", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000511", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "staatscode2": "DE", + "wert": "VRNCAylF" + }, + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/BirthName", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000513", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "staatscode2": "DE", + "wert": "miEklFHC" + } + ], + "entityId": "1933000000000498", + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "letzteOperation": { + "begruendung": "Add new person", + "durchgefuehrtVon": { + "behoerdenkennzeichen": "380630", + "benutzer": "eidtapp@bmi.gv.at" + }, + "vorgang": "PersonAnlegen", + "zeitpunkt": "2022-03-03T11:14:59.712+01:00" + }, + "personendaten": { + "basiszahl": "000951265372", + "bpkZp": "TBGoMlirU881e2jMGETa9WLx1+A=", + "entityId": "1933000000000498", + "familienname": "mRjMKAQc", + "geburtsdatum": { + "jahr": 1996, + "monat": 1, + "tag": 1 + }, + "geprueft": false, + "gueltigAb": "2022-03-03T11:14:59.712+01:00", + "vorname": "vdqZZIaA" + }, + "version": "2022-03-03T11:14:59.712+01:00" + } + ] +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/3_search_with_mds_req.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/3_search_with_mds_req.json new file mode 100644 index 00000000..eb382bc0 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/3_search_with_mds_req.json @@ -0,0 +1,18 @@ +{ + "begruendung": "Searching with MDS only", + "suchoptionen": { + "historisch": "AktuellUndHistorisch", + "sucheMitNamensteilen": false, + "suchwizard": false, + "zmr": false + }, + "suchdaten": { + "familienname": "DOPISN[0xc3][0x8d]", + "vorname": "DANA", + "geburtsdatum": { + "jahr": 1996, + "monat": 1, + "tag": 1 + } + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/3_search_with_mds_resp.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/3_search_with_mds_resp.json new file mode 100644 index 00000000..87be362d --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/3_search_with_mds_resp.json @@ -0,0 +1,44 @@ +{ + "person": [ + { + "type": "Person", + "eidas": [ + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000058", + "gueltigAb": "2022-03-02T16:23:32.743+01:00", + "staatscode2": "CZ", + "wert": "7cEYWithDEElementsasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit" + } + ], + "entityId": "1933000000000047", + "gueltigAb": "2022-03-02T16:23:32.743+01:00", + "letzteOperation": { + "begruendung": "Add new person", + "durchgefuehrtVon": { + "behoerdenkennzeichen": "380630", + "benutzer": "eidtapp@bmi.gv.at" + }, + "vorgang": "PersonAnlegen", + "zeitpunkt": "2022-03-02T16:23:32.743+01:00" + }, + "personendaten": { + "basiszahl": "000501189333", + "bpkZp": "vypyCkyczK7i+cgPWlJasuJphIA=", + "entityId": "1933000000000047", + "familienname": "DOPISNÍ", + "geburtsdatum": { + "jahr": 1996, + "monat": 1, + "tag": 1 + }, + "geprueft": false, + "gueltigAb": "2022-03-02T16:23:32.743+01:00", + "vorname": "DANA" + }, + "version": "2022-03-02T16:23:32.743+01:00" + } + ] +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/4_search_with_mds_multi_resp.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/4_search_with_mds_multi_resp.json new file mode 100644 index 00000000..87a23647 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/4_search_with_mds_multi_resp.json @@ -0,0 +1,84 @@ +{ + "person": [ + { + "type": "Person", + "eidas": [ + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933000000000653", + "gueltigAb": "2022-03-03T11:27:57.651+01:00", + "staatscode2": "XZ", + "wert": "ybgLmbYGxU" + } + ], + "entityId": "1933000000000642", + "gueltigAb": "2022-03-03T11:27:57.651+01:00", + "letzteOperation": { + "begruendung": "Add new person", + "durchgefuehrtVon": { + "behoerdenkennzeichen": "380630", + "benutzer": "eidtapp@bmi.gv.at" + }, + "vorgang": "PersonAnlegen", + "zeitpunkt": "2022-03-03T11:27:57.651+01:00" + }, + "personendaten": { + "basiszahl": "000693812023", + "bpkZp": "QJ/5YLEbOCfRhG5R0KKHNnmeMYo=", + "entityId": "1933000000000642", + "familienname": "HjecFKGu", + "geburtsdatum": { + "jahr": 1996, + "monat": 1, + "tag": 1 + }, + "geprueft": false, + "gueltigAb": "2022-03-03T11:27:57.651+01:00", + "vorname": "QwnAMXsJ" + }, + "version": "2022-03-03T11:27:57.651+01:00" + }, + { + "type": "Person", + "eidas": [ + { + "ablaufDatum": "9999-12-31T00:00:00.000+01:00", + "art": "http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier", + "ausstellDatum": "9999-12-31T00:00:00.000+01:00", + "entityId": "1933100000000762", + "gueltigAb": "2022-03-03T11:27:57.885+01:00", + "staatscode2": "XZ", + "wert": "rEhBYWgiSx" + } + ], + "entityId": "1933100000000751", + "gueltigAb": "2022-03-03T11:27:57.885+01:00", + "letzteOperation": { + "begruendung": "Add new person", + "durchgefuehrtVon": { + "behoerdenkennzeichen": "380630", + "benutzer": "eidtapp@bmi.gv.at" + }, + "vorgang": "PersonAnlegen", + "zeitpunkt": "2022-03-03T11:27:57.885+01:00" + }, + "personendaten": { + "basiszahl": "000803465934", + "bpkZp": "ZaJ2Yvx0u/z8VqNyCJ8zKT8XQa0=", + "entityId": "1933100000000751", + "familienname": "HjecFKGu", + "geburtsdatum": { + "jahr": 1996, + "monat": 1, + "tag": 1 + }, + "geprueft": false, + "gueltigAb": "2022-03-03T11:27:57.885+01:00", + "vorname": "QwnAMXsJ" + }, + "version": "2022-03-03T11:27:57.885+01:00" + } + ] +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/4_search_with_mds_req.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/4_search_with_mds_req.json new file mode 100644 index 00000000..01c3c3f9 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/4_search_with_mds_req.json @@ -0,0 +1,18 @@ +{ + "begruendung": "Searching with MDS only", + "suchoptionen": { + "historisch": "AktuellUndHistorisch", + "sucheMitNamensteilen": false, + "suchwizard": false, + "zmr": false + }, + "suchdaten": { + "familienname": "HjecFKGu", + "vorname": "QwnAMXsJ", + "geburtsdatum": { + "jahr": 1996, + "monat": 1, + "tag": 1 + } + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/ernp_empty_resp.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/ernp_empty_resp.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/ernp_empty_resp.json @@ -0,0 +1 @@ +{} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/ernp_handbook_example.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/ernp_handbook_example.json new file mode 100644 index 00000000..f4485ff7 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/ernp_handbook_example.json @@ -0,0 +1,85 @@ +{ + "person": [ + { + "type": "Person", + "anschrift": { + "type": "AnschriftInland", + "adressstatus": "XXXXXXXXX", + "codes": { + "gemeindekennziffer": "09988", + "strassenkennziffer": "T80001" + }, + "entityId": 33069800000171092, + "gemeinde": "Testgemeinde", + "gueltigAb": "2011-09-06T11:23:55.306+02:00", + "hausnummer": "99", + "postleitzahl": "0077", + "postort": "Testpostort 77 mit maximalmögl. Längen", + "staat": { + "isoCode3": "AUT", + "name": "Österreich" + }, + "strasse": "Testgasse" + }, + "entityId": 33069800000171080, + "gueltigAb": "2011-09-06T11:23:55.306+02:00", + "letzteOperation": { + "begruendung": "Testperson", + "durchgefuehrtVon": { + "behoerdenkennzeichen": "346743", + "benutzer": "xlechne@bmi.gv.at" + }, + "vorgang": "PERSON_ANLEGEN", + "zeitpunkt": "2011-09-06T11:23:55.306+02:00" + }, + "personendaten": { + "basiszahl": "000766083209", + "bpkZp": "BC1ifQanMKaDQG0yLBPbQ9AHgb4=", + "entityId": 33069800000171080, + "familienname": "XXXSZR", + "geburtsbundesland": "Wien", + "geburtsdatum": { + "jahr": 1985, + "monat": 1, + "tag": 1 + }, + "geburtsort": "Wien", + "geburtsstaat": { + "isoCode3": "AUT", + "name": "Österreich" + }, + "geprueft": true, + "geschlecht": "Männlich", + "gueltigAb": "2011-09-06T11:23:55.306+02:00", + "vorname": "XXXTest" + }, + "reisedokument": [ + { + "art": "Personalausweis", + "ausgestelltVon": { + "behoerde": "Wien", + "datum": "1985-01-01T00:00:00.000+01:00", + "staat": { + "isoCode3": "AUT", + "name": "Österreich" + } + }, + "entityId": 33069800000171090, + "gueltigAb": "2011-09-06T11:23:55.306+02:00", + "nummer": "123456789" + } + ], + "staatsangehoerigkeit": [ + { + "entityId": 33069800000171084, + "gueltigAb": "2011-09-06T11:23:55.306+02:00", + "staat": { + "isoCode3": "AUT", + "name": "Österreich" + } + } + ], + "version": "2011-09-06T11:23:55.306+02:00" + } + ] +}
\ No newline at end of file diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/error_resp.json b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/error_resp.json new file mode 100644 index 00000000..76e3e7ba --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/error_resp.json @@ -0,0 +1,12 @@ +{ + "faultDetails": { + "fault": [ + { + "key": "suchdaten", + "message": "Mindestsuchkriterien sind: Vorname & Familienname & Geburtsdatum (statt Familienname kann auch Name vor Ehe angegeben werden) oder mindestens ein Eidas Attribut (Art & Wert & Staat)" + } + ], + "faultNumber": 100 + }, + "message": "Validierungsfehler" +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_1-8_search_with_personalId_only_resp.xml b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_1-8_search_with_personalId_only_resp.xml index 3fd477ee..f21c3698 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_1-8_search_with_personalId_only_resp.xml +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_1-8_search_with_personalId_only_resp.xml @@ -182,7 +182,76 @@ <zmr:EidasWert>7cEYWithDEElementsasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit</zmr:EidasWert> <base:AusstellDatum>9999-12-31</base:AusstellDatum> <base:AblaufDatum>9999-12-31</base:AblaufDatum> - </zmr:EidasIdentitaet> + </zmr:EidasIdentitaet> + <zmr:EidasIdentitaet> + <base:EntityErgebnisReferenz> + <base:Technisch> + <base:EntityID>1879000000000005</base:EntityID> + <base:LetzteAenderung>2021-11-12T08:24:39.695</base:LetzteAenderung> + </base:Technisch> + <base:Von>2021-11-12T08:24:39.695</base:Von> + <base:BeginnCode>EIDAS_ANLEGEN</base:BeginnCode> + <base:BeginnFreitext>KITT for eIDAS Matching</base:BeginnFreitext> + <base:DurchgefuehrtVon> + <base:Organisation> + <base:Behoerdenschluessel>101179</base:Behoerdenschluessel> + </base:Organisation> + <base:Benutzer>eidtapp@bmi.gv.at</base:Benutzer> + </base:DurchgefuehrtVon> + </base:EntityErgebnisReferenz> + <zmr:EidasArt>http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName</zmr:EidasArt> + <zmr:Staatscode2>DE</zmr:Staatscode2> + <base:AusstellBehoerde/> + <zmr:EidasWert>XXXvon Brandenburg</zmr:EidasWert> + <base:AusstellDatum>9999-12-31</base:AusstellDatum> + <base:AblaufDatum>9999-12-31</base:AblaufDatum> + </zmr:EidasIdentitaet> + <zmr:EidasIdentitaet> + <base:EntityErgebnisReferenz> + <base:Technisch> + <base:EntityID>1879000000000005</base:EntityID> + <base:LetzteAenderung>2021-11-12T08:24:39.695</base:LetzteAenderung> + </base:Technisch> + <base:Von>2021-11-12T08:24:39.695</base:Von> + <base:BeginnCode>EIDAS_ANLEGEN</base:BeginnCode> + <base:BeginnFreitext>KITT for eIDAS Matching</base:BeginnFreitext> + <base:DurchgefuehrtVon> + <base:Organisation> + <base:Behoerdenschluessel>101179</base:Behoerdenschluessel> + </base:Organisation> + <base:Benutzer>eidtapp@bmi.gv.at</base:Benutzer> + </base:DurchgefuehrtVon> + </base:EntityErgebnisReferenz> + <zmr:EidasArt>http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName</zmr:EidasArt> + <zmr:Staatscode2>DE</zmr:Staatscode2> + <base:AusstellBehoerde/> + <zmr:EidasWert>XXXClaus - Maria</zmr:EidasWert> + <base:AusstellDatum>9999-12-31</base:AusstellDatum> + <base:AblaufDatum>9999-12-31</base:AblaufDatum> + </zmr:EidasIdentitaet> + <zmr:EidasIdentitaet> + <base:EntityErgebnisReferenz> + <base:Technisch> + <base:EntityID>1879000000000005</base:EntityID> + <base:LetzteAenderung>2021-11-12T08:24:39.695</base:LetzteAenderung> + </base:Technisch> + <base:Von>2021-11-12T08:24:39.695</base:Von> + <base:BeginnCode>EIDAS_ANLEGEN</base:BeginnCode> + <base:BeginnFreitext>KITT for eIDAS Matching</base:BeginnFreitext> + <base:DurchgefuehrtVon> + <base:Organisation> + <base:Behoerdenschluessel>101179</base:Behoerdenschluessel> + </base:Organisation> + <base:Benutzer>eidtapp@bmi.gv.at</base:Benutzer> + </base:DurchgefuehrtVon> + </base:EntityErgebnisReferenz> + <zmr:EidasArt>http://eidas.europa.eu/attributes/naturalperson/DateOfBirth</zmr:EidasArt> + <zmr:Staatscode2>DE</zmr:Staatscode2> + <base:AusstellBehoerde/> + <zmr:EidasWert>1994-12-31</zmr:EidasWert> + <base:AusstellDatum>9999-12-31</base:AusstellDatum> + <base:AblaufDatum>9999-12-31</base:AblaufDatum> + </zmr:EidasIdentitaet> </zmr:PersonErgebnis> </zmr:Personendaten> <zmr:Meldedaten> diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_1-8_search_with_personalId_only_resp_no_additional_attributes.xml b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_1-8_search_with_personalId_only_resp_no_additional_attributes.xml new file mode 100644 index 00000000..6551cdd3 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_1-8_search_with_personalId_only_resp_no_additional_attributes.xml @@ -0,0 +1,221 @@ +<?xml version="1.0" encoding="UTF-8"?> + <base:Response xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://reference.e-government.gv.at/namespace/persondata/de/20040201#" xmlns:base="http://bmi.gv.at/namespace/zmr-su/base/20040201#" xmlns:smi="http://bmi.gv.at/namespace/zmr-su/smi/20060901#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:zmr="http://bmi.gv.at/namespace/zmr-su/zmr/20040201#" xmlns:ns10="http://bmi.gv.at/namespace/zmr-su/ernp/20050901#" xmlns:ns11="http://bmi.gv.at/namespace/zmr-su/gis/20070725#" xmlns:ns12="http://egov.gv.at/pvp1.xsd" xmlns:ns13="http://schemas.xmlsoap.org/ws/2002/04/secext" xmlns:ns8="http://bmi.gv.at/namespace/zmr-su/lmr/20050401#" xmlns:ns9="http://www.w3.org/2000/09/xmldsig#"> + <base:WorkflowInfoServer> + <base:ProzessName>GP_EIDAS</base:ProzessName> + <base:ProzessInstanzID>367100000000079</base:ProzessInstanzID> + <base:SequenzID>0</base:SequenzID> + </base:WorkflowInfoServer> + <base:ServerInfo> + <base:GeneriertVon>ZMR-Server Version: 5.9.0.0-SNAPSHOT</base:GeneriertVon> + <base:GeneriertAm>2021-11-12T08:24:40.985</base:GeneriertAm> + <base:ServerTransaktionNr>1877300000000139</base:ServerTransaktionNr> + </base:ServerInfo> + <zmr:PersonSuchenResponse> + <zmr:PersonensucheAnfrage> + <zmr:PersonensucheInfo> + <base:Bezugsfeld>Searching PersonIdentifier</base:Bezugsfeld> + <zmr:Suchkriterien> + <base:InclusivHistorie>true</base:InclusivHistorie> + <base:Formalisiert>false</base:Formalisiert> + </zmr:Suchkriterien> + <zmr:Ergebniskriterien> + <base:InclusivHistorie>false</base:InclusivHistorie> + </zmr:Ergebniskriterien> + <base:AnzahlSaetze>10</base:AnzahlSaetze> + </zmr:PersonensucheInfo> + <NatuerlichePerson/> + </zmr:PersonensucheAnfrage> + <base:Message> + <base:Number>5020</base:Number> + <base:Text>Person gefunden.</base:Text> + </base:Message> + <zmr:Personensuchergebnis> + <base:GefundeneSaetze>1</base:GefundeneSaetze> + <zmr:GefundeneSaetzeERnP>0</zmr:GefundeneSaetzeERnP> + <base:SaetzeVon>0</base:SaetzeVon> + <base:SaetzeBis>1</base:SaetzeBis> + <zmr:PersonErgebnisSatz> + <zmr:Personendaten> + <zmr:PersonErgebnis> + <base:ErgebnissatzInfo> + <base:LetzteAenderung>2021-11-12T08:24:39.695</base:LetzteAenderung> + </base:ErgebnissatzInfo> + <base:EntityErgebnisReferenz> + <base:Technisch> + <base:EntityID>44453600000000697</base:EntityID> + <base:LetzteAenderung>2020-02-05T13:07:06.311</base:LetzteAenderung> + </base:Technisch> + <base:Von>2020-02-05T13:07:06.311</base:Von> + <base:BeginnCode>SONSTIGES</base:BeginnCode> + <base:BeginnText>Sonstiges</base:BeginnText> + <base:BeginnFreitext>Testerperson</base:BeginnFreitext> + <base:DurchgefuehrtVon> + <base:Organisation> + <base:Behoerdenschluessel>109091</base:Behoerdenschluessel> + </base:Organisation> + </base:DurchgefuehrtVon> + </base:EntityErgebnisReferenz> + <base:ZMRZahl>000430320173</base:ZMRZahl> + <zmr:NatuerlichePerson> + <Identification> + <Value>UgeknNsc26lVuB7U/uYGVmWtnnA=</Value> + <Type>urn:publicid:gv.at:cdid+ZP</Type> + </Identification> + <zmr:PersonenName> + <Vorname>XXXClaus - Maria</Vorname> + <Familienname>XXXvon Brandenburg</Familienname> + </zmr:PersonenName> + <Familienstand>unbekannt</Familienstand> + <Geschlecht>männlich</Geschlecht> + <Geburtsdatum>1994-12-31</Geburtsdatum> + <Geburtsort>Wien</Geburtsort> + <Geburtsbundesland>Wien</Geburtsbundesland> + <Geburtsstaat>Österreich</Geburtsstaat> + <zmr:Staatsangehoerigkeit> + <ISOCode3>AUT</ISOCode3> + <StaatsnameDE>Österreich</StaatsnameDE> + <base:EntityErgebnisReferenz> + <base:Technisch> + <base:EntityID>44453600000000727</base:EntityID> + <base:LetzteAenderung>2020-02-05T13:07:06.311</base:LetzteAenderung> + </base:Technisch> + <base:Von>2020-02-05T13:07:06.311</base:Von> + <base:BeginnCode>STAATSANGEH_ANLEGEN</base:BeginnCode> + <base:BeginnText>Staatsangehörigkeit anlegen</base:BeginnText> + <base:BeginnFreitext>Testerperson</base:BeginnFreitext> + <base:DurchgefuehrtVon> + <base:Organisation> + <base:Behoerdenschluessel>109091</base:Behoerdenschluessel> + </base:Organisation> + </base:DurchgefuehrtVon> + </base:EntityErgebnisReferenz> + </zmr:Staatsangehoerigkeit> + </zmr:NatuerlichePerson> + <zmr:EidasIdentitaet> + <base:EntityErgebnisReferenz> + <base:Technisch> + <base:EntityID>1879000000000001</base:EntityID> + <base:LetzteAenderung>2021-11-12T08:24:39.695</base:LetzteAenderung> + </base:Technisch> + <base:Von>2021-11-12T08:24:39.695</base:Von> + <base:BeginnCode>EIDAS_ANLEGEN</base:BeginnCode> + <base:BeginnFreitext>KITT for eIDAS Matching</base:BeginnFreitext> + <base:DurchgefuehrtVon> + <base:Organisation> + <base:Behoerdenschluessel>101179</base:Behoerdenschluessel> + </base:Organisation> + <base:Benutzer>eidtapp@bmi.gv.at</base:Benutzer> + </base:DurchgefuehrtVon> + </base:EntityErgebnisReferenz> + <zmr:EidasArt>http://eidas.europa.eu/attributes/naturalperson/BirthName</zmr:EidasArt> + <zmr:Staatscode2>DE</zmr:Staatscode2> + <base:AusstellBehoerde/> + <zmr:EidasWert>XXXvon Heuburg</zmr:EidasWert> + <base:AusstellDatum>9999-12-31</base:AusstellDatum> + <base:AblaufDatum>9999-12-31</base:AblaufDatum> + </zmr:EidasIdentitaet> + <zmr:EidasIdentitaet> + <base:EntityErgebnisReferenz> + <base:Technisch> + <base:EntityID>1879000000000005</base:EntityID> + <base:LetzteAenderung>2021-11-12T08:24:39.695</base:LetzteAenderung> + </base:Technisch> + <base:Von>2021-11-12T08:24:39.695</base:Von> + <base:BeginnCode>EIDAS_ANLEGEN</base:BeginnCode> + <base:BeginnFreitext>KITT for eIDAS Matching</base:BeginnFreitext> + <base:DurchgefuehrtVon> + <base:Organisation> + <base:Behoerdenschluessel>101179</base:Behoerdenschluessel> + </base:Organisation> + <base:Benutzer>eidtapp@bmi.gv.at</base:Benutzer> + </base:DurchgefuehrtVon> + </base:EntityErgebnisReferenz> + <zmr:EidasArt>http://eidas.europa.eu/attributes/naturalperson/PersonIdentifier</zmr:EidasArt> + <zmr:Staatscode2>DE</zmr:Staatscode2> + <base:AusstellBehoerde/> + <zmr:EidasWert>7cEYWithDEElementsasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit</zmr:EidasWert> + <base:AusstellDatum>9999-12-31</base:AusstellDatum> + <base:AblaufDatum>9999-12-31</base:AblaufDatum> + </zmr:EidasIdentitaet> + </zmr:PersonErgebnis> + </zmr:Personendaten> + <zmr:Meldedaten> + <zmr:MeldungErgebnis> + <base:ErgebnissatzInfo> + <base:LetzteAenderung>2020-02-05T13:07:06.311</base:LetzteAenderung> + </base:ErgebnissatzInfo> + <base:EntityErgebnisReferenz> + <base:Technisch> + <base:EntityID>44453500000005242</base:EntityID> + <base:LetzteAenderung>2020-02-05T13:07:06.311</base:LetzteAenderung> + </base:Technisch> + <base:Von>2020-02-05T13:07:06.311</base:Von> + <base:BeginnCode>WSANM</base:BeginnCode> + <base:BeginnText>Wohnsitz anmelden</base:BeginnText> + <base:DurchgefuehrtVon> + <base:Organisation> + <base:Behoerdenschluessel>109091</base:Behoerdenschluessel> + </base:Organisation> + </base:DurchgefuehrtVon> + </base:EntityErgebnisReferenz> + <zmr:Wohnsitz> + <zmr:PostAdresse> + <Postleitzahl>0088</Postleitzahl> + <Gemeinde>Testgemeinde</Gemeinde> + <Gemeindekennziffer>09988</Gemeindekennziffer> + <Ortschaft>Testort A</Ortschaft> + <zmr:Zustelladresse> + <Strassenname>Testgasse</Strassenname> + <Orientierungsnummer>1a-2b</Orientierungsnummer> + <Gebaeude>Stg. 3c-4d</Gebaeude> + <Nutzungseinheit>5</Nutzungseinheit> + <Wohnsitzqualitaet>H</Wohnsitzqualitaet> + <Abgabestelle>false</Abgabestelle> + <Nutzungseinheitlaufnummer>0001</Nutzungseinheitlaufnummer> + <zmr:AdressRegisterEintrag> + <Adresscode>T800001</Adresscode> + <Subcode>001</Subcode> + <Objektnummer>T800001</Objektnummer> + </zmr:AdressRegisterEintrag> + </zmr:Zustelladresse> + </zmr:PostAdresse> + <base:Adressstatus>HST111WWW</base:Adressstatus> + <base:Adressschluessel> + <base:OKZ>T8001</base:OKZ> + <base:SKZ>T80001</base:SKZ> + <base:ADRRefkey>T80000000001</base:ADRRefkey> + <base:GBRRefkey>T80000000002</base:GBRRefkey> + </base:Adressschluessel> + <base:HauptIdent>H</base:HauptIdent> + <base:Postleitzahlgebiet>Testpostort</base:Postleitzahlgebiet> + </zmr:Wohnsitz> + <base:GemeldetVon>2020-02-05T13:07:06.311</base:GemeldetVon> + <base:PeriodeCode>WSANM</base:PeriodeCode> + <base:PeriodeText>Wohnsitz anmelden</base:PeriodeText> + <zmr:Auskunftssperre> + <base:EntityErgebnisReferenz> + <base:Technisch> + <base:EntityID>44453500000005262</base:EntityID> + <base:LetzteAenderung>2020-02-05T13:07:06.311</base:LetzteAenderung> + </base:Technisch> + <base:Von>2020-02-05T13:07:06.311</base:Von> + <base:BeginnCode>AUSK_SPERRE_SETZ</base:BeginnCode> + <base:BeginnText>Auskunftssperre setzen</base:BeginnText> + <base:DurchgefuehrtVon> + <base:Organisation> + <base:Behoerdenschluessel>109091</base:Behoerdenschluessel> + </base:Organisation> + </base:DurchgefuehrtVon> + </base:EntityErgebnisReferenz> + <zmr:SperreVon>2020-02-05T13:07:06.311</zmr:SperreVon> + <zmr:SperreBis>9999-12-31T23:59:59.000</zmr:SperreBis> + <zmr:SperrCode>ASMG</zmr:SperrCode> + <zmr:SperrText>Auskunftssperre nach § 18 / 2ff MeldeG</zmr:SperrText> + <zmr:SperrFreitext>automatische Auskunftssperre</zmr:SperrFreitext> + </zmr:Auskunftssperre> + </zmr:MeldungErgebnis> + </zmr:Meldedaten> + </zmr:PersonErgebnisSatz> + </zmr:Personensuchergebnis> + </zmr:PersonSuchenResponse> + </base:Response> diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_3-8_kitt_get_latest_version_resp.xml b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_3-8_kitt_get_latest_version_resp.xml index 447d2b55..656164f2 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_3-8_kitt_get_latest_version_resp.xml +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_3-8_kitt_get_latest_version_resp.xml @@ -146,7 +146,76 @@ <zmr:EidasWert>7cEYasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit</zmr:EidasWert> <base:AusstellDatum>9999-12-31</base:AusstellDatum> <base:AblaufDatum>9999-12-31</base:AblaufDatum> - </zmr:EidasIdentitaet> + </zmr:EidasIdentitaet> + <zmr:EidasIdentitaet> + <base:EntityErgebnisReferenz> + <base:Technisch> + <base:EntityID>1879000000000005</base:EntityID> + <base:LetzteAenderung>2021-11-12T08:24:39.695</base:LetzteAenderung> + </base:Technisch> + <base:Von>2021-11-12T08:24:39.695</base:Von> + <base:BeginnCode>EIDAS_ANLEGEN</base:BeginnCode> + <base:BeginnFreitext>KITT for eIDAS Matching</base:BeginnFreitext> + <base:DurchgefuehrtVon> + <base:Organisation> + <base:Behoerdenschluessel>101179</base:Behoerdenschluessel> + </base:Organisation> + <base:Benutzer>eidtapp@bmi.gv.at</base:Benutzer> + </base:DurchgefuehrtVon> + </base:EntityErgebnisReferenz> + <zmr:EidasArt>http://eidas.europa.eu/attributes/naturalperson/CurrentFamilyName</zmr:EidasArt> + <zmr:Staatscode2>DE</zmr:Staatscode2> + <base:AusstellBehoerde/> + <zmr:EidasWert>XXXvon Brandenburg</zmr:EidasWert> + <base:AusstellDatum>9999-12-31</base:AusstellDatum> + <base:AblaufDatum>9999-12-31</base:AblaufDatum> + </zmr:EidasIdentitaet> + <zmr:EidasIdentitaet> + <base:EntityErgebnisReferenz> + <base:Technisch> + <base:EntityID>1879000000000005</base:EntityID> + <base:LetzteAenderung>2021-11-12T08:24:39.695</base:LetzteAenderung> + </base:Technisch> + <base:Von>2021-11-12T08:24:39.695</base:Von> + <base:BeginnCode>EIDAS_ANLEGEN</base:BeginnCode> + <base:BeginnFreitext>KITT for eIDAS Matching</base:BeginnFreitext> + <base:DurchgefuehrtVon> + <base:Organisation> + <base:Behoerdenschluessel>101179</base:Behoerdenschluessel> + </base:Organisation> + <base:Benutzer>eidtapp@bmi.gv.at</base:Benutzer> + </base:DurchgefuehrtVon> + </base:EntityErgebnisReferenz> + <zmr:EidasArt>http://eidas.europa.eu/attributes/naturalperson/CurrentGivenName</zmr:EidasArt> + <zmr:Staatscode2>DE</zmr:Staatscode2> + <base:AusstellBehoerde/> + <zmr:EidasWert>XXXClaus - Maria</zmr:EidasWert> + <base:AusstellDatum>9999-12-31</base:AusstellDatum> + <base:AblaufDatum>9999-12-31</base:AblaufDatum> + </zmr:EidasIdentitaet> + <zmr:EidasIdentitaet> + <base:EntityErgebnisReferenz> + <base:Technisch> + <base:EntityID>1879000000000005</base:EntityID> + <base:LetzteAenderung>2021-11-12T08:24:39.695</base:LetzteAenderung> + </base:Technisch> + <base:Von>2021-11-12T08:24:39.695</base:Von> + <base:BeginnCode>EIDAS_ANLEGEN</base:BeginnCode> + <base:BeginnFreitext>KITT for eIDAS Matching</base:BeginnFreitext> + <base:DurchgefuehrtVon> + <base:Organisation> + <base:Behoerdenschluessel>101179</base:Behoerdenschluessel> + </base:Organisation> + <base:Benutzer>eidtapp@bmi.gv.at</base:Benutzer> + </base:DurchgefuehrtVon> + </base:EntityErgebnisReferenz> + <zmr:EidasArt>http://eidas.europa.eu/attributes/naturalperson/DateOfBirth</zmr:EidasArt> + <zmr:Staatscode2>DE</zmr:Staatscode2> + <base:AusstellBehoerde/> + <zmr:EidasWert>1994-12-31</zmr:EidasWert> + <base:AusstellDatum>9999-12-31</base:AusstellDatum> + <base:AblaufDatum>9999-12-31</base:AblaufDatum> + </zmr:EidasIdentitaet> </zmr:PersonErgebnis> </zmr:Personendaten> <zmr:Meldedaten> |