aboutsummaryrefslogtreecommitdiff
path: root/eidas_modules
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2022-03-03 15:27:30 +0000
committerThomas Lenz <thomas.lenz@egiz.gv.at>2022-03-03 15:27:30 +0000
commitd8247d4de494c176f78658fa2c0a38ac9ceab0aa (patch)
treed0b6bf2293b6e82282bfbab595e0b4d39fdb0428 /eidas_modules
parentb81ef7a782278cb941d3b424ccbe1ccc976c54f3 (diff)
parentc3bba97c9093eca911f6edd9cbb9742d5f32583c (diff)
downloadNational_eIDAS_Gateway-d8247d4de494c176f78658fa2c0a38ac9ceab0aa.tar.gz
National_eIDAS_Gateway-d8247d4de494c176f78658fa2c0a38ac9ceab0aa.tar.bz2
National_eIDAS_Gateway-d8247d4de494c176f78658fa2c0a38ac9ceab0aa.zip
Merge branch 'feature/matching_ernp_client' into 'feature/matching_base'
refactor(ernp): update openAPI specification from BM.I to use... See merge request egiz/eidas_at_proxy!16
Diffstat (limited to 'eidas_modules')
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/pom.xml52
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java69
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java857
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java114
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/szr/SzrClient.java49
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/IZmrClient.java21
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java114
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/controller/AdresssucheController.java269
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/MatchedPersonResult.java6
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/RegisterResult.java5
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleEidasData.java30
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleMobileSignatureData.java6
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/DummyErnpClient.java47
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/IErnpClient.java46
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ErnpRestCommunicationException.java29
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/RegisterSearchService.java102
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java6
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateIdentityLinkTask.java126
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateNewErnpEntryTask.java58
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateOtherLoginMethodGuiTask.java7
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java43
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java179
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseTask.java11
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveOtherLoginMethodGuiResponseTask.java17
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml12
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml9
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties11
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json1940
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ErnpRestClientProductionTest.java460
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ErnpRestClientTest.java1085
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/SzrClientProductionTest.java75
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/SzrClientTest.java91
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientTest.java178
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java75
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskEidNewTest.java75
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateIdentityLinkTaskTest.java45
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/CreateNewErnpEntryTaskTest.java198
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateOtherLoginMethodGuiTaskTest.java76
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskTest.java360
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java193
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskRegisterTest.java337
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskTest.java141
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseTaskTest.java10
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties19
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1_springboot.properties11
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_add_req.json30
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_add_resp.json60
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_search_latest_req.json19
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_search_latest_resp.json62
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_update_req.json17
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_kitt_update_resp.json60
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_search_with_personalId_req.json20
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/1_search_with_personalId_resp.json62
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_add_req.json30
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_add_resp.json60
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_search_latest_req.json19
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_search_latest_resp.json62
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_update_req.json14
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_kitt_update_resp.json69
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_search_with_cc_specific_req.json30
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/2_search_with_cc_specific_resp.json62
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/3_search_with_mds_req.json18
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/3_search_with_mds_resp.json44
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/4_search_with_mds_multi_resp.json84
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/4_search_with_mds_req.json18
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/ernp_empty_resp.json1
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/ernp_handbook_example.json85
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/ernp/error_resp.json12
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_1-8_search_with_personalId_only_resp.xml71
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_1-8_search_with_personalId_only_resp_no_additional_attributes.xml221
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/resources/data/zmr/seq_3-8_kitt_get_latest_version_resp.xml71
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>