From 594114759ea7df52a2a21db91e20272f3aa5a3c9 Mon Sep 17 00:00:00 2001 From: Christian Kollmann Date: Mon, 12 Jul 2021 14:04:05 +0200 Subject: Implement stub for step 7b in matching process --- .../eidas/v2/service/RegisterSearchService.java | 176 ++++++++++++--------- .../auth/eidas/v2/tasks/AlternativeSearchTask.java | 32 ++-- 2 files changed, 119 insertions(+), 89 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 b5e83490..fc26b214 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,15 +1,5 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.service; -import java.math.BigInteger; -import java.util.Arrays; -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; @@ -23,6 +13,14 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.Nullable; +import org.springframework.stereotype.Service; + +import javax.annotation.Nonnull; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; @Slf4j @Service("registerSearchService") @@ -32,16 +30,16 @@ public class RegisterSearchService { private final IErnpClient ernpClient; private final List handlers; - + /** * Service that combines ZMR and ERnP register search operations. - * - * @param handlers Available country-specific search processors - * @param zmrClient ZMR client + * + * @param handlers Available country-specific search processors + * @param zmrClient ZMR client * @param ernpClient ERnP client */ public RegisterSearchService(List handlers, IZmrClient zmrClient, - IErnpClient ernpClient) { + IErnpClient ernpClient) { this.zmrClient = zmrClient; this.ernpClient = ernpClient; this.handlers = handlers; @@ -52,7 +50,7 @@ public class RegisterSearchService { /** * Search with Person Identifier (eIDAS Pseudonym) in ZMR and ERnP. * - * @param eidasData Received eIDAS data + * @param eidasData Received eIDAS data * @throws WorkflowException In case of a register interaction error */ @Nonnull @@ -60,15 +58,15 @@ public class RegisterSearchService { throws WorkflowException { try { final ZmrRegisterResult resultsZmr = zmrClient.searchWithPersonIdentifier( - null, eidasData.getPseudonym(), eidasData.getCitizenCountryCode()); + null, eidasData.getPseudonym(), eidasData.getCitizenCountryCode()); final List resultsErnp = ernpClient.searchWithPersonIdentifier( eidasData.getPersonalIdentifier()); - - return new RegisterStatusResults(new RegisterOperationStatus(resultsZmr.getProcessId()), + + return new RegisterStatusResults(new RegisterOperationStatus(resultsZmr.getProcessId()), resultsZmr.getPersonResult(), resultsErnp); } catch (final EidasSAuthenticationException e) { - throw new WorkflowException("searchWithPersonalIdentifier", e.getMessage(), + throw new WorkflowException("searchWithPersonalIdentifier", e.getMessage(), !(e instanceof ZmrCommunicationException), e); } @@ -86,18 +84,18 @@ public class RegisterSearchService { throws WorkflowException { try { final ZmrRegisterResult resultsZmr = - zmrClient.searchWithMds(operationStatus.getZmrProcessId(), eidasData.getGivenName(), + zmrClient.searchWithMds(operationStatus.getZmrProcessId(), eidasData.getGivenName(), eidasData.getFamilyName(), eidasData.getDateOfBirth(), eidasData.getCitizenCountryCode()); - + final List resultsErnp = ernpClient.searchWithMds(eidasData.getGivenName(), eidasData.getFamilyName(), eidasData .getDateOfBirth()); - - return new RegisterStatusResults(new RegisterOperationStatus(resultsZmr.getProcessId()), + + return new RegisterStatusResults(new RegisterOperationStatus(resultsZmr.getProcessId()), resultsZmr.getPersonResult(), resultsErnp); } catch (final EidasSAuthenticationException e) { - throw new WorkflowException("searchWithMDSOnly", e.getMessage(), + throw new WorkflowException("searchWithMDSOnly", e.getMessage(), !(e instanceof ZmrCommunicationException), e); } @@ -106,22 +104,21 @@ public class RegisterSearchService { /** * 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 + * @param eidasData Receive eIDAS eID information * @return Results from ZMR or ERnP search * @throws WorkflowException In case of a register interaction error */ @Nonnull - public RegisterStatusResults searchWithCountrySpecifics(RegisterOperationStatus operationStatus, - SimpleEidasData eidasData) throws WorkflowException { + public RegisterStatusResults searchWithCountrySpecifics(RegisterOperationStatus operationStatus, + SimpleEidasData eidasData) throws WorkflowException { try { - @Nullable - final CountrySpecificDetailSearchProcessor ccSpecificProcessor = findSpecificProcessor(eidasData); + @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(), + zmrClient.searchCountrySpecific(operationStatus.getZmrProcessId(), ccSpecificProcessor.generateSearchRequest(eidasData), eidasData.getCitizenCountryCode()); @@ -134,7 +131,7 @@ public class RegisterSearchService { } } catch (final EidasSAuthenticationException e) { - throw new WorkflowException("searchWithCountrySpecifics", e.getMessage(), + throw new WorkflowException("searchWithCountrySpecifics", e.getMessage(), !(e instanceof ZmrCommunicationException), e); } @@ -142,17 +139,17 @@ 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 zipcode Provided Zipcode + * @param city Provided City + * @param street Provided street * @return Results from ZMR or ERnP search */ - public RegisterStatusResults searchWithResidence(RegisterOperationStatus operationStatus, SimpleEidasData eidasData, - String zipcode, String city, String street) { + public RegisterStatusResults searchWithResidence(RegisterOperationStatus operationStatus, SimpleEidasData eidasData, + String zipcode, String city, String street) { final ZmrRegisterResult resultsZmr = zmrClient.searchWithResidenceData( - operationStatus.getZmrProcessId(), eidasData.getGivenName(), eidasData.getFamilyName(), + operationStatus.getZmrProcessId(), eidasData.getGivenName(), eidasData.getFamilyName(), eidasData.getDateOfBirth(), zipcode, city, street); return new RegisterStatusResults(operationStatus, resultsZmr.getPersonResult(), Collections.emptyList()); @@ -160,41 +157,71 @@ public class RegisterSearchService { /** * Automatic process to fix the register entries. + * Called when the initial eIDAS authn leads to a match in a register. * * @param specificSearchResult Result of last register search - * @param eidasData Received eidas data - * @return + * @param initialEidasData Received eidas data from initial authn + * @return */ public RegisterStatusResults step7aKittProcess(RegisterStatusResults specificSearchResult, - SimpleEidasData eidasData) throws WorkflowException { + SimpleEidasData initialEidasData) 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"); - } try { if (specificSearchResult.getResultsZmr().size() == 1) { final ZmrRegisterResult resultsZmr = zmrClient.update( - specificSearchResult.getOperationStatus().getZmrProcessId(), - specificSearchResult.getResultsZmr().get(0), eidasData); - return new RegisterStatusResults(specificSearchResult.getOperationStatus(), + specificSearchResult.getOperationStatus().getZmrProcessId(), + specificSearchResult.getResultsZmr().get(0), initialEidasData); + return new RegisterStatusResults(specificSearchResult.getOperationStatus(), resultsZmr.getPersonResult(), Collections.emptyList()); - } else { - return new RegisterStatusResults(specificSearchResult.getOperationStatus(), Collections.emptyList(), - Arrays.asList(ernpClient.update(specificSearchResult.getResultsErnp().get(0), eidasData))); - + return new RegisterStatusResults(specificSearchResult.getOperationStatus(), Collections.emptyList(), + Arrays.asList(ernpClient.update(specificSearchResult.getResultsErnp().get(0), initialEidasData))); } - } catch (final EidasSAuthenticationException e) { - throw new WorkflowException("kittMatchedIdentitiess", e.getMessage(), + throw new WorkflowException("kittMatchedIdentitiess", e.getMessage(), !(e instanceof ZmrCommunicationException), e); + } + } + /** + * Automatic process to fix the register entries. + * Called when the alternative eIDAS authn leads to a match in a register. + * + * @param specificSearchResult Result of last register search + * @param initialEidasData Received eidas data from initial authentication + * @param altEidasData Received eidas data from alternative authentication + * @return + */ + public RegisterStatusResults step7bKittProcess(RegisterStatusResults specificSearchResult, + SimpleEidasData initialEidasData, SimpleEidasData altEidasData) + throws WorkflowException { + log.trace("Starting step7bKittProcess"); + // TODO What to do with the initialEidasData? + // TODO verify with which data this method gets called + if (specificSearchResult.getResultCount() != 1) { + throw new WorkflowException("step7bKittProcess", "getResultCount() != 1"); + } + try { + if (specificSearchResult.getResultsZmr().size() == 1) { + final ZmrRegisterResult resultsZmr = zmrClient.update( + specificSearchResult.getOperationStatus().getZmrProcessId(), + specificSearchResult.getResultsZmr().get(0), altEidasData); + return new RegisterStatusResults(specificSearchResult.getOperationStatus(), + resultsZmr.getPersonResult(), Collections.emptyList()); + } else { + return new RegisterStatusResults(specificSearchResult.getOperationStatus(), Collections.emptyList(), + Arrays.asList(ernpClient.update(specificSearchResult.getResultsErnp().get(0), altEidasData))); + } + } catch (final EidasSAuthenticationException e) { + throw new WorkflowException("kittMatchedIdentitiess", e.getMessage(), + !(e instanceof ZmrCommunicationException), e); } - } - + @Nullable private CountrySpecificDetailSearchProcessor findSpecificProcessor(SimpleEidasData eidasData) { final String citizenCountry = eidasData.getCitizenCountryCode(); @@ -206,55 +233,52 @@ public class RegisterSearchService { } return null; } - + /** * Register releated information that are needed for any request. - * - * @author tlenz * + * @author tlenz */ @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} that holds a set of {@link RegisterResult}. - * - * @author tlenz * + * @author tlenz */ @Getter @RequiredArgsConstructor - public static class RegisterStatusResults { + public static class RegisterStatusResults { /** * Operation status for this result. */ private final RegisterOperationStatus operationStatus; - + /** * Current ZMR search result. */ private final List resultsZmr; - + /** * Current ERnP search result. */ private final List resultsErnp; - - + + /** * Get sum of ZMR and ERnP results. - * + * * @return number of results */ public int getResultCount() { @@ -270,7 +294,7 @@ public class RegisterSearchService { public String getBpk() throws WorkflowException { if (getResultCount() != 1) { throw new WorkflowException("readRegisterResults", "getResultCount() != 1"); - + } return getResult().getBpk(); } @@ -287,13 +311,13 @@ public class RegisterSearchService { } if (resultsZmr.size() == 1) { return resultsZmr.get(0); - + } else { return resultsErnp.get(0); - + } } - + } } 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 135eeec1..38a7076a 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 @@ -53,7 +53,8 @@ import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.TRANSIT * Searches registers (ERnP and ZMR) after alternative eIDAS authn, before adding person to SZR. * Input: *
    - *
  • {@link Constants#DATA_FULL_EIDAS_RESPONSE_ALTERNATIVE}
  • + *
  • {@link Constants#DATA_FULL_EIDAS_RESPONSE_ALTERNATIVE} data from the alternative eIDAS authn
  • + *
  • {@link Constants#DATA_SIMPLE_EIDAS} data from the initial eIDAS authn
  • *
* Output: *
    @@ -94,8 +95,10 @@ public class AlternativeSearchTask extends AbstractAuthServletTask { public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) throws TaskExecutionException { try { - final SimpleEidasData eidasData = convertEidasAttrToSimpleData(); - step11RegisterSearchWithPersonIdentifier(executionContext, eidasData); + final SimpleEidasData altEidasData = convertEidasAttrToSimpleData(); + final SimpleEidasData initialEidasData = MatchingTaskUtils.getInitialEidasData(pendingReq); + // TODO Verify that altEidasData and initialEidasData "match"? + step11RegisterSearchWithPersonIdentifier(executionContext, altEidasData, initialEidasData); } catch (WorkflowException e) { throw new TaskExecutionException(pendingReq, "Initial search failed", e); } catch (final Exception e) { @@ -105,15 +108,17 @@ public class AlternativeSearchTask extends AbstractAuthServletTask { } private void step11RegisterSearchWithPersonIdentifier( - ExecutionContext executionContext, SimpleEidasData eidasData) throws WorkflowException, EaafStorageException { + ExecutionContext executionContext, SimpleEidasData initialEidasData, SimpleEidasData altEidasData) + throws WorkflowException, EaafStorageException { try { log.trace("Starting step11RegisterSearchWithPersonIdentifier"); - RegisterStatusResults searchResult = registerSearchService.searchWithPersonIdentifier(eidasData); + RegisterStatusResults searchResult = registerSearchService.searchWithPersonIdentifier(altEidasData); int resultCount = searchResult.getResultCount(); if (resultCount == 0) { - step12CountrySpecificSearch(executionContext, searchResult.getOperationStatus(), eidasData); + step12CountrySpecificSearch(executionContext, searchResult.getOperationStatus(), initialEidasData, + altEidasData); } else if (resultCount == 1) { - foundMatchFinalizeTask(searchResult, eidasData); + foundMatchFinalizeTask(searchResult, altEidasData); } else { throw new WorkflowException("step11RegisterSearchWithPersonIdentifier", "More than one entry with unique personal-identifier", true); @@ -125,21 +130,22 @@ public class AlternativeSearchTask extends AbstractAuthServletTask { } } - private void step12CountrySpecificSearch( - ExecutionContext executionContext, RegisterOperationStatus registerOperationStatus, SimpleEidasData eidasData) + private void step12CountrySpecificSearch(ExecutionContext executionContext, + RegisterOperationStatus registerOperationStatus, + SimpleEidasData initialEidasData, + SimpleEidasData altEidasData) throws EaafStorageException, WorkflowException { log.trace("Starting 'step12CountrySpecificSearch' ... "); RegisterStatusResults searchResult = registerSearchService.searchWithCountrySpecifics( - registerOperationStatus, eidasData); + registerOperationStatus, altEidasData); if (searchResult.getResultCount() == 0) { 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); } else if (searchResult.getResultCount() == 1) { log.trace("'step12CountrySpecificSearch' finds a person. Forward to 'step7aKittProcess' step ... "); - // TODO is step 7b kitt different from step 7a? - registerSearchService.step7aKittProcess(searchResult, eidasData); - foundMatchFinalizeTask(searchResult, eidasData); + registerSearchService.step7bKittProcess(searchResult, initialEidasData, altEidasData); + foundMatchFinalizeTask(searchResult, altEidasData); } else { throw new WorkflowException("step12CountrySpecificSearch", "More than one entry with unique country-specific information", true); -- cgit v1.2.3