aboutsummaryrefslogtreecommitdiff
path: root/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/RegisterSearchService.java
diff options
context:
space:
mode:
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/RegisterSearchService.java')
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/service/RegisterSearchService.java328
1 files changed, 258 insertions, 70 deletions
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 6b524e36..166ffafb 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
@@ -1,18 +1,28 @@
package at.asitplus.eidas.specific.modules.auth.eidas.v2.service;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.MergedRegisterSearchResult;
+import java.math.BigInteger;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import org.jetbrains.annotations.Nullable;
+import org.springframework.stereotype.Service;
+
+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.zmr.IZmrClient;
-import at.gv.egiz.eaaf.core.api.IRequest;
-import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.ZmrCommunicationException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.CountrySpecificDetailSearchProcessor;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-import java.util.Collections;
-import java.util.List;
@Slf4j
@Service("registerSearchService")
@@ -21,99 +31,277 @@ public class RegisterSearchService {
private final IZmrClient zmrClient;
private final IErnpClient ernpClient;
- public RegisterSearchService(IZmrClient zmrClient, IErnpClient ernpClient) {
+ private final List<CountrySpecificDetailSearchProcessor> handlers;
+
+ /**
+ * Service that combines ZMR and ERnP register search operations.
+ *
+ * @param handlers Available country-specific search processors
+ * @param zmrClient ZMR client
+ * @param ernpClient ERnP client
+ */
+ public RegisterSearchService(List<CountrySpecificDetailSearchProcessor> handlers, IZmrClient zmrClient,
+ IErnpClient ernpClient) {
this.zmrClient = zmrClient;
this.ernpClient = ernpClient;
+ this.handlers = handlers;
+ log.info("Init with #{} search services for country-specific details", handlers.size());
+
}
/**
- * Automatic process to fix the register entries.
+ * Search with Person Identifier (eIDAS Pseudonym) in ZMR and ERnP.
*
- * @param initialSearchResult Result of initial register search
- * @param specificSearchResult Result of last register search
- * @param eidasData Received eidas data
- * @param pendingReq Pending request
- * @return The bpk
- * @throws TaskExecutionException if an error occurs during the register update
+ * @param eidasData Received eIDAS data
+ * @throws WorkflowException In case of a register interaction error
*/
- public String step7aKittProcess(MergedRegisterSearchResult initialSearchResult,
- MergedRegisterSearchResult specificSearchResult,
- SimpleEidasData eidasData,
- IRequest pendingReq) throws TaskExecutionException {
- log.trace("Starting step7aKittProcess");
- // TODO verify with which data this method gets called
+ @Nonnull
+ public RegisterSearchResult searchWithPersonIdentifier(SimpleEidasData eidasData)
+ throws WorkflowException {
try {
- if (initialSearchResult.getResultCount() != 0) {
- throw new WorkflowException("initialSearchResult.getResultCount() != 0");
- }
- if (specificSearchResult.getResultCount() != 1) {
- throw new WorkflowException("specificSearchResult.getResultCount() != 1");
- }
- if (specificSearchResult.getResultsZmr().size() == 1) {
- zmrClient.update(specificSearchResult.getResultsZmr().get(0), eidasData);
- }
- if (specificSearchResult.getResultsErnp().size() == 1) {
- ernpClient.update(specificSearchResult.getResultsErnp().get(0), eidasData);
- }
- return specificSearchResult.getBpk();
- } catch (WorkflowException e) {
- throw new TaskExecutionException(pendingReq, "Step7a failed.", e);
+ final ZmrRegisterResult resultsZmr = zmrClient.searchWithPersonIdentifier(
+ null, eidasData.getPersonalIdentifier());
+ final List<RegisterResult> resultsErnp = ernpClient.searchWithPersonIdentifier(
+ eidasData.getPersonalIdentifier());
+
+ return new RegisterSearchResult(new RegisterOperationStatus(resultsZmr.getProcessId()),
+ resultsZmr.getPersonResult(), resultsErnp);
+
+ } catch (final EidasSAuthenticationException e) {
+ throw new WorkflowException("searchWithPersonalIdentifier", e.getMessage(),
+ !(e instanceof ZmrCommunicationException), e);
+
}
}
/**
* Search with MDS (Given Name, Family Name, Date of Birth) in ZMR and ERnP.
+ *
+ * @param operationStatus Current register-operation status that contains processing informations
+ * @param eidasData Received eIDAS data
+ * @throws WorkflowException In case of a register interaction error
*/
- public MergedRegisterSearchResult searchWithMds(SimpleEidasData eidasData) {
- List<RegisterResult> resultsZmr =
- zmrClient.searchWithMds(eidasData.getGivenName(), eidasData.getFamilyName(), eidasData.getDateOfBirth());
- List<RegisterResult> resultsErnp =
- ernpClient.searchWithMds(eidasData.getGivenName(), eidasData.getFamilyName(), eidasData.getDateOfBirth());
- return new MergedRegisterSearchResult(resultsZmr, resultsErnp);
+ @Nonnull
+ public RegisterSearchResult searchWithMds(RegisterOperationStatus operationStatus, SimpleEidasData eidasData)
+ throws WorkflowException {
+ try {
+ final ZmrRegisterResult resultsZmr =
+ zmrClient.searchWithMds(operationStatus.getZmrProcessId(), eidasData.getGivenName(),
+ eidasData.getFamilyName(), eidasData.getDateOfBirth(), eidasData.getCitizenCountryCode());
+
+ final List<RegisterResult> resultsErnp =
+ ernpClient.searchWithMds(eidasData.getGivenName(), eidasData.getFamilyName(), eidasData
+ .getDateOfBirth());
+
+ return new RegisterSearchResult(new RegisterOperationStatus(resultsZmr.getProcessId()),
+ resultsZmr.getPersonResult(), resultsErnp);
+
+ } catch (final EidasSAuthenticationException e) {
+ throw new WorkflowException("searchWithMDSOnly", e.getMessage(),
+ !(e instanceof ZmrCommunicationException), e);
+
+ }
}
/**
- * Search with Person Identifier (eIDAS Pseudonym) in ZMR and ERnP.
+ * Search with country-specific parameters based on information from available
+ * {@link CountrySpecificDetailSearchProcessor} implementations.
+ *
+ * @param operationStatus Current register-operation status that contains processing informations
+ * @param eidasData Receive eIDAS eID information
+ * @return Results from ZMR or ERnP search
+ * @throws WorkflowException In case of a register interaction error
*/
- public MergedRegisterSearchResult searchWithPersonIdentifier(SimpleEidasData eidasData) {
- List<RegisterResult> resultsZmr = zmrClient.searchWithPersonIdentifier(eidasData.getPseudonym());
- List<RegisterResult> resultsErnp = ernpClient.searchWithPersonIdentifier(eidasData.getPseudonym());
- return new MergedRegisterSearchResult(resultsZmr, resultsErnp);
+ @Nonnull
+ public RegisterSearchResult searchWithCountrySpecifics(RegisterOperationStatus operationStatus,
+ SimpleEidasData eidasData) throws WorkflowException {
+ try {
+ @Nullable
+ final CountrySpecificDetailSearchProcessor ccSpecificProcessor = findSpecificProcessor(eidasData);
+ if (ccSpecificProcessor != null) {
+ log.debug("Selecting country-specific search processor: {}", ccSpecificProcessor.getName());
+ final ZmrRegisterResult resultsZmr =
+ zmrClient.searchCountrySpecific(operationStatus.getZmrProcessId(),
+ ccSpecificProcessor.generateSearchRequest(eidasData),
+ eidasData.getCitizenCountryCode());
+
+ // TODO: add search procesfor for ERnP searching
+ return new RegisterSearchResult(operationStatus, resultsZmr.getPersonResult(), Collections.emptyList());
+
+ } else {
+ return new RegisterSearchResult(operationStatus, Collections.emptyList(), Collections.emptyList());
+
+ }
+
+ } catch (final EidasSAuthenticationException e) {
+ throw new WorkflowException("searchWithCountrySpecifics", e.getMessage(),
+ !(e instanceof ZmrCommunicationException), e);
+
+ }
}
/**
- * Search with Tax Number in ZMR and ERnP.
+ * Search with BPK-ZP in BMR and ERnP.
*/
- public MergedRegisterSearchResult searchItSpecific(SimpleEidasData eidasData) {
- List<RegisterResult> resultsZmr = zmrClient.searchItSpecific(eidasData.getTaxNumber());
- List<RegisterResult> resultsErnb = ernpClient.searchItSpecific(eidasData.getTaxNumber());
- return new MergedRegisterSearchResult(resultsZmr, resultsErnb);
+ public RegisterSearchResult searchWithBpkZp(RegisterOperationStatus operationStatus, String bpkZp) {
+ final ZmrRegisterResult resultsZmr = zmrClient.searchWithBpkZp(
+ operationStatus.getZmrProcessId(), bpkZp);
+ final List<RegisterResult> resultsErnp = ernpClient.searchWithBpkZp(bpkZp);
+ return new RegisterSearchResult(operationStatus, resultsZmr.getPersonResult(), resultsErnp);
+
}
/**
- * Search with Given Name, Family Name, Date of Birth, Place of Birth and Birth Name in ZMR and ERnP.
+ * 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
+ * @return Results from ZMR or ERnP search
*/
- public MergedRegisterSearchResult searchDeSpecific(SimpleEidasData eidasData) {
- List<RegisterResult> resultsZmr =
- zmrClient.searchDeSpecific(eidasData.getGivenName(), eidasData.getFamilyName(), eidasData.getDateOfBirth(),
- eidasData.getPlaceOfBirth(), eidasData.getBirthName());
- List<RegisterResult> resultsErnb =
- ernpClient.searchDeSpecific(eidasData.getGivenName(), eidasData.getFamilyName(), eidasData.getDateOfBirth(),
- eidasData.getPlaceOfBirth(), eidasData.getBirthName());
- return new MergedRegisterSearchResult(resultsZmr, resultsErnb);
+ public RegisterSearchResult 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 new RegisterSearchResult(operationStatus, resultsZmr.getPersonResult(), Collections.emptyList());
+
}
/**
- * Search with BPK-ZP in BMR and ERnP.
+ * Automatic process to fix the register entries.
+ *
+ * @param specificSearchResult Result of last register search
+ * @param eidasData Received eidas data
+ */
+ public void step7aKittProcess(RegisterSearchResult specificSearchResult,
+ SimpleEidasData eidasData) throws WorkflowException {
+ log.trace("Starting step7aKittProcess");
+ // TODO verify with which data this method gets called
+ if (specificSearchResult.getResultCount() != 1) {
+ throw new WorkflowException("step7aKittProcess", "getResultCount() != 1");
+
+ }
+
+ if (specificSearchResult.getResultsZmr().size() == 1) {
+ zmrClient.update(specificSearchResult.getOperationStatus().getZmrProcessId(),
+
+ specificSearchResult.getResultsZmr().get(0), eidasData);
+ }
+
+ if (specificSearchResult.getResultsErnp().size() == 1) {
+ ernpClient.update(specificSearchResult.getResultsErnp().get(0), eidasData);
+
+ }
+
+ }
+
+ @Nullable
+ private CountrySpecificDetailSearchProcessor findSpecificProcessor(SimpleEidasData eidasData) {
+ final String citizenCountry = eidasData.getCitizenCountryCode();
+ for (final CountrySpecificDetailSearchProcessor processor : handlers) {
+ if (processor.canHandle(citizenCountry, eidasData)) {
+ log.debug("Found suitable search handler for {} by using: {}", citizenCountry, processor.getName());
+ return processor;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Register releated information that are needed for any request.
+ *
+ * @author tlenz
+ *
*/
- public MergedRegisterSearchResult searchWithBpkZp(String bpkZp) {
- List<RegisterResult> resultsZmr = zmrClient.searchWithBpkZp(bpkZp);
- List<RegisterResult> resultsErnp = ernpClient.searchWithBpkZp(bpkZp);
- return new MergedRegisterSearchResult(resultsZmr, resultsErnp);
+ @AllArgsConstructor
+ @Getter
+ public static class RegisterOperationStatus {
+
+ /**
+ * ZMR internal processId that is required for any further request in the same process.
+ */
+ private BigInteger zmrProcessId;
+
+
}
+
+ /**
+ * Response container for {@link RegisterSearchService}.
+ *
+ * @author tlenz
+ *
+ */
+ @Getter
+ @RequiredArgsConstructor
+ public static class RegisterSearchResult {
+
+ /**
+ * Mark the register result finished.
+ */
+ @Setter
+ private boolean matchingFinished = false;
+
+ /**
+ * Operation status for this result.
+ */
+ private final RegisterOperationStatus operationStatus;
+
+ /**
+ * Current ZMR search result.
+ */
+ private final List<RegisterResult> resultsZmr;
+
+ /**
+ * Current ERnP search result.
+ */
+ private final List<RegisterResult> resultsErnp;
+
+
+ /**
+ * Get sum of ZMR and ERnP results.
+ *
+ * @return number of results
+ */
+ public int getResultCount() {
+ return resultsZmr.size() + resultsErnp.size();
+ }
+
+ /**
+ * Verifies that there is only one match and returns the bpk.
+ *
+ * @return bpk bpk of the match
+ * @throws WorkflowException if multiple results have been found or matching is not marked as finished
+ */
+ public String getBpk() throws WorkflowException {
+ if (getResultCount() != 1 || !matchingFinished) {
+ throw new WorkflowException("readRegisterResults",
+ matchingFinished ? "getResultCount() != 1" : "matching prozess not finished yet");
+
+ }
+ return getResult().getBpk();
+ }
- public MergedRegisterSearchResult searchWithResidence(String zipcode, String city, String street) {
- List<RegisterResult> resultsZmr = zmrClient.searchWithResidenceData(zipcode, city, street);
- return new MergedRegisterSearchResult(resultsZmr, Collections.emptyList());
+ /**
+ * Returns the results, if there is exactly one, throws exception otherwise.
+ *
+ * @return The result
+ * @throws WorkflowException Results does not contain exactly one result
+ */
+ public RegisterResult getResult() throws WorkflowException {
+ if (getResultCount() != 1) {
+ throw new WorkflowException("readRegisterResults", "getResultCount() != 1");
+ }
+ if (resultsZmr.size() == 1) {
+ return resultsZmr.get(0);
+
+ } else {
+ return resultsErnp.get(0);
+
+ }
+ }
+
}
+
}