From a3d1b2e9aaad4b00031cfcd76e26940697c876c2 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Wed, 2 Feb 2022 18:02:11 +0100
Subject: refactor(ernp): move IErnpClient interface into another package
---
.../auth/eidas/v2/clients/ernp/IErnpClient.java | 46 ++++++++++++++++++++++
.../auth/eidas/v2/ernp/DummyErnpClient.java | 1 +
.../modules/auth/eidas/v2/ernp/IErnpClient.java | 46 ----------------------
.../eidas/v2/service/RegisterSearchService.java | 2 +-
4 files changed, 48 insertions(+), 47 deletions(-)
create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java
delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/IErnpClient.java
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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..377048d9
--- /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,46 @@
+/*
+ * 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 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 searchWithPersonIdentifier(String personIdentifier);
+
+ List searchWithMds(String givenName, String familyName, String dateOfBirth);
+
+ List searchDeSpecific(String givenName, String familyName, String dateOfBirth,
+ String birthPlace, String birthName);
+
+ List searchItSpecific(String taxNumber);
+
+ RegisterResult update(RegisterResult registerResult, SimpleEidasData eidData);
+
+ List searchWithBpkZp(String bpkzp);
+
+}
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..db10752b 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
@@ -28,6 +28,7 @@ import java.util.List;
import org.springframework.stereotype.Service;
+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;
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 searchWithPersonIdentifier(String personIdentifier);
-
- List searchWithMds(String givenName, String familyName, String dateOfBirth);
-
- List searchDeSpecific(String givenName, String familyName, String dateOfBirth,
- String birthPlace, String birthName);
-
- List searchItSpecific(String taxNumber);
-
- RegisterResult update(RegisterResult registerResult, SimpleEidasData eidData);
-
- List searchWithBpkZp(String bpkzp);
-
-}
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..5f1e96a4 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
@@ -11,11 +11,11 @@ import org.springframework.stereotype.Service;
import com.google.common.collect.Streams;
+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.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;
--
cgit v1.2.3
From b70915cf52ecb08c881d33e8c65b6256922fc0f4 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Thu, 3 Feb 2022 15:50:33 +0100
Subject: refactor(ernp): change API of ERnP client to same model as ZMR client
---
.../auth/eidas/v2/clients/ernp/ErnpRestClient.java | 65 +++++++++++++++++++
.../auth/eidas/v2/clients/ernp/IErnpClient.java | 74 +++++++++++++++++++---
.../auth/eidas/v2/ernp/DummyErnpClient.java | 43 +++++++------
.../eidas/v2/service/RegisterSearchService.java | 30 +++++----
4 files changed, 168 insertions(+), 44 deletions(-)
create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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..7763fc9d
--- /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,65 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.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;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
+import at.gv.bmi.namespace.zmr_su.zmr._20040201.PersonSuchenRequest;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * Implements an ERnP client that uses REST API for communication.
+ *
+ * @author tlenz
+ *
+ */
+public class ErnpRestClient implements IErnpClient {
+
+ @AllArgsConstructor
+ @Getter
+ public static class ErnpRegisterResult {
+ private final List personResult;
+
+ }
+
+ @Override
+ public ErnpRegisterResult searchWithPersonIdentifier(String personIdentifier, String citizenCountryCode)
+ throws EidasSAuthenticationException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ErnpRegisterResult searchWithMds(String givenName, String familyName, String dateOfBirth,
+ String citizenCountryCode) throws EidasSAuthenticationException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ErnpRegisterResult searchCountrySpecific(PersonSuchenRequest personSearchDao,
+ String citizenCountryCode) throws EidasSAuthenticationException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ErnpRegisterResult update(RegisterResult registerResult, SimpleEidasData eidData)
+ throws EidasSAuthenticationException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ErnpRegisterResult searchWithResidenceData(String givenName, String familyName, String dateOfBirth,
+ String zipcode, String city, String street) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+
+
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java
index 377048d9..4c8bcd3e 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java
@@ -23,24 +23,80 @@
package at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp;
-import java.util.List;
+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 {
- List searchWithPersonIdentifier(String personIdentifier);
+ /**
+ * 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 null
+ * @throws EidasSAuthenticationException In case of a communication error
+ */
+ @Nonnull
+ ErnpRegisterResult searchWithPersonIdentifier(@Nonnull String personIdentifier,
+ @Nonnull String citizenCountryCode) throws EidasSAuthenticationException;
- List searchWithMds(String givenName, String familyName, String dateOfBirth);
+ /**
+ * 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 null
+ * @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;
- List searchDeSpecific(String givenName, String familyName, String dateOfBirth,
- String birthPlace, String birthName);
+ /**
+ * 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 null
+ * @throws EidasSAuthenticationException In case of a communication error
+ */
+ @Nonnull
+ ErnpRegisterResult searchCountrySpecific(@Nonnull PersonSuchenRequest personSearchDao,
+ @Nonnull String citizenCountryCode) throws EidasSAuthenticationException;
- List searchItSpecific(String taxNumber);
+ /**
+ * 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 null
+ * @throws EidasSAuthenticationException In case of a communication error
+ */
+ @Nonnull
+ ErnpRegisterResult update(RegisterResult registerResult, SimpleEidasData eidData)
+ throws EidasSAuthenticationException;
- RegisterResult update(RegisterResult registerResult, SimpleEidasData eidData);
-
- List searchWithBpkZp(String bpkzp);
+ /**
+ * 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 null
+ */
+ @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/ernp/DummyErnpClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/DummyErnpClient.java
index db10752b..52703232 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,52 +24,53 @@
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 searchWithPersonIdentifier(String personIdentifier) {
- return Collections.emptyList();
+ public ErnpRegisterResult searchWithPersonIdentifier(String personIdentifier, String citizenCountryCode)
+ throws EidasSAuthenticationException {
+ return buildEmptyResult();
}
@Override
- public List 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 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 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 searchWithBpkZp(String bpkzp) {
- //TODO
- return Collections.emptyList();
+ private static ErnpRegisterResult buildEmptyResult() {
+ return new ErnpRegisterResult(Collections.emptyList());
+
}
-
}
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 5f1e96a4..fd9a67a9 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
@@ -11,6 +11,7 @@ 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;
@@ -77,8 +78,8 @@ public class RegisterSearchService {
final ZmrRegisterResult resultsZmr = zmrClient.searchWithPersonIdentifier(
operationStatus != null ? operationStatus.getZmrProcessId() : null,
eidasData.getPseudonym(), eidasData.getCitizenCountryCode());
- final List resultsErnp = ernpClient.searchWithPersonIdentifier(
- eidasData.getPersonalIdentifier());
+ final ErnpRegisterResult resultsErnp = ernpClient.searchWithPersonIdentifier(
+ eidasData.getPseudonym(), eidasData.getCitizenCountryCode());
return RegisterStatusResults.fromZmrAndErnp(resultsZmr, resultsErnp);
@@ -104,9 +105,9 @@ public class RegisterSearchService {
zmrClient.searchWithMds(operationStatus.getZmrProcessId(), eidasData.getGivenName(),
eidasData.getFamilyName(), eidasData.getDateOfBirth(), eidasData.getCitizenCountryCode());
- final List 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);
@@ -141,7 +142,8 @@ public class RegisterSearchService {
} else {
// TODO: add search procesfor for ERnP searching
- return RegisterStatusResults.fromErnp(operationStatus, Collections.emptyList());
+ return RegisterStatusResults.fromErnp(operationStatus,
+ new ErnpRegisterResult(Collections.emptyList()));
}
@@ -193,8 +195,8 @@ public class RegisterSearchService {
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(),
@@ -263,9 +265,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.operationStatus, updateAlt);
}
} catch (final EidasSAuthenticationException e) {
throw new WorkflowException("kittMatchedIdentitiess", e.getMessage(),
@@ -373,13 +375,13 @@ public class RegisterSearchService {
result.getPersonResult(), Collections.emptyList());
}
- static RegisterStatusResults fromZmrAndErnp(ZmrRegisterResult result, List 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 resultsErnp) {
- return new RegisterStatusResults(status, Collections.emptyList(), resultsErnp);
+ static RegisterStatusResults fromErnp(RegisterOperationStatus status, ErnpRegisterResult updateErnp) {
+ return new RegisterStatusResults(status, Collections.emptyList(), updateErnp.getPersonResult());
}
}
--
cgit v1.2.3
From 8d19a4097a61723950830c79aaee3168785b683b Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Thu, 3 Feb 2022 15:51:38 +0100
Subject: feature(ernp): implement 'searchByPersonalIdentifier' as a first test
version
---
.../specific/modules/auth/eidas/v2/Constants.java | 57 +++-
.../auth/eidas/v2/clients/ernp/ErnpRestClient.java | 374 ++++++++++++++++++++-
.../auth/eidas/v2/clients/zmr/ZmrSoapClient.java | 4 +-
3 files changed, 407 insertions(+), 28 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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..d48d69bf 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,21 @@ 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_DEBUG_TRACEMESSAGES = CONIG_PROPS_EIDAS_ERNPCLIENT
+ + ".debug.logfullmessages";
+ 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
@@ -255,8 +292,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";
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
index 7763fc9d..a651385f 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
@@ -1,13 +1,62 @@
package at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.time.OffsetDateTime;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import javax.annotation.PostConstruct;
+
+import org.apache.http.client.HttpClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+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.web.client.ResponseErrorHandler;
+import org.springframework.web.client.RestTemplate;
+
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+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.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.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.PersonSuchen;
+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.WorkflowException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.VersionHolder;
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.
@@ -15,51 +64,344 @@ import lombok.Getter;
* @author tlenz
*
*/
+@Slf4j
public class ErnpRestClient implements IErnpClient {
- @AllArgsConstructor
- @Getter
- public static class ErnpRegisterResult {
- private final List personResult;
-
- }
+ private static final String ERROR_MATCHING_01 = "module.eidasauth.matching.01";
+ private static final String ERROR_MATCHING_02 = "module.eidasauth.matching.02";
+ private static final String ERROR_MATCHING_99 = "module.eidasauth.matching.99";
+
+ 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_SOAP_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 FRIENDLYNAME_HTTP_CLIENT = "ERnP Client";
+
+ private static final String PATTERN_BIRTHDAY_STRING = "{0}-{1}-{2}";
+
+
+ @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 {
- // TODO Auto-generated method stub
- return null;
- }
+
+ try {
+
+ // build generic request metadata
+ GenericRequestParams generic = buildGenericRequestParameters("step1");
+ // build search request
+ SuchEidas eidasInfos = new SuchEidas();
+ eidasInfos.setArt(Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER);
+ eidasInfos.setWert(personIdentifier);
+ eidasInfos.setStaatscode2(citizenCountryCode);
+
+ PersonSuchen personSuchen = new PersonSuchen();
+ personSuchen.setSuchoptionen(generateSearchParameters());
+ personSuchen.setBegruendung(PROCESS_SEARCH_PERSONAL_IDENTIFIER);
+ Suchdaten searchInfos = new Suchdaten();
+ searchInfos.setEidas(eidasInfos);
+ personSuchen.setSuchdaten(searchInfos);
+
+ // request ERnP
+ log.trace("Requesting ERnP for '{}' operation", PROCESS_SEARCH_PERSONAL_IDENTIFIER);
+ 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 (EidasSAuthenticationException e) {
+ throw e;
+
+ } catch (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 {
- // TODO Auto-generated method stub
- return null;
+ return new ErnpRegisterResult(Collections.emptyList());
}
@Override
public ErnpRegisterResult searchCountrySpecific(PersonSuchenRequest personSearchDao,
String citizenCountryCode) throws EidasSAuthenticationException {
- // TODO Auto-generated method stub
- return null;
+ return new ErnpRegisterResult(Collections.emptyList());
}
@Override
public ErnpRegisterResult update(RegisterResult registerResult, SimpleEidasData eidData)
throws EidasSAuthenticationException {
- // TODO Auto-generated method stub
- return null;
+ return new ErnpRegisterResult(Collections.emptyList());
}
@Override
public ErnpRegisterResult searchWithResidenceData(String givenName, String familyName, String dateOfBirth,
String zipcode, String city, String street) {
+ return new ErnpRegisterResult(Collections.emptyList());
+ }
+
+ @PostConstruct
+ private void initialize() throws EaafException {
+ // set-up the Ernp client
+ ernpClient = new DefaultApi(new ApiClient(buildRestClient()));
+
+ // validate additional Ernp communication parameters
+ valdiateAdditionalConfigParameters();
+
+ }
+
+ private void valdiateAdditionalConfigParameters() {
// TODO Auto-generated method stub
- return null;
+
+ }
+
+ private Suchoptionen generateSearchParameters() {
+ 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 processSearchPersonResponse(
+ @Nonnull List list,
+ @Nonnull String citizenCountryCode) throws EaafAuthenticationException {
+ return list.stream()
+ .map(el -> mapErnpResponseToRegisterResult(el, citizenCountryCode))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+
}
+ @NonNull
+ private List processSearchPersonResponseSingleResult(
+ @Nonnull List 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(buildTextualBirthday(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 String buildTextualBirthday(PartialDate geburtsdatum) {
+ return MessageFormat.format(PATTERN_BIRTHDAY_STRING,
+ geburtsdatum.getJahr(), geburtsdatum.getMonat(), 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 selectAllEidasDocument(Person person, String citizenCountryCode,
+ String eidasAttrurnPersonalidentifier) {
+ return person.getEidas().stream()
+ .filter(el -> eidasAttrurnPersonalidentifier.equals(el.getArt())
+ && el.getStaatscode2().equals(citizenCountryCode))
+ .map(el -> el.getWert())
+ .collect(Collectors.toList());
+
+ }
+
+ /**
+ * 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 null
if's not found
+ */
+ @Nullable
+ private String selectSingleEidasDocument(Person person, String citizenCountryCode,
+ String eidasAttrurnPersonalidentifier) {
+ return person.getEidas().stream()
+ .filter(el -> eidasAttrurnPersonalidentifier.equals(el.getArt())
+ && el.getStaatscode2().equals(citizenCountryCode))
+ .findFirst()
+ .map(el -> el.getWert())
+ .orElse(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() {
+ MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.setSerializationInclusion(Include.NON_NULL);
+ converter.setObjectMapper(objectMapper);
+ 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: implement errorHandling based on response infos
+
+ if (response.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR) {
+ log.warn("Receive http-server-error: {} from ERnP", response.getRawStatusCode());
+
+ } else if (response.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR) {
+ log.warn("Receive http-client-error: {} from ERnP", 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 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/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..432df9ef 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
@@ -100,7 +100,6 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient {
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";
@@ -429,7 +428,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 +464,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);
--
cgit v1.2.3
From 84bb45ecb417f6a92b7d8884048bd7901c6b1b42 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Thu, 3 Feb 2022 20:28:50 +0100
Subject: fix(ernp): fix some bugs in ERnP client implementation
---
.../specific/modules/auth/eidas/v2/Constants.java | 2 -
.../auth/eidas/v2/clients/ernp/ErnpRestClient.java | 265 ++++++++++++---------
.../exception/ErnpRestCommunicationException.java | 24 ++
3 files changed, 180 insertions(+), 111 deletions(-)
create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ErnpRestCommunicationException.java
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 d48d69bf..6da30299 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
@@ -166,8 +166,6 @@ public class Constants {
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_DEBUG_TRACEMESSAGES = CONIG_PROPS_EIDAS_ERNPCLIENT
- + ".debug.logfullmessages";
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
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
index a651385f..605f1d0f 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
@@ -2,6 +2,7 @@ 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.Collections;
@@ -12,9 +13,11 @@ import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
+import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
@@ -23,10 +26,10 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
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.ObjectMapper;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult;
@@ -42,6 +45,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.SuchenRes
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.zmr._20040201.PersonSuchenRequest;
@@ -60,17 +64,18 @@ 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_01 = "module.eidasauth.matching.01";
- private static final String ERROR_MATCHING_02 = "module.eidasauth.matching.02";
+ 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 =
@@ -78,69 +83,73 @@ public class ErnpRestClient implements IErnpClient {
private static final String LOGMSG_ERNP_SOAP_ERROR =
"ERnP anwser for transaction: {0} with code: {1} and message: {2}";
-
- private static final String PROCESS_SEARCH_PERSONAL_IDENTIFIER =
+
+ 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 FRIENDLYNAME_HTTP_CLIENT = "ERnP Client";
-
- private static final String PATTERN_BIRTHDAY_STRING = "{0}-{1}-{2}";
-
-
- @Autowired IConfiguration basicConfig;
- @Autowired EaafKeyStoreFactory keyStoreFactory;
- @Autowired IHttpClientFactory httpClientFactory;
- @Autowired VersionHolder versionHolder;
-
+
+ @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
- GenericRequestParams generic = buildGenericRequestParameters("step1");
+ final GenericRequestParams generic = buildGenericRequestParameters("step1");
- // build search request
- SuchEidas eidasInfos = new SuchEidas();
+ // build search request
+ final SuchEidas eidasInfos = new SuchEidas();
eidasInfos.setArt(Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER);
eidasInfos.setWert(personIdentifier);
eidasInfos.setStaatscode2(citizenCountryCode);
-
- PersonSuchen personSuchen = new PersonSuchen();
+
+ final PersonSuchen personSuchen = new PersonSuchen();
personSuchen.setSuchoptionen(generateSearchParameters());
- personSuchen.setBegruendung(PROCESS_SEARCH_PERSONAL_IDENTIFIER);
- Suchdaten searchInfos = new Suchdaten();
- searchInfos.setEidas(eidasInfos);
+ personSuchen.setBegruendung(PROCESS_SEARCH_PERSONAL_IDENTIFIER);
+ final Suchdaten searchInfos = new Suchdaten();
+ searchInfos.setEidas(eidasInfos);
personSuchen.setSuchdaten(searchInfos);
-
+
// request ERnP
log.trace("Requesting ERnP for '{}' operation", PROCESS_SEARCH_PERSONAL_IDENTIFIER);
- SuchenResponse resp = ernpClient.suchen(generic.getClientBehkz(), generic.clientName,
+ 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 (EidasSAuthenticationException e) {
+ } catch (final EidasSAuthenticationException e) {
throw e;
-
- } catch (Exception 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 {
@@ -164,54 +173,66 @@ public class ErnpRestClient implements IErnpClient {
String zipcode, String city, String street) {
return new ErnpRegisterResult(Collections.emptyList());
}
-
+
@PostConstruct
private void initialize() throws EaafException {
- // set-up the Ernp client
- ernpClient = new DefaultApi(new ApiClient(buildRestClient()));
-
// 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() {
- // TODO Auto-generated method stub
-
+ 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() {
- Suchoptionen options = new Suchoptionen();
+ final Suchoptionen options = new Suchoptionen();
options.setZmr(false);
options.setHistorisch(HistorischEnum.AKTUELLUNDHISTORISCH);
options.setSucheMitNamensteilen(false);
- options.setSuchwizard(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
+ 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",
+
+ } 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
@@ -224,22 +245,22 @@ public class ErnpRestClient implements IErnpClient {
.collect(Collectors.toList());
}
-
+
@NonNull
private List processSearchPersonResponseSingleResult(
@Nonnull List 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,
+ 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) {
@@ -254,15 +275,28 @@ public class ErnpRestClient implements IErnpClient {
.placeOfBirth(selectSingleEidasDocument(person, citizenCountryCode,
Constants.eIDAS_ATTRURN_PLACEOFBIRTH))
.birthName(selectSingleEidasDocument(person, citizenCountryCode,
- Constants.eIDAS_ATTRURN_BIRTHNAME))
+ Constants.eIDAS_ATTRURN_BIRTHNAME))
.build();
}
-
+
+ /**
+ * Build AT specific Date String 'yyyy-MM-dd' from ERnP birthday representation.
+ *
+ *
+ * Info: {@link LocalDate} can not be used, because '1940-00-00' is also
+ * a valid birthday on ERnP site.
+ *
+ *
+ * @param geburtsdatum ERnP birthday representation
+ * @return birthday in 'yyyy-MM-dd' format
+ */
private String buildTextualBirthday(PartialDate geburtsdatum) {
- return MessageFormat.format(PATTERN_BIRTHDAY_STRING,
- geburtsdatum.getJahr(), geburtsdatum.getMonat(), geburtsdatum.getTag());
-
+ return MessageFormat.format("{0}-{1}-{2}",
+ String.valueOf(geburtsdatum.getJahr()),
+ String.format("%02d", geburtsdatum.getMonat()),
+ String.format("%02d", geburtsdatum.getTag()));
+
}
/**
@@ -276,12 +310,18 @@ public class ErnpRestClient implements IErnpClient {
*/
@NonNull
private List selectAllEidasDocument(Person person, String citizenCountryCode,
- String eidasAttrurnPersonalidentifier) {
- return person.getEidas().stream()
- .filter(el -> eidasAttrurnPersonalidentifier.equals(el.getArt())
- && el.getStaatscode2().equals(citizenCountryCode))
- .map(el -> el.getWert())
- .collect(Collectors.toList());
+ 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();
+
+ }
}
@@ -297,15 +337,20 @@ public class ErnpRestClient implements IErnpClient {
@Nullable
private String selectSingleEidasDocument(Person person, String citizenCountryCode,
String eidasAttrurnPersonalidentifier) {
- return person.getEidas().stream()
- .filter(el -> eidasAttrurnPersonalidentifier.equals(el.getArt())
- && el.getStaatscode2().equals(citizenCountryCode))
- .findFirst()
- .map(el -> el.getWert())
- .orElse(null);
+ 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());
@@ -316,42 +361,44 @@ public class ErnpRestClient implements IErnpClient {
return springClient;
}
-
+
private HttpMessageConverter> buildCustomJacksonObjectMapper() {
- MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
- ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.setSerializationInclusion(Include.NON_NULL);
- converter.setObjectMapper(objectMapper);
+ final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
+ converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
+ converter.getObjectMapper()
+ .setSerializationInclusion(Include.NON_NULL);
return converter;
-
+
}
-
+
@Nonnull
private ResponseErrorHandler buildErrorHandler() {
return new ResponseErrorHandler() {
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
- return response.getStatusCode().is4xxClientError()
- || response.getStatusCode().is5xxServerError();
-
+ return response.getStatusCode().is4xxClientError()
+ || response.getStatusCode().is5xxServerError();
+
}
@Override
- public void handleError(ClientHttpResponse response) throws IOException {
- //TODO: implement errorHandling based on response infos
-
+ public void handleError(ClientHttpResponse response) throws IOException {
+ // TODO: implement errorHandling based on response infos
+
if (response.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR) {
log.warn("Receive http-server-error: {} from ERnP", response.getRawStatusCode());
-
+
} else if (response.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR) {
log.warn("Receive http-client-error: {} from ERnP", response.getRawStatusCode());
-
+
}
+
+ throw new ErnpRestCommunicationException(response.getRawStatusCode());
}
};
}
-
+
@Nonnull
private HttpClientConfiguration buildHttpClientConfiguration() throws EaafException {
final HttpClientConfiguration config = new HttpClientConfiguration(FRIENDLYNAME_HTTP_CLIENT);
@@ -369,39 +416,39 @@ public class ErnpRestClient implements IErnpClient {
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
-
+ // TODO: update EAAF-components to allow custom HTTP Connection-Timeouts
+
return config;
}
-
@AllArgsConstructor
@Getter
public static class ErnpRegisterResult {
private final List personResult;
-
+
}
private GenericRequestParams buildGenericRequestParameters(String operationIdentifier) {
return GenericRequestParams.builder()
- .clientBehkz(basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_REQ_ORGANIZATION_NR))
+ .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();
-
+ .build();
+
}
-
+
@Builder
@Getter
- private static class GenericRequestParams {
+ private static class GenericRequestParams {
String clientBehkz;
- String clientName;
- OffsetDateTime clientRequestTime;
+ 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/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..72a5ece6
--- /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,24 @@
+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;
+
+ public ErnpRestCommunicationException(int rawStatusCode) {
+ super("ERnP service answers with an error and HTTP status-code: " + rawStatusCode);
+ this.httpStatusCode = rawStatusCode;
+ }
+
+}
--
cgit v1.2.3
From 87a347c359ec7ee2a39bfcace1975f60c4eb9375 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Mon, 7 Feb 2022 07:55:13 +0100
Subject: feature(ernp): port search and update steps from ZMR client to ERnP
client because we need the same functionality on different API
---
.../auth/eidas/v2/clients/ernp/ErnpRestClient.java | 308 +++++++++++++++++++--
.../exception/ErnpRestCommunicationException.java | 4 +-
.../eidas/v2/service/RegisterSearchService.java | 24 +-
.../auth/eidas/v2/tasks/InitialSearchTask.java | 5 +-
4 files changed, 310 insertions(+), 31 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
index 605f1d0f..2eaece1d 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
@@ -5,9 +5,13 @@ 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;
@@ -16,7 +20,6 @@ import javax.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpClient;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
@@ -25,6 +28,7 @@ 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;
@@ -36,8 +40,11 @@ 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.ernp.api.DefaultApi;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.invoker.ApiClient;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.AendernResponse;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.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.PersonSuchen;
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;
@@ -48,6 +55,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenti
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.PersonSuchenRequest;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException;
@@ -81,7 +89,7 @@ public class ErnpRestClient implements IErnpClient {
private static final String LOGMSG_ERNP_RESP_PROCESS =
"Proces ERnP response during '{}' operation failes with msg: {}";
- private static final String LOGMSG_ERNP_SOAP_ERROR =
+ 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 =
@@ -95,6 +103,10 @@ public class ErnpRestClient implements IErnpClient {
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
@@ -109,11 +121,9 @@ public class ErnpRestClient implements IErnpClient {
@Override
public ErnpRegisterResult searchWithPersonIdentifier(String personIdentifier, String citizenCountryCode)
throws EidasSAuthenticationException {
-
try {
-
// build generic request metadata
- final GenericRequestParams generic = buildGenericRequestParameters("step1");
+ final GenericRequestParams generic = buildGenericRequestParameters("stepId");
// build search request
final SuchEidas eidasInfos = new SuchEidas();
@@ -153,19 +163,242 @@ public class ErnpRestClient implements IErnpClient {
@Override
public ErnpRegisterResult searchWithMds(String givenName, String familyName, String dateOfBirth,
String citizenCountryCode) throws EidasSAuthenticationException {
- return new ErnpRegisterResult(Collections.emptyList());
+ 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 {
- return new ErnpRegisterResult(Collections.emptyList());
+ try {
+ // build generic request metadata
+ final GenericRequestParams generic = buildGenericRequestParameters("stepCC");
+
+ // build search request
+ final PersonSuchen personSuchen = new PersonSuchen();
+ personSuchen.setSuchoptionen(generateSearchParameters());
+ personSuchen.setBegruendung(PROCESS_SEARCH_COUNTRY_SPECIFIC);
+ personSuchen.setSuchdaten(mapCountrySpecificSearchData(personSearchDao));
+
+ // request ERnP
+ log.trace("Requesting ERnP for '{}' operation", PROCESS_SEARCH_COUNTRY_SPECIFIC);
+ final SuchenResponse resp = ernpClient.suchen(generic.getClientBehkz(), generic.clientName,
+ generic.getClientRequestTime(), generic.getClientRequestId(), personSuchen);
+
+ // parse ZMR response
+ return processErnpResponse(resp, citizenCountryCode, false, PROCESS_SEARCH_COUNTRY_SPECIFIC);
+
+ } catch (RestClientException e) {
+ log.warn(LOGMSG_ERNP_ERROR, PROCESS_SEARCH_COUNTRY_SPECIFIC, 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_COUNTRY_SPECIFIC, e.getMessage());
+ throw new EidasSAuthenticationException(ERROR_MATCHING_99, new Object[] { e.getMessage() }, e);
+
+ }
}
@Override
public ErnpRegisterResult update(RegisterResult registerResult, SimpleEidasData eidData)
throws EidasSAuthenticationException {
- return new ErnpRegisterResult(Collections.emptyList());
+ 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);
+
+ if (eidasDocumentToAdd.isEmpty()) {
+ log.info("Find no eIDAS document for update during: {}. Looks strange but nothing todo",
+ 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, eidData.getCitizenCountryCode());
+
+ }
+
+ } catch (RestClientException e) {
+ log.warn(LOGMSG_ERNP_ERROR, PROCESS_SEARCH_COUNTRY_SPECIFIC, 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_COUNTRY_SPECIFIC, e.getMessage());
+ throw new EidasSAuthenticationException(ERROR_MATCHING_99, new Object[] { e.getMessage() }, e);
+
+ }
+ }
+
+ private ErnpRegisterResult updatePersonInErnp(Person ernpPersonToKitt,
+ Collection extends Eidas> eidasDocumentToAdd, String citizenCountryCode)
+ throws ServiceFault {
+ // build generic request metadata
+ final GenericRequestParams generic = buildGenericRequestParameters("stepKittUpdate");
+
+ // build update request
+ PersonAendern ernpReq = new PersonAendern();
+ ernpReq.setBegruendung(PROCESS_KITT_IDENITIES_UPDATE);
+
+ // set reference elements for person update
+ ernpReq.setEntityId(ernpPersonToKitt.getEntityId());
+ ernpReq.setVersion(ernpPersonToKitt.getVersion());
+
+ // add new eIDAS attributes
+ eidasDocumentToAdd.stream().forEach(el -> ernpReq.getAnlegen().addEidasItem(el));
+
+ // TODO: should we update MDS also in that step?
+
+
+ // request ZMR
+ 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 result = new HashSet<>();
+ addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(),
+ Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym(), true);
+ addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(),
+ Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth(), false);
+ addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(),
+ Constants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName(), false);
+
+ return result;
+
+ }
+
+ private void addEidasDocumentIfNotAvailable(Set result,
+ Person ernpPersonToKitt, String citizenCountryCode,
+ String attrName, String attrValue, boolean allowMoreThanOneEntry) {
+
+ if (StringUtils.isEmpty(attrValue)) {
+ log.trace("No eIDAS document: {}. Nothing todo for KITT process ... ", attrName);
+ return;
+
+ }
+
+ // check if eIDAS attribute is already includes an eIDAS-Document
+ boolean alreadyExist = ernpPersonToKitt.getEidas().stream()
+ .filter(el -> el.getWert().equals(attrValue)
+ && el.getArt().equals(attrName)
+ && el.getStaatscode2().equals(citizenCountryCode))
+ .findAny()
+ .isPresent();
+
+ if (!alreadyExist) {
+ // check eIDAS documents already contains a document with this pair of country-code and attribute-name
+ Optional oneDocWithNameExists = ernpPersonToKitt.getEidas().stream()
+ .filter(el -> el.getStaatscode2().equals(citizenCountryCode)
+ && el.getArt().equals(attrName))
+ .findAny();
+
+ if (!allowMoreThanOneEntry && oneDocWithNameExists.isPresent()
+ && !oneDocWithNameExists.get().getWert().equals(attrValue)) {
+ log.warn("eIDAS document: {} already exists for country: {} but attribute-value does not match. "
+ + "Skip update process because no multi-value allowed for this ... ",
+ attrName, citizenCountryCode);
+
+ } else {
+
+ Eidas eidasDocToAdd = new Eidas();
+ eidasDocToAdd.setStaatscode2(citizenCountryCode);
+ eidasDocToAdd.setArt(attrName);
+ eidasDocToAdd.setWert(attrValue);
+ log.info("Add eIDAS document: {} for country: {} to ERnP person", attrName, citizenCountryCode);
+ result.add(eidasDocToAdd);
+
+ }
+
+ } else {
+ log.debug("eIDAS document: {} already exists for country: {}. Skip update process for this ... ",
+ attrName, citizenCountryCode);
+
+ }
+ }
+
+ private Person searchPersonForUpdate(RegisterResult registerResult) throws WorkflowException {
+ // build generic request metadata
+ final GenericRequestParams generic = buildGenericRequestParameters("stepKittSearch");
+
+ // build search request
+ final Suchdaten searchInfos = new Suchdaten();
+ searchInfos.setFamilienname(registerResult.getFamilyName());
+ searchInfos.setVorname(registerResult.getGivenName());
+ searchInfos.setGeburtsdatum(buildErnpBirthday(registerResult.getDateOfBirth()));
+
+ final PersonSuchen personSuchen = new PersonSuchen();
+ personSuchen.setSuchoptionen(generateSearchParameters());
+ personSuchen.setBegruendung(PROCESS_KITT_IDENITIES_GET);
+ personSuchen.setSuchdaten(searchInfos);
+
+ // request ERnP
+ log.trace("Requesting ERnP for '{}' operation", PROCESS_KITT_IDENITIES_GET);
+ final SuchenResponse resp = ernpClient.suchen(generic.getClientBehkz(), generic.clientName,
+ generic.getClientRequestTime(), generic.getClientRequestId(), personSuchen);
+
+ // perform shot validation of ERnP response
+ if (resp.getPerson() == null || resp.getPerson().size() != 1) {
+ log.error("ERnP result contains NO 'Person' or 'Person' is empty");
+ throw new WorkflowException(PROCESS_KITT_IDENITIES_GET,
+ "Find NO data-set with already matchted eID during ERnP KITT process");
+
+ } else {
+ log.debug("Find person for '{}' operation", PROCESS_KITT_IDENITIES_GET);
+ return resp.getPerson().get(0);
+
+ }
}
@Override
@@ -270,7 +503,7 @@ public class ErnpRestClient implements IErnpClient {
Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER))
.familyName(person.getPersonendaten().getFamilienname())
.givenName(person.getPersonendaten().getVorname())
- .dateOfBirth(buildTextualBirthday(person.getPersonendaten().getGeburtsdatum()))
+ .dateOfBirth(getTextualBirthday(person.getPersonendaten().getGeburtsdatum()))
.bpk(person.getPersonendaten().getBpkZp())
.placeOfBirth(selectSingleEidasDocument(person, citizenCountryCode,
Constants.eIDAS_ATTRURN_PLACEOFBIRTH))
@@ -280,18 +513,31 @@ public class ErnpRestClient implements IErnpClient {
}
+ 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()));
+
+ //TODO: search eIDAS has to be a LIST!!!!!!
+ SuchEidas eidasInfos = new SuchEidas();
+ searchInfos.setEidas(eidasInfos );
+ return searchInfos;
+
+ }
+
/**
* Build AT specific Date String 'yyyy-MM-dd' from ERnP birthday representation.
*
*
- * Info: {@link LocalDate} can not be used, because '1940-00-00' is also
+ * Info: {@link LocalDate} can not be used, because '1940-00-00' is also
* a valid birthday on ERnP site.
*
*
* @param geburtsdatum ERnP birthday representation
* @return birthday in 'yyyy-MM-dd' format
*/
- private String buildTextualBirthday(PartialDate geburtsdatum) {
+ private String getTextualBirthday(PartialDate geburtsdatum) {
return MessageFormat.format("{0}-{1}-{2}",
String.valueOf(geburtsdatum.getJahr()),
String.format("%02d", geburtsdatum.getMonat()),
@@ -299,6 +545,29 @@ public class ErnpRestClient implements IErnpClient {
}
+ /**
+ * Map an AT specific Date String 'yyyy-MM-dd' to ERnP birthday representation.
+ *
+ *
+ * Info: {@link LocalDate} can not be used, because '1940-00-00' is also
+ * a valid birthday.
+ *
+ *
+ * @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;
+
+ }
+
/**
* Get all eIDAS document with the specified country code and document type.
*
@@ -364,7 +633,7 @@ public class ErnpRestClient implements IErnpClient {
private HttpMessageConverter> buildCustomJacksonObjectMapper() {
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
- converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
+ converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
converter.getObjectMapper()
.setSerializationInclusion(Include.NON_NULL);
return converter;
@@ -384,17 +653,14 @@ public class ErnpRestClient implements IErnpClient {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
- // TODO: implement errorHandling based on response infos
+ // TODO: opimize errorHandling based on response info's from real ERnP
+
+ List 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));
- if (response.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR) {
- log.warn("Receive http-server-error: {} from ERnP", response.getRawStatusCode());
-
- } else if (response.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR) {
- log.warn("Receive http-client-error: {} from ERnP", response.getRawStatusCode());
-
- }
-
throw new ErnpRestCommunicationException(response.getRawStatusCode());
+
}
};
}
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
index 72a5ece6..e3224c93 100644
--- 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
@@ -19,6 +19,6 @@ public class ErnpRestCommunicationException extends IOException {
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 fd9a67a9..488b571b 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
@@ -21,6 +21,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenti
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;
@@ -133,17 +134,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,
- new ErnpRegisterResult(Collections.emptyList()));
+ return RegisterStatusResults.fromEmpty(operationStatus);
}
@@ -383,6 +389,10 @@ public class RegisterSearchService {
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/InitialSearchTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java
index f295d66b..c720cb7f 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
@@ -185,7 +185,10 @@ public class InitialSearchTask extends AbstractAuthServletTask {
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
+
+ //TODO: update of ERnP information are allowed. Add ERnP update-step. Maybe we can use regular KITT steps
+
+
return searchResult;
} else {
log.debug("Register information match to eIDAS information. No update required");
--
cgit v1.2.3
From 8c08120d543f4eba2b1d1480d6649f13c46e9ef0 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Mon, 7 Feb 2022 10:37:42 +0100
Subject: feature(ernp): add person into ERnP of mathing ends with no result
---
.../auth/eidas/v2/clients/ernp/ErnpRestClient.java | 301 ++++++++++++---------
.../auth/eidas/v2/clients/ernp/IErnpClient.java | 12 +
.../auth/eidas/v2/ernp/DummyErnpClient.java | 5 +
.../eidas/v2/tasks/CreateNewErnpEntryTask.java | 58 ++--
4 files changed, 232 insertions(+), 144 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
index 2eaece1d..58b3ca45 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
@@ -41,11 +41,14 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.api.DefaultApi;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.invoker.ApiClient;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.AendernResponse;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.AnlegenResponse;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.Eidas;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.PartialDate;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.Person;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.PersonAendern;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.PersonAnlegen;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.PersonSuchen;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.Personendaten;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.SuchEidas;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.Suchdaten;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.SuchenResponse;
@@ -100,7 +103,8 @@ public class ErnpRestClient implements IErnpClient {
private static final String PROCESS_KITT_GENERAL = "KITT general-processing";
private static final String PROCESS_KITT_IDENITIES_GET = "KITT get-latest-version";
private static final String PROCESS_KITT_IDENITIES_UPDATE = "KITT update dataset";
-
+ private static final String PROCESS_ADD_IDENITY = "Add new person";
+
private static final String FRIENDLYNAME_HTTP_CLIENT = "ERnP Client";
// HTTP header-names from ERnP response
@@ -272,141 +276,41 @@ public class ErnpRestClient implements IErnpClient {
}
}
- private ErnpRegisterResult updatePersonInErnp(Person ernpPersonToKitt,
- Collection extends Eidas> eidasDocumentToAdd, String citizenCountryCode)
- throws ServiceFault {
+ @Override
+ public ErnpRegisterResult add(SimpleEidasData eidData) throws EidasSAuthenticationException {
// build generic request metadata
- final GenericRequestParams generic = buildGenericRequestParameters("stepKittUpdate");
+ final GenericRequestParams generic = buildGenericRequestParameters("stepNew");
// build update request
- PersonAendern ernpReq = new PersonAendern();
- ernpReq.setBegruendung(PROCESS_KITT_IDENITIES_UPDATE);
-
- // set reference elements for person update
- ernpReq.setEntityId(ernpPersonToKitt.getEntityId());
- ernpReq.setVersion(ernpPersonToKitt.getVersion());
-
- // add new eIDAS attributes
- eidasDocumentToAdd.stream().forEach(el -> ernpReq.getAnlegen().addEidasItem(el));
-
- // TODO: should we update MDS also in that step?
-
+ PersonAnlegen ernpReq = new PersonAnlegen();
+ ernpReq.setBegruendung(PROCESS_ADD_IDENITY);
+
+ // inject person data
+ Personendaten person = new Personendaten();
+ person.setFamilienname(eidData.getFamilyName());
+ person.setVorname(eidData.getGivenName());
+ person.setGeburtsdatum(buildErnpBirthday(eidData.getDateOfBirth()));
+ ernpReq.setPersonendaten(person);
- // request ZMR
- log.trace("Requesting ERnP for '{}' operation", PROCESS_KITT_IDENITIES_UPDATE);
- AendernResponse ernpResp = ernpClient.aendern(generic.getClientBehkz(), generic.clientName,
+ buildNewEidasDocumens(ernpReq, eidData);
+
+ // request ERnP
+ log.trace("Requesting ERnP for '{}' operation", PROCESS_ADD_IDENITY);
+ AnlegenResponse ernpResp = ernpClient.anlegen(generic.getClientBehkz(), generic.clientName,
generic.getClientRequestTime(), generic.getClientRequestId(), ernpReq);
- log.trace("Receive response from ERnP for '{}' operation", PROCESS_KITT_IDENITIES_UPDATE);
+ log.trace("Receive response from ERnP for '{}' operation", PROCESS_ADD_IDENITY);
return new ErnpRegisterResult(Arrays.asList(
- mapErnpResponseToRegisterResult(ernpResp.getPerson(), citizenCountryCode)));
-
- }
-
- private Collection 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 result = new HashSet<>();
- addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym(), true);
- addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth(), false);
- addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName(), false);
-
- return result;
+ mapErnpResponseToRegisterResult(ernpResp.getPerson(), eidData.getCitizenCountryCode())));
}
- private void addEidasDocumentIfNotAvailable(Set result,
- Person ernpPersonToKitt, String citizenCountryCode,
- String attrName, String attrValue, boolean allowMoreThanOneEntry) {
-
- if (StringUtils.isEmpty(attrValue)) {
- log.trace("No eIDAS document: {}. Nothing todo for KITT process ... ", attrName);
- return;
-
- }
-
- // check if eIDAS attribute is already includes an eIDAS-Document
- boolean alreadyExist = ernpPersonToKitt.getEidas().stream()
- .filter(el -> el.getWert().equals(attrValue)
- && el.getArt().equals(attrName)
- && el.getStaatscode2().equals(citizenCountryCode))
- .findAny()
- .isPresent();
-
- if (!alreadyExist) {
- // check eIDAS documents already contains a document with this pair of country-code and attribute-name
- Optional oneDocWithNameExists = ernpPersonToKitt.getEidas().stream()
- .filter(el -> el.getStaatscode2().equals(citizenCountryCode)
- && el.getArt().equals(attrName))
- .findAny();
-
- if (!allowMoreThanOneEntry && oneDocWithNameExists.isPresent()
- && !oneDocWithNameExists.get().getWert().equals(attrValue)) {
- log.warn("eIDAS document: {} already exists for country: {} but attribute-value does not match. "
- + "Skip update process because no multi-value allowed for this ... ",
- attrName, citizenCountryCode);
-
- } else {
-
- Eidas eidasDocToAdd = new Eidas();
- eidasDocToAdd.setStaatscode2(citizenCountryCode);
- eidasDocToAdd.setArt(attrName);
- eidasDocToAdd.setWert(attrValue);
- log.info("Add eIDAS document: {} for country: {} to ERnP person", attrName, citizenCountryCode);
- result.add(eidasDocToAdd);
-
- }
-
- } else {
- log.debug("eIDAS document: {} already exists for country: {}. Skip update process for this ... ",
- attrName, citizenCountryCode);
-
- }
- }
-
- private Person searchPersonForUpdate(RegisterResult registerResult) throws WorkflowException {
- // build generic request metadata
- final GenericRequestParams generic = buildGenericRequestParameters("stepKittSearch");
-
- // build search request
- final Suchdaten searchInfos = new Suchdaten();
- searchInfos.setFamilienname(registerResult.getFamilyName());
- searchInfos.setVorname(registerResult.getGivenName());
- searchInfos.setGeburtsdatum(buildErnpBirthday(registerResult.getDateOfBirth()));
-
- final PersonSuchen personSuchen = new PersonSuchen();
- personSuchen.setSuchoptionen(generateSearchParameters());
- personSuchen.setBegruendung(PROCESS_KITT_IDENITIES_GET);
- personSuchen.setSuchdaten(searchInfos);
-
- // request ERnP
- log.trace("Requesting ERnP for '{}' operation", PROCESS_KITT_IDENITIES_GET);
- final SuchenResponse resp = ernpClient.suchen(generic.getClientBehkz(), generic.clientName,
- generic.getClientRequestTime(), generic.getClientRequestId(), personSuchen);
-
- // perform shot validation of ERnP response
- if (resp.getPerson() == null || resp.getPerson().size() != 1) {
- log.error("ERnP result contains NO 'Person' or 'Person' is empty");
- throw new WorkflowException(PROCESS_KITT_IDENITIES_GET,
- "Find NO data-set with already matchted eID during ERnP KITT process");
-
- } else {
- log.debug("Find person for '{}' operation", PROCESS_KITT_IDENITIES_GET);
- return resp.getPerson().get(0);
-
- }
- }
-
@Override
public ErnpRegisterResult searchWithResidenceData(String givenName, String familyName, String dateOfBirth,
String zipcode, String city, String street) {
return new ErnpRegisterResult(Collections.emptyList());
}
-
+
@PostConstruct
private void initialize() throws EaafException {
// validate additional Ernp communication parameters
@@ -545,6 +449,161 @@ public class ErnpRestClient implements IErnpClient {
}
+ private ErnpRegisterResult updatePersonInErnp(Person ernpPersonToKitt,
+ Collection extends Eidas> eidasDocumentToAdd, String citizenCountryCode)
+ throws ServiceFault {
+ // build generic request metadata
+ final GenericRequestParams generic = buildGenericRequestParameters("stepKittUpdate");
+
+ // build update request
+ PersonAendern ernpReq = new PersonAendern();
+ ernpReq.setBegruendung(PROCESS_KITT_IDENITIES_UPDATE);
+
+ // set reference elements for person update
+ ernpReq.setEntityId(ernpPersonToKitt.getEntityId());
+ ernpReq.setVersion(ernpPersonToKitt.getVersion());
+
+ // add new eIDAS attributes
+ eidasDocumentToAdd.stream().forEach(el -> ernpReq.getAnlegen().addEidasItem(el));
+
+ // TODO: should we update MDS also in that step?
+
+
+ // request ERnP
+ log.trace("Requesting ERnP for '{}' operation", PROCESS_KITT_IDENITIES_UPDATE);
+ AendernResponse ernpResp = ernpClient.aendern(generic.getClientBehkz(), generic.clientName,
+ generic.getClientRequestTime(), generic.getClientRequestId(), ernpReq);
+ log.trace("Receive response from ERnP for '{}' operation", PROCESS_KITT_IDENITIES_UPDATE);
+
+ return new ErnpRegisterResult(Arrays.asList(
+ mapErnpResponseToRegisterResult(ernpResp.getPerson(), citizenCountryCode)));
+
+ }
+
+ private Collection 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 result = new HashSet<>();
+ addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(),
+ Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym(), true);
+ addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(),
+ Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth(), false);
+ addEidasDocumentIfNotAvailable(result, ernpPersonToKitt, eidData.getCitizenCountryCode(),
+ Constants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName(), false);
+
+ return result;
+
+ }
+
+ private void addEidasDocumentIfNotAvailable(Set result,
+ Person ernpPersonToKitt, String citizenCountryCode,
+ String attrName, String attrValue, boolean allowMoreThanOneEntry) {
+
+ if (StringUtils.isEmpty(attrValue)) {
+ log.trace("No eIDAS document: {}. Nothing todo for KITT process ... ", attrName);
+ return;
+
+ }
+
+ // check if eIDAS attribute is already includes an eIDAS-Document
+ boolean alreadyExist = ernpPersonToKitt.getEidas().stream()
+ .filter(el -> el.getWert().equals(attrValue)
+ && el.getArt().equals(attrName)
+ && el.getStaatscode2().equals(citizenCountryCode))
+ .findAny()
+ .isPresent();
+
+ if (!alreadyExist) {
+ // check eIDAS documents already contains a document with this pair of country-code and attribute-name
+ Optional oneDocWithNameExists = ernpPersonToKitt.getEidas().stream()
+ .filter(el -> el.getStaatscode2().equals(citizenCountryCode)
+ && el.getArt().equals(attrName))
+ .findAny();
+
+ if (!allowMoreThanOneEntry && oneDocWithNameExists.isPresent()
+ && !oneDocWithNameExists.get().getWert().equals(attrValue)) {
+ log.warn("eIDAS document: {} already exists for country: {} but attribute-value does not match. "
+ + "Skip update process because no multi-value allowed for this ... ",
+ attrName, citizenCountryCode);
+
+ } else {
+
+ Eidas eidasDocToAdd = new Eidas();
+ eidasDocToAdd.setStaatscode2(citizenCountryCode);
+ eidasDocToAdd.setArt(attrName);
+ eidasDocToAdd.setWert(attrValue);
+ log.info("Add eIDAS document: {} for country: {} to ERnP person", attrName, citizenCountryCode);
+ result.add(eidasDocToAdd);
+
+ }
+
+ } else {
+ log.debug("eIDAS document: {} already exists for country: {}. Skip update process for this ... ",
+ attrName, citizenCountryCode);
+
+ }
+ }
+
+ private Person searchPersonForUpdate(RegisterResult registerResult) throws WorkflowException {
+ // build generic request metadata
+ final GenericRequestParams generic = buildGenericRequestParameters("stepKittSearch");
+
+ // build search request
+ final Suchdaten searchInfos = new Suchdaten();
+ searchInfos.setFamilienname(registerResult.getFamilyName());
+ searchInfos.setVorname(registerResult.getGivenName());
+ searchInfos.setGeburtsdatum(buildErnpBirthday(registerResult.getDateOfBirth()));
+
+ final PersonSuchen personSuchen = new PersonSuchen();
+ personSuchen.setSuchoptionen(generateSearchParameters());
+ personSuchen.setBegruendung(PROCESS_KITT_IDENITIES_GET);
+ personSuchen.setSuchdaten(searchInfos);
+
+ // request ERnP
+ log.trace("Requesting ERnP for '{}' operation", PROCESS_KITT_IDENITIES_GET);
+ final SuchenResponse resp = ernpClient.suchen(generic.getClientBehkz(), generic.clientName,
+ generic.getClientRequestTime(), generic.getClientRequestId(), personSuchen);
+
+ // perform shot validation of ERnP response
+ if (resp.getPerson() == null || resp.getPerson().size() != 1) {
+ log.error("ERnP result contains NO 'Person' or 'Person' is empty");
+ throw new WorkflowException(PROCESS_KITT_IDENITIES_GET,
+ "Find NO data-set with already matchted eID during ERnP KITT process");
+
+ } else {
+ log.debug("Find person for '{}' operation", PROCESS_KITT_IDENITIES_GET);
+ return resp.getPerson().get(0);
+
+ }
+ }
+
+ private void buildNewEidasDocumens(PersonAnlegen ernpReq, SimpleEidasData eidData) {
+ ernpReq.addEidasItem(buildNewEidasDocument(eidData.getCitizenCountryCode(),
+ Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym()));
+
+ if (StringUtils.isNotEmpty(eidData.getPlaceOfBirth())) {
+ ernpReq.addEidasItem(buildNewEidasDocument(eidData.getCitizenCountryCode(),
+ Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth()));
+
+ }
+
+ if (StringUtils.isNotEmpty(eidData.getBirthName())) {
+ ernpReq.addEidasItem(buildNewEidasDocument(eidData.getCitizenCountryCode(),
+ Constants.eIDAS_ATTRURN_BIRTHNAME, eidData.getBirthName()));
+
+ }
+ }
+
+ private Eidas buildNewEidasDocument(String citizenCountryCode, String eidasAttrName,
+ String eidasAddrValue) {
+ Eidas el = new Eidas();
+ el.setArt(eidasAttrName);
+ el.setWert(eidasAddrValue);
+ el.setStaatscode2(citizenCountryCode);
+ return el;
+ }
+
/**
* Map an AT specific Date String 'yyyy-MM-dd' to ERnP birthday representation.
*
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java
index 4c8bcd3e..7a957531 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/IErnpClient.java
@@ -84,6 +84,18 @@ public interface IErnpClient {
ErnpRegisterResult update(RegisterResult registerResult, SimpleEidasData eidData)
throws EidasSAuthenticationException;
+
+ /**
+ * Add new entry into ERnP by using identity from this eIDAS authentication.
+ *
+ * @param eidData eIDAS eID information from current authentication process
+ * @return Update result but never null
+ * @throws EidasSAuthenticationException In case of a communication error
+ */
+ @Nonnull
+ ErnpRegisterResult add(SimpleEidasData eidData) throws EidasSAuthenticationException;
+
+
/**
* Search person based on address information.
*
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/DummyErnpClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/DummyErnpClient.java
index 52703232..dabb73dc 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/DummyErnpClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernp/DummyErnpClient.java
@@ -73,4 +73,9 @@ public class DummyErnpClient implements IErnpClient {
}
+ @Override
+ public ErnpRegisterResult add(SimpleEidasData eidData) throws EidasSAuthenticationException {
+ return buildEmptyResult();
+ }
+
}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateNewErnpEntryTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateNewErnpEntryTask.java
index 6fc6d499..b63b0ca0 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateNewErnpEntryTask.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateNewErnpEntryTask.java
@@ -26,9 +26,16 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.ErnpRestClient;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.ErnpRestClient.ErnpRegisterResult;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.MatchedPersonResult;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.WorkflowException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
@@ -46,6 +53,7 @@ import lombok.extern.slf4j.Slf4j;
* TODO MDS, BPK of new entry
*
*
+ * @author tlenz
* @author amarsalek
* @author ckollmann
*/
@@ -53,36 +61,40 @@ import lombok.extern.slf4j.Slf4j;
@Component("CreateNewErnbEntryTask")
public class CreateNewErnpEntryTask extends AbstractAuthServletTask {
- //private final SzrClient szrClient;
+ private final ErnpRestClient ernpClient;
- ///**
- // * Constructor.
- // * @param szrClient SZR client for creating a new ERnP entry
- // */
- //public CreateNewErnpEntryTask(SzrClient szrClient) {
- // this.szrClient = szrClient;
- //}
+ /**
+ * Constructor.
+ * @param szrClient SZR client for creating a new ERnP entry
+ */
+ public CreateNewErnpEntryTask(@Autowired ErnpRestClient client) {
+ this.ernpClient = client;
+ }
@Override
public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
throws TaskExecutionException {
try {
- //SimpleEidasData simpleEidasData = MatchingTaskUtils.getInitialEidasData(pendingReq);
-
- // insert person into ERnP
- //TODO: should we insert it directly into ERnP?
- //TODO: has to updated to new eIDAS document model in ERnP
- //String vsz = szrClient.createNewErnpEntry(simpleEidasData);
-
- // finish matching process, because new user-entry uniquly matches
- //log.info("User successfully registerred into ERnP and matching tasks are finished ");
- //MatchingTaskUtils.storeFinalMatchingResult(pendingReq,
- // MatchedPersonResult.builder()
- // .vsz(vsz)
- // .build());
-
- log.warn("Skipping new insert ERnP task, because it's currently unknown who we should it");
+ SimpleEidasData simpleEidasData = MatchingTaskUtils.getInitialEidasData(pendingReq);
+ if (simpleEidasData == null) {
+ throw new WorkflowException("step09", "No initial eIDAS authn data", true);
+
+ }
+ //add person into ERnP
+ ErnpRegisterResult resp = ernpClient.add(simpleEidasData);
+ if (resp.getPersonResult().size() != 1) {
+ log.error("Receive {} from ERnP during 'add person' step",
+ resp.getPersonResult().isEmpty() ? "no result" : "more-than-one result");
+ throw new WorkflowException("step09", "Add person into ERnP failed", true);
+
+ }
+
+ // finish matching process, because new user-entry uniquly matches
+ log.info("User successfully registerred into ERnP and matching tasks are finished ");
+ MatchingTaskUtils.storeFinalMatchingResult(pendingReq,
+ MatchedPersonResult.generateFormMatchingResult(
+ resp.getPersonResult().get(0), simpleEidasData.getCitizenCountryCode()));
} catch (final Exception e) {
log.error("Initial search FAILED.", e);
--
cgit v1.2.3
From 1a442f77692a0438cc9d43be563b0ca965ff6c2b Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Mon, 7 Feb 2022 11:17:42 +0100
Subject: refactor(szr): remove 'insertErnp' functionality from SZR client.
After this, the person is directly added into ERnP by using ErnpRestClient
---
.../auth/eidas/v2/clients/szr/SzrClient.java | 49 ----------------------
.../eidas/v2/tasks/CreateIdentityLinkTask.java | 29 ++-----------
2 files changed, 4 insertions(+), 74 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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.
- *
- * Note: Previously, this method did create a new ERnP entry, if it did not exist. This is
- * not 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/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..740e5292 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
@@ -86,9 +86,6 @@ import szrservices.IdentityLinkType;
*
* - {@link at.gv.egiz.eaaf.core.impl.idp.controller.tasks.FinalizeAuthenticationTask}
*
- * 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
@@ -192,16 +189,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);
@@ -252,18 +241,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();
--
cgit v1.2.3
From e9bb7aeaf5a9f7a445907ccb2abc96635e5b534c Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Mon, 7 Feb 2022 11:37:22 +0100
Subject: chore(szr): remove dummy code for SZR emulation
---
.../eidas/v2/tasks/CreateIdentityLinkTask.java | 97 ++--------------------
1 file changed, 6 insertions(+), 91 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 740e5292..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;
@@ -124,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);
@@ -213,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(
@@ -343,63 +317,4 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask {
final String bpK;
}
-
- /**
- * Build a dummy IdentityLink and a dummy bPK based on eIDAS information.
- *
- *
- * FOR LOCAL TESTING ONLY!!!
- *
- * @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 bpkCalc = BpkBuilder.generateAreaSpecificPersonIdentifier(idValue, idType, targetId);
- return new SzrResultHolder(identityLink, bpkCalc.getFirst());
-
- }
-
}
--
cgit v1.2.3
From b430405209fb61d7de7dec19fe9b2da780a575ac Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Mon, 7 Feb 2022 15:11:55 +0100
Subject: feature(ernp): update MDS if register information does not match to
information from eIDAS
---
.../auth/eidas/v2/clients/ernp/ErnpRestClient.java | 111 ++++++++++++++++-----
1 file changed, 85 insertions(+), 26 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
index 58b3ca45..15b7573c 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
@@ -38,8 +38,10 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include;
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.AnlegenResponse;
import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.Eidas;
@@ -49,6 +51,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ernp.model.PersonAen
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;
@@ -247,10 +250,11 @@ public class ErnpRestClient implements IErnpClient {
// select elements that have to be updated
Collection extends Eidas> eidasDocumentToAdd =
- selectEidasDocumentsToAdd(ernpPersonToKitt, eidData);
+ selectEidasDocumentsToAdd(ernpPersonToKitt, eidData);
+ SimpleEidasData mdsToUpdate = selectMdsInformationToUpdate(ernpPersonToKitt, eidData);
- if (eidasDocumentToAdd.isEmpty()) {
- log.info("Find no eIDAS document for update during: {}. Looks strange but nothing todo",
+ 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));
@@ -258,7 +262,7 @@ public class ErnpRestClient implements IErnpClient {
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, eidData.getCitizenCountryCode());
+ return updatePersonInErnp(ernpPersonToKitt, eidasDocumentToAdd, mdsToUpdate, eidData.getCitizenCountryCode());
}
@@ -430,27 +434,8 @@ public class ErnpRestClient implements IErnpClient {
}
- /**
- * Build AT specific Date String 'yyyy-MM-dd' from ERnP birthday representation.
- *
- *
- * Info: {@link LocalDate} can not be used, because '1940-00-00' is also
- * a valid birthday on ERnP site.
- *
- *
- * @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()));
-
- }
-
private ErnpRegisterResult updatePersonInErnp(Person ernpPersonToKitt,
- Collection extends Eidas> eidasDocumentToAdd, String citizenCountryCode)
+ Collection extends Eidas> eidasDocumentToAdd, SimpleEidasData mdsToUpdate, String citizenCountryCode)
throws ServiceFault {
// build generic request metadata
final GenericRequestParams generic = buildGenericRequestParameters("stepKittUpdate");
@@ -466,8 +451,12 @@ public class ErnpRestClient implements IErnpClient {
// add new eIDAS attributes
eidasDocumentToAdd.stream().forEach(el -> ernpReq.getAnlegen().addEidasItem(el));
- // TODO: should we update MDS also in that step?
-
+ // 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);
@@ -604,6 +593,56 @@ public class ErnpRestClient implements IErnpClient {
return el;
}
+ private SimpleEidasData selectMdsInformationToUpdate(Person ernpPersonToKitt, SimpleEidasData eidData) {
+ PersonendatenErgebnis person = ernpPersonToKitt.getPersonendaten();
+ SimpleEidasDataBuilder builder = SimpleEidasData.builder();
+
+ boolean findMismatch = false;
+ if (!person.getVorname().equals(eidData.getGivenName())) {
+ findMismatch = true;
+ builder.givenName(eidData.getGivenName());
+
+ }
+
+ if (!person.getFamilienname().equals(eidData.getFamilyName())) {
+ findMismatch = true;
+ builder.familyName(eidData.getFamilyName());
+
+ }
+
+ if (!getTextualBirthday(person.getGeburtsdatum()).equals(eidData.getDateOfBirth())) {
+ findMismatch = true;
+ builder.dateOfBirth(eidData.getDateOfBirth());
+
+ }
+
+ return findMismatch ? builder.build() : null;
+ }
+
+ private Aendern generateMdsChangeRequest(Person ernpPersonToKitt, SimpleEidasData mdsToUpdate) {
+ Aendern el = new Aendern();
+ Personendaten person = new Personendaten();
+ person.setEntityId(ernpPersonToKitt.getPersonendaten().getEntityId());
+ el.setPersonendaten(person);
+
+ if (StringUtils.isNotEmpty(mdsToUpdate.getFamilyName())) {
+ person.setFamilienname(mdsToUpdate.getFamilyName());
+
+ }
+
+ if (StringUtils.isNotEmpty(mdsToUpdate.getGivenName())) {
+ person.setVorname(mdsToUpdate.getGivenName());
+
+ }
+
+ if (StringUtils.isNotEmpty(mdsToUpdate.getDateOfBirth())) {
+ person.setGeburtsdatum(buildErnpBirthday(mdsToUpdate.getDateOfBirth()));
+
+ }
+ return el;
+
+ }
+
/**
* Map an AT specific Date String 'yyyy-MM-dd' to ERnP birthday representation.
*
@@ -626,6 +665,26 @@ public class ErnpRestClient implements IErnpClient {
return result;
}
+
+ /**
+ * Build AT specific Date String 'yyyy-MM-dd' from ERnP birthday representation.
+ *
+ *
+ * Info: {@link LocalDate} can not be used, because '1940-00-00' is also
+ * a valid birthday on ERnP site.
+ *
+ *
+ * @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.
--
cgit v1.2.3
From 5b0a9142a0e00fa528f86f8fe432c0e44ed4ae8e Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Mon, 7 Feb 2022 15:19:56 +0100
Subject: refactor(matching): change 'kitt' and 'update' steps in
'InitialSearchTask'
- Update MDS in case of changes eIDAS data and already existing ERnP entry
- Add additional attributes in case of new eIDAS attributes outside of MDS
---
.../modules/auth/eidas/v2/dao/SimpleEidasData.java | 22 ++++++++++--
.../eidas/v2/service/RegisterSearchService.java | 22 ++++++++++--
.../auth/eidas/v2/tasks/InitialSearchTask.java | 42 +++++++++++-----------
3 files changed, 59 insertions(+), 27 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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..e76768b6 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,10 +23,11 @@
package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao;
+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
@@ -68,8 +69,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 +88,17 @@ public class SimpleEidasData {
.isEquals();
}
+ /**
+ * Check if eIDAS attribute is available.
+ *
+ * @param registerData Attribute value from register
+ * @param eidasData Attribute value from eIDAS
+ * @return true
if eidasData is null
or eidasData does not match to register value,
+ * otherwise false
+ */
+ 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/service/RegisterSearchService.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/RegisterSearchService.java
index 488b571b..85ea942c 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,6 +7,7 @@ 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;
@@ -186,34 +187,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);
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.
+ *
+ * This method perform two additional operations:
+ *
+ * - Use bPK to check if altSearchResult is part of initialSearchResult.
+ * - Update register entry twice, be using information from alternative authentication altEidasData
+ * and from initial authentication initialEidasData.
+ *
+ *
*
* @param initialSearchResult Register results from initial authentication
* @param initialEidasData Received eIDAS data from initial authentication
@@ -273,7 +289,7 @@ public class RegisterSearchService {
// update ZMR entry by using eIDAS information from alternative authentication
ErnpRegisterResult updateAlt = ernpClient.update(entryErnp, altEidasData);
- return RegisterStatusResults.fromErnp(altSearchResult.operationStatus, updateAlt);
+ return RegisterStatusResults.fromErnp(altSearchResult.getOperationStatus(), updateAlt);
}
} catch (final EidasSAuthenticationException e) {
throw new WorkflowException("kittMatchedIdentitiess", e.getMessage(),
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 c720cb7f..9564a8fc 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);
@@ -172,29 +175,26 @@ public class InitialSearchTask extends AbstractAuthServletTask {
}
}
- 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: update of ERnP information are allowed. Add ERnP update-step. Maybe we can use regular KITT steps
-
+ if (!eidasData.equalsRegisterData(searchResult.getResult())) {
+ log.debug("PersonalIdentifier match but MDS or other information changed. Starting update process ... ");
+ return registerSearchService.step7aKittProcess(searchResult, eidasData).getResult();
- return searchResult;
} 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()
--
cgit v1.2.3
From 02e3d1b479234ac8d028f00263cfc1b311209a0c Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Mon, 7 Feb 2022 15:20:29 +0100
Subject: chore(mathing): change log level ZMRClient
---
.../eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 432df9ef..18a80c33 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
@@ -269,7 +269,7 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient {
selectEidasDocumentsToAdd(zmrPersonToKitt, eidData);
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);
--
cgit v1.2.3
From cc54421d99604cd2f2b01846f94bb11fb192028d Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Mon, 7 Feb 2022 18:22:27 +0100
Subject: chore(matching): fix some code-style and code-quality issues
---
.../auth/eidas/v2/clients/ernp/ErnpRestClient.java | 20 ++++++++++----------
.../v2/exception/ErnpRestCommunicationException.java | 5 +++++
.../auth/eidas/v2/tasks/CreateNewErnpEntryTask.java | 2 +-
3 files changed, 16 insertions(+), 11 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
index 15b7573c..3c19e9c1 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
@@ -86,7 +86,7 @@ import lombok.extern.slf4j.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_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}";
@@ -95,8 +95,8 @@ public class ErnpRestClient implements IErnpClient {
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 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;
@@ -429,7 +429,7 @@ public class ErnpRestClient implements IErnpClient {
//TODO: search eIDAS has to be a LIST!!!!!!
SuchEidas eidasInfos = new SuchEidas();
- searchInfos.setEidas(eidasInfos );
+ searchInfos.setEidas(eidasInfos);
return searchInfos;
}
@@ -542,7 +542,7 @@ public class ErnpRestClient implements IErnpClient {
final Suchdaten searchInfos = new Suchdaten();
searchInfos.setFamilienname(registerResult.getFamilyName());
searchInfos.setVorname(registerResult.getGivenName());
- searchInfos.setGeburtsdatum(buildErnpBirthday(registerResult.getDateOfBirth()));
+ searchInfos.setGeburtsdatum(buildErnpBirthday(registerResult.getDateOfBirth()));
final PersonSuchen personSuchen = new PersonSuchen();
personSuchen.setSuchoptionen(generateSearchParameters());
@@ -572,8 +572,8 @@ public class ErnpRestClient implements IErnpClient {
Constants.eIDAS_ATTRURN_PERSONALIDENTIFIER, eidData.getPseudonym()));
if (StringUtils.isNotEmpty(eidData.getPlaceOfBirth())) {
- ernpReq.addEidasItem(buildNewEidasDocument(eidData.getCitizenCountryCode(),
- Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth()));
+ ernpReq.addEidasItem(buildNewEidasDocument(eidData.getCitizenCountryCode(),
+ Constants.eIDAS_ATTRURN_PLACEOFBIRTH, eidData.getPlaceOfBirth()));
}
@@ -773,9 +773,9 @@ public class ErnpRestClient implements IErnpClient {
public void handleError(ClientHttpResponse response) throws IOException {
// TODO: opimize errorHandling based on response info's from real ERnP
- List 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));
+ List 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));
throw new ErnpRestCommunicationException(response.getRawStatusCode());
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
index e3224c93..566a8fa4 100644
--- 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
@@ -16,6 +16,11 @@ public class ErnpRestCommunicationException extends IOException {
@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/tasks/CreateNewErnpEntryTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/CreateNewErnpEntryTask.java
index b63b0ca0..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
@@ -65,7 +65,7 @@ public class CreateNewErnpEntryTask extends AbstractAuthServletTask {
/**
* Constructor.
- * @param szrClient SZR client for creating a new ERnP entry
+ * @param client SZR client for creating a new ERnP entry
*/
public CreateNewErnpEntryTask(@Autowired ErnpRestClient client) {
this.ernpClient = client;
--
cgit v1.2.3
From 6e7c333ec6e9a6fe33737ee3a67a23433854a55b Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Mon, 7 Feb 2022 18:37:05 +0100
Subject: fix(matching): make matching DTO's serializeable because the has to
be stored into session
---
.../specific/modules/auth/eidas/v2/dao/MatchedPersonResult.java | 6 +++++-
.../eidas/specific/modules/auth/eidas/v2/dao/RegisterResult.java | 5 ++++-
.../eidas/specific/modules/auth/eidas/v2/dao/SimpleEidasData.java | 6 +++++-
.../modules/auth/eidas/v2/dao/SimpleMobileSignatureData.java | 6 +++++-
4 files changed, 19 insertions(+), 4 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 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 e76768b6..f9301505 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,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 at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType;
@@ -31,7 +33,9 @@ import lombok.Data;
@Data
@Builder
-public class SimpleEidasData {
+public class SimpleEidasData implements Serializable {
+
+ private static final long serialVersionUID = 2848914124372968418L;
/**
* Full eIDAS personal identifier with prefix.
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;
--
cgit v1.2.3
From 1a5d7bd12b0028b7cdb4e1b5e99d6162a323dce8 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Tue, 8 Feb 2022 08:07:48 +0100
Subject: chore(ernp): ignore search requests with residence information.
ERnP search is not used here, because we only search for people with Austrian residence and they are in ZMR only.
---
.../specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
index 3c19e9c1..3822da01 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
@@ -311,8 +311,10 @@ public class ErnpRestClient implements IErnpClient {
@Override
public ErnpRegisterResult searchWithResidenceData(String givenName, String familyName, String dateOfBirth,
- String zipcode, String city, String street) {
+ 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
--
cgit v1.2.3
From a2baf085fcd3a1940585beb3f4a8acb2e4e5a461 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Tue, 8 Feb 2022 11:40:01 +0100
Subject: refactor(matching): move AddresssucheController into eIDAS module to
reuse data-model for tasks
---
.../eidas/v2/controller/AdresssucheController.java | 258 +++++++++++++++++++++
1 file changed, 258 insertions(+)
create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/controller/AdresssucheController.java
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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..8505f5d5
--- /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,258 @@
+/*
+ * 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.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 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 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 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 results;
+ private final int resultCount;
+ }
+
+ @Data
+ @AllArgsConstructor
+ public static class AdresssucheOutput implements Comparable {
+ 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();
+ }
+ }
+
+}
--
cgit v1.2.3
From 33404685b1d8de14229f61ea5dfa1fbee6229916 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Tue, 8 Feb 2022 14:50:03 +0100
Subject: feature(matching): finalize matching by residence search
Add ZMR communication and state validation for match-by-residence operation
---
.../specific/modules/auth/eidas/v2/Constants.java | 4 +-
.../auth/eidas/v2/clients/zmr/IZmrClient.java | 21 ++-
.../auth/eidas/v2/clients/zmr/ZmrSoapClient.java | 96 +++++++++--
.../eidas/v2/controller/AdresssucheController.java | 11 ++
.../eidas/v2/service/RegisterSearchService.java | 28 ++--
.../ReceiveAustrianResidenceGuiResponseTask.java | 175 +++++++++++----------
6 files changed, 230 insertions(+), 105 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 6da30299..40bcd27a 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
@@ -314,10 +314,12 @@ public class Constants {
// UI options
public static final String HTML_FORM_ADVANCED_MATCHING_FAILED = "advancedMatchingFailed";
-
+
// 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/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;
@@ -79,6 +80,23 @@ public interface IZmrClient {
@Nonnull PersonSuchenRequest personSearchDao, @Nonnull String citizenCountryCode)
throws EidasSAuthenticationException;
+ /**
+ * Search person based on MDS information and Austrian residence.
+ *
+ * @param zmrProzessId zmrProzessId zmrProzessId ProcessId from ZMR or null
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 null
+ * @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.
*
@@ -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 18a80c33..0f2f94cc 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,6 +98,7 @@ 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";
@@ -173,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));
@@ -296,12 +292,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_SEARCH_BY_RESIDENCE, 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
@@ -685,6 +718,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) {
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
index 8505f5d5..6dcd4879 100644
--- 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
@@ -58,6 +58,7 @@ 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;
@@ -166,18 +167,23 @@ public class AdresssucheController {
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();
+
}
}
@@ -185,7 +191,9 @@ public class AdresssucheController {
if (searchOutput.getPersonResult().isEmpty()) {
log.warn("No result from ZMR");
return new AdresssucheResult(Collections.emptyList(), 0);
+
}
+
log.info("Result level is {}", searchOutput.getLevel());
Set result = searchOutput.getPersonResult().stream()
.map(Adressdaten::getPostAdresse)
@@ -195,6 +203,7 @@ public class AdresssucheController {
// TODO Add configuration option for the limit of 30
List sorted = result.stream().sorted().limit(30).collect(Collectors.toList());
return new AdresssucheResult(sorted, result.size());
+
}
private Adressdaten buildSearchInput(String postleitzahl,
@@ -225,6 +234,7 @@ public class AdresssucheController {
Adressdaten searchInput = new Adressdaten();
searchInput.setPostAdresse(postAdresse);
return searchInput;
+
}
@Data
@@ -236,6 +246,7 @@ public class AdresssucheController {
@Data
@AllArgsConstructor
+ @Builder
public static class AdresssucheOutput implements Comparable {
private final String postleitzahl;
private final String municipality;
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 85ea942c..d95aadda 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
@@ -16,6 +16,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.ErnpRestCli
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.exception.EidasSAuthenticationException;
@@ -165,18 +166,27 @@ 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);
+ }
}
/**
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..67addf94 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
*
* Transitions:
*
- * - {@link CreateNewErnpEntryTask} if no results from search with residency data in registers
+ * - {@link GenerateOtherLoginMethodGuiTask} if no results from search with residency data in registers
* - {@link CreateIdentityLinkTask} if one exact match between initial register search (with MDS) and results
* from search with residency data in registers exists
* - {@link GenerateOtherLoginMethodGuiTask} if a user input error has happened
@@ -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_20);
+ 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(executionContext, 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 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(ExecutionContext executionContext,
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) {
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 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();
}
}
--
cgit v1.2.3
From d4027bf1ac134e50a1b8f1a59f862cf8abaa6c8c Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Tue, 8 Feb 2022 15:43:39 +0100
Subject: fix(zmr): update wrong workflow identifier in ZMR request in case of
match-by-residence step
---
.../eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 0f2f94cc..11c7cffe 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
@@ -308,7 +308,7 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient {
searchPersonReq.setPostAdresse(buildSearchAddress(address));
// set work-flow client information
- req.setWorkflowInfoClient(generateWorkFlowInfos(PROCESS_SEARCH_BY_RESIDENCE, zmrProzessId));
+ req.setWorkflowInfoClient(generateWorkFlowInfos(PROCESS_TASK_SEARCH, zmrProzessId));
req.setClientInfo(generateClientInfos());
// set additionl search parameters
--
cgit v1.2.3
From e3eae0a6f822d66f33c1a32459dd4ba3cfc76852 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Tue, 8 Feb 2022 16:31:08 +0100
Subject: chore(matching): update matching by 'ID Austria login' to forward
user to 'otherLoginMethod' GUI in case of an error
---
.../v2/tasks/ReceiveMobilePhoneSignatureResponseTask.java | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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..2d28709b 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 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(Constants.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;
}
--
cgit v1.2.3
From 6936c9a9350ad5d83f6c84d649df63d5de1c188a Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Tue, 8 Feb 2022 16:37:50 +0100
Subject: chore(matching): update matching by 'alternative eIDAS Login' to
forward user to 'otherLoginMethod' GUI in case of an error and show specific
error message
---
.../specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java | 6 ++++++
1 file changed, 6 insertions(+)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 ... ");
--
cgit v1.2.3
From 71d94fdd4435187c13321322893cd9b1bf273402 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Tue, 8 Feb 2022 17:16:42 +0100
Subject: chore(matching): update 'other-login-method' GUI steps to use it as
common starting-point for any other alternative matching method
---
.../eidas/specific/modules/auth/eidas/v2/Constants.java | 4 +++-
.../eidas/v2/tasks/GenerateOtherLoginMethodGuiTask.java | 7 +++++++
.../tasks/ReceiveOtherLoginMethodGuiResponseTask.java | 17 ++++++++++-------
3 files changed, 20 insertions(+), 8 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 40bcd27a..e642c5ec 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
@@ -314,12 +314,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";
+ 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/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/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);
}
}
--
cgit v1.2.3
From a16e5ba2c6030788524e6dc49f6bb5ae4f0cabe0 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Tue, 8 Feb 2022 17:17:52 +0100
Subject: chore(core): add log message and add empty lines for better reading
---
.../eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java | 2 ++
.../auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java | 1 +
2 files changed, 3 insertions(+)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 9564a8fc..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
@@ -167,11 +167,13 @@ 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);
+
}
}
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 67addf94..08d2bfa1 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
@@ -190,6 +190,7 @@ public class ReceiveAustrianResidenceGuiResponseTask extends AbstractLocaleAuthS
}
} catch (WorkflowException e) {
+ log.warn("Kitt operation after successful residence matching FAILED.", e);
throw new TaskExecutionException(pendingReq, "Search failed", new ManualFixNecessaryException(eidasData));
}
--
cgit v1.2.3
From 0fb02a267d231ce130f7ea419cade9a0cc79bb6e Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Tue, 8 Feb 2022 17:35:24 +0100
Subject: fix(matching): update wrong error-reason and remove an unused method
parameter
---
.../v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 08d2bfa1..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
@@ -117,11 +117,11 @@ public class ReceiveAustrianResidenceGuiResponseTask extends AbstractLocaleAuthS
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 ... ");
+ 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_20);
- executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true);
+
+ executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON, MSG_PROP_21);
+ executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true);
return;
}
@@ -145,7 +145,7 @@ public class ReceiveAustrianResidenceGuiResponseTask extends AbstractLocaleAuthS
} else {
log.debug("Find single match by using residence information. Starting data validation ... ");
- compareSearchResultWithInitialData(executionContext, residencyResult, eidasData);
+ compareSearchResultWithInitialData(residencyResult, eidasData);
}
@@ -167,8 +167,7 @@ public class ReceiveAustrianResidenceGuiResponseTask extends AbstractLocaleAuthS
&& StringUtils.isEmpty(input.getVillage());
}
- private void compareSearchResultWithInitialData(ExecutionContext executionContext,
- RegisterStatusResults residencyResult, SimpleEidasData eidasData)
+ private void compareSearchResultWithInitialData(RegisterStatusResults residencyResult, SimpleEidasData eidasData)
throws TaskExecutionException, EaafStorageException {
try {
if (!eidasData.equalsRegisterData(residencyResult.getResult())) {
--
cgit v1.2.3
From 474fc2b1c7645672e3ed60039177c3c04ba85dc9 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Tue, 8 Feb 2022 17:41:14 +0100
Subject: chore(core): fix some code-quality and code-style issues
---
.../specific/modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java | 2 +-
.../modules/auth/eidas/v2/service/RegisterSearchService.java | 6 ++++--
.../eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseTask.java | 2 +-
3 files changed, 6 insertions(+), 4 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 11c7cffe..f24c75eb 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
@@ -731,7 +731,7 @@ public class ZmrSoapClient extends AbstractSoapClient implements IZmrClient {
private PostAdresseTyp buildSearchAddress(AdresssucheOutput address) {
PostAdresseTyp postAdresse = new PostAdresseTyp();
- if (StringUtils.isNotBlank(address.getPostleitzahl())){
+ if (StringUtils.isNotBlank(address.getPostleitzahl())) {
postAdresse.setPostleitzahl(address.getPostleitzahl());
}
if (StringUtils.isNotBlank(address.getMunicipality())) {
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 d95aadda..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
@@ -174,11 +174,13 @@ public class RegisterSearchService {
public RegisterStatusResults searchWithResidence(RegisterOperationStatus operationStatus, SimpleEidasData eidasData,
AdresssucheOutput address) throws WorkflowException {
try {
- final ZmrRegisterResult resultsZmr = zmrClient.searchWithResidenceData(
+ 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
+ /* 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);
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 2d28709b..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
@@ -156,7 +156,7 @@ public class ReceiveMobilePhoneSignatureResponseTask extends AbstractAuthServlet
Pair 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_OTHER_LOGIN_METHOD_GUI_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;
--
cgit v1.2.3
From e4ccd3df84e7ea509e66f2f832719529fe408839 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Wed, 9 Feb 2022 08:34:26 +0100
Subject: feature(zmr): add MDS attributes as 'eIdAS-Documents' too
ZMR does not allow MDS update on regular places. Therefore, we add it as 'eIDAS-Documents' for later usage.
---
.../eidas/specific/modules/auth/eidas/v2/Constants.java | 8 +++++++-
.../modules/auth/eidas/v2/clients/zmr/ZmrSoapClient.java | 12 ++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 e642c5ec..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
@@ -268,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 =
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 f24c75eb..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
@@ -264,6 +264,10 @@ 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: {}. Nothing todo on ZMR side",
PROCESS_KITT_GENERAL);
@@ -766,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;
--
cgit v1.2.3
From be411ba3e668eb86f87c0d8a021989d97b63c7a3 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Wed, 2 Mar 2022 13:10:39 +0100
Subject: chore(ernp): update ERnP REST API to v1.5.1
---
.../auth/eidas/v2/clients/ernp/ErnpRestClient.java | 25 ++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
index 3822da01..45a4010b 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
@@ -62,6 +62,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.ErnpRestCommun
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;
@@ -142,7 +143,7 @@ public class ErnpRestClient implements IErnpClient {
personSuchen.setSuchoptionen(generateSearchParameters());
personSuchen.setBegruendung(PROCESS_SEARCH_PERSONAL_IDENTIFIER);
final Suchdaten searchInfos = new Suchdaten();
- searchInfos.setEidas(eidasInfos);
+ searchInfos.setEidas(Arrays.asList(eidasInfos));
personSuchen.setSuchdaten(searchInfos);
// request ERnP
@@ -429,9 +430,11 @@ public class ErnpRestClient implements IErnpClient {
searchInfos.setVorname(personSearchDao.getNatuerlichePerson().getPersonenName().getVorname());
searchInfos.setGeburtsdatum(buildErnpBirthday(personSearchDao.getNatuerlichePerson().getGeburtsdatum()));
- //TODO: search eIDAS has to be a LIST!!!!!!
- SuchEidas eidasInfos = new SuchEidas();
- searchInfos.setEidas(eidasInfos);
+ // map all eIDAS documents into ERnP format
+ searchInfos.setEidas(personSearchDao.getEidasSuchdaten().stream()
+ .map(el -> buildErnpEidasDocument(el))
+ .collect(Collectors.toList()));
+
return searchInfos;
}
@@ -668,6 +671,20 @@ public class ErnpRestClient implements IErnpClient {
}
+ /**
+ * 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.
*
--
cgit v1.2.3
From df894a4076abbcb4357509eb453f4c447a8856d5 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Thu, 3 Mar 2022 11:42:53 +0100
Subject: chore(ernp): optimize ERnP client based on results from integration
test
---
.../auth/eidas/v2/clients/ernp/ErnpRestClient.java | 74 +++++++++++-----------
1 file changed, 38 insertions(+), 36 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
index 45a4010b..66fec9dc 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
@@ -17,6 +17,7 @@ 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;
@@ -34,6 +35,8 @@ 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;
@@ -43,6 +46,7 @@ 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;
@@ -206,37 +210,39 @@ public class ErnpRestClient implements IErnpClient {
throw new EidasSAuthenticationException(ERROR_MATCHING_99, new Object[] { e.getMessage() }, e);
}
}
-
+
@Override
public ErnpRegisterResult searchCountrySpecific(PersonSuchenRequest personSearchDao,
String citizenCountryCode) throws EidasSAuthenticationException {
- try {
+ 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(PROCESS_SEARCH_COUNTRY_SPECIFIC);
+ personSuchen.setBegruendung(countrySearchMsg);
personSuchen.setSuchdaten(mapCountrySpecificSearchData(personSearchDao));
// request ERnP
- log.trace("Requesting ERnP for '{}' operation", PROCESS_SEARCH_COUNTRY_SPECIFIC);
+ 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, false, PROCESS_SEARCH_COUNTRY_SPECIFIC);
+ return processErnpResponse(resp, citizenCountryCode, false, countrySearchMsg);
} catch (RestClientException e) {
- log.warn(LOGMSG_ERNP_ERROR, PROCESS_SEARCH_COUNTRY_SPECIFIC, e.getMessage());
+ 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, PROCESS_SEARCH_COUNTRY_SPECIFIC, e.getMessage());
+ log.warn(LOGMSG_ERNP_RESP_PROCESS, countrySearchMsg, e.getMessage());
throw new EidasSAuthenticationException(ERROR_MATCHING_99, new Object[] { e.getMessage() }, e);
}
@@ -268,14 +274,14 @@ public class ErnpRestClient implements IErnpClient {
}
} catch (RestClientException e) {
- log.warn(LOGMSG_ERNP_ERROR, PROCESS_SEARCH_COUNTRY_SPECIFIC, e.getMessage());
+ 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_SEARCH_COUNTRY_SPECIFIC, e.getMessage());
+ log.warn(LOGMSG_ERNP_RESP_PROCESS, PROCESS_KITT_GENERAL, e.getMessage());
throw new EidasSAuthenticationException(ERROR_MATCHING_99, new Object[] { e.getMessage() }, e);
}
@@ -454,7 +460,12 @@ public class ErnpRestClient implements IErnpClient {
ernpReq.setVersion(ernpPersonToKitt.getVersion());
// add new eIDAS attributes
- eidasDocumentToAdd.stream().forEach(el -> ernpReq.getAnlegen().addEidasItem(el));
+ 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) {
@@ -545,10 +556,11 @@ public class ErnpRestClient implements IErnpClient {
// 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()));
-
+ searchInfos.setGeburtsdatum(buildErnpBirthday(registerResult.getDateOfBirth()));
+
final PersonSuchen personSuchen = new PersonSuchen();
personSuchen.setSuchoptionen(generateSearchParameters());
personSuchen.setBegruendung(PROCESS_KITT_IDENITIES_GET);
@@ -600,28 +612,16 @@ public class ErnpRestClient implements IErnpClient {
private SimpleEidasData selectMdsInformationToUpdate(Person ernpPersonToKitt, SimpleEidasData eidData) {
PersonendatenErgebnis person = ernpPersonToKitt.getPersonendaten();
- SimpleEidasDataBuilder builder = SimpleEidasData.builder();
+ SimpleEidasDataBuilder builder = SimpleEidasData.builder()
+ .givenName(eidData.getGivenName())
+ .familyName(eidData.getFamilyName())
+ .dateOfBirth(eidData.getDateOfBirth());
- boolean findMismatch = false;
- if (!person.getVorname().equals(eidData.getGivenName())) {
- findMismatch = true;
- builder.givenName(eidData.getGivenName());
-
- }
-
- if (!person.getFamilienname().equals(eidData.getFamilyName())) {
- findMismatch = true;
- builder.familyName(eidData.getFamilyName());
-
- }
-
- if (!getTextualBirthday(person.getGeburtsdatum()).equals(eidData.getDateOfBirth())) {
- findMismatch = true;
- builder.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();
- return findMismatch ? builder.build() : null;
}
private Aendern generateMdsChangeRequest(Person ernpPersonToKitt, SimpleEidasData mdsToUpdate) {
@@ -771,8 +771,10 @@ public class ErnpRestClient implements IErnpClient {
private HttpMessageConverter> buildCustomJacksonObjectMapper() {
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
- converter.getObjectMapper()
- .setSerializationInclusion(Include.NON_NULL);
+ converter.getObjectMapper().setSerializationInclusion(Include.NON_NULL);
+
+ converter.getObjectMapper().registerModule(new JavaTimeModule());
+ converter.getObjectMapper().configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return converter;
}
@@ -793,9 +795,9 @@ public class ErnpRestClient implements IErnpClient {
// TODO: opimize errorHandling based on response info's from real ERnP
List serverId = response.getHeaders().getOrEmpty(ERNP_RESPONSE_HEADER_SERVER_ID);
- log.warn("Receive http-error: {} from ERnP with serverTransactionId",
+ 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());
}
--
cgit v1.2.3
From 0020b5d6084501b6ee6b6b07fdc40ab47dc30dc7 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Thu, 3 Mar 2022 11:43:59 +0100
Subject: test(ernp): add all ERnP integration tests into test that operates in
real test ERnP
---
.../eidas/specific/modules/auth/eidas/v2/dao/SimpleEidasData.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 f9301505..094b2a9f 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
@@ -32,7 +32,7 @@ import lombok.Builder;
import lombok.Data;
@Data
-@Builder
+@Builder(toBuilder=true)
public class SimpleEidasData implements Serializable {
private static final long serialVersionUID = 2848914124372968418L;
--
cgit v1.2.3
From 7b2c31e14aa5f4823d970ec6ebd3e134a280f442 Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Thu, 3 Mar 2022 15:06:28 +0100
Subject: fix(ernp): fix some problems in ERnP client that we found during
tests
---
.../auth/eidas/v2/clients/ernp/ErnpRestClient.java | 78 +++++++++++-----------
1 file changed, 38 insertions(+), 40 deletions(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
index 66fec9dc..4c4e3d87 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java
@@ -232,7 +232,7 @@ public class ErnpRestClient implements IErnpClient {
generic.getClientRequestTime(), generic.getClientRequestId(), personSuchen);
// parse ZMR response
- return processErnpResponse(resp, citizenCountryCode, false, countrySearchMsg);
+ return processErnpResponse(resp, citizenCountryCode, true, countrySearchMsg);
} catch (RestClientException e) {
log.warn(LOGMSG_ERNP_ERROR, countrySearchMsg, e.getMessage());
@@ -289,31 +289,41 @@ public class ErnpRestClient implements IErnpClient {
@Override
public ErnpRegisterResult add(SimpleEidasData eidData) throws EidasSAuthenticationException {
- // 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())));
+ 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
@@ -629,21 +639,9 @@ public class ErnpRestClient implements IErnpClient {
Personendaten person = new Personendaten();
person.setEntityId(ernpPersonToKitt.getPersonendaten().getEntityId());
el.setPersonendaten(person);
-
- if (StringUtils.isNotEmpty(mdsToUpdate.getFamilyName())) {
- person.setFamilienname(mdsToUpdate.getFamilyName());
-
- }
-
- if (StringUtils.isNotEmpty(mdsToUpdate.getGivenName())) {
- person.setVorname(mdsToUpdate.getGivenName());
-
- }
-
- if (StringUtils.isNotEmpty(mdsToUpdate.getDateOfBirth())) {
- person.setGeburtsdatum(buildErnpBirthday(mdsToUpdate.getDateOfBirth()));
-
- }
+ person.setFamilienname(mdsToUpdate.getFamilyName());
+ person.setVorname(mdsToUpdate.getGivenName());
+ person.setGeburtsdatum(buildErnpBirthday(mdsToUpdate.getDateOfBirth()));
return el;
}
--
cgit v1.2.3
From c3bba97c9093eca911f6edd9cbb9742d5f32583c Mon Sep 17 00:00:00 2001
From: Thomas <>
Date: Thu, 3 Mar 2022 15:40:39 +0100
Subject: fix(core): solve code-style issue
---
.../eidas/specific/modules/auth/eidas/v2/dao/SimpleEidasData.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus')
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 094b2a9f..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
@@ -32,7 +32,7 @@ import lombok.Builder;
import lombok.Data;
@Data
-@Builder(toBuilder=true)
+@Builder(toBuilder = true)
public class SimpleEidasData implements Serializable {
private static final long serialVersionUID = 2848914124372968418L;
--
cgit v1.2.3