aboutsummaryrefslogtreecommitdiff
path: root/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/controller/AdresssucheController.java
diff options
context:
space:
mode:
Diffstat (limited to 'modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/controller/AdresssucheController.java')
-rw-r--r--modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/controller/AdresssucheController.java269
1 files changed, 269 insertions, 0 deletions
diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/controller/AdresssucheController.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/controller/AdresssucheController.java
new file mode 100644
index 00000000..9a42af04
--- /dev/null
+++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/controller/AdresssucheController.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.controller;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.CompareToBuilder;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import at.asitplus.eidas.specific.core.MsEidasNodeConstants;
+import at.asitplus.eidas.specific.core.gui.StaticGuiBuilderConfiguration;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrAddressSoapClient;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
+import at.gv.bmi.namespace.zmr_su.zrm._20040201_.address.Adressdaten;
+import at.gv.e_government.reference.namespace.persondata.de._20040201.PostAdresseTyp;
+import at.gv.e_government.reference.namespace.persondata.de._20040201.ZustelladresseTyp;
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+import at.gv.egiz.eaaf.core.api.gui.ISpringMvcGuiFormBuilder;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.GuiBuildException;
+import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Default process-engine signaling controller.
+ *
+ * @author tlenz
+ */
+@Controller
+@Slf4j
+public class AdresssucheController {
+
+ public static final String PARAM_POSTLEITZAHL = "postleitzahl";
+ public static final String PARAM_MUNIPICALITY = "municipality";
+ public static final String PARAM_VILLAGE = "village";
+ public static final String PARAM_STREET = "street";
+ public static final String PARAM_NUMBER = "number";
+
+ @Autowired
+ private ISpringMvcGuiFormBuilder guiBuilder;
+
+ @Autowired
+ private IConfiguration basicConfig;
+
+ @Autowired
+ private ResourceLoader resourceLoader;
+
+ @Autowired
+ private ZmrAddressSoapClient client;
+
+ @Autowired
+ private IPendingRequestIdGenerationStrategy pendingReqGeneration;
+
+ /**
+ * Show the "residency.html" directly.
+ * TODO Remove this after testing.
+ */
+ @RequestMapping(value = {"/test"}, method = {RequestMethod.GET})
+ public void test(HttpServletRequest request, HttpServletResponse response) throws GuiBuildException, EaafException {
+ final StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration(
+ basicConfig,
+ "http://localhost:8080/ms_connector/",
+ basicConfig.getBasicConfiguration(//TODO
+ MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_RESIDENCY,
+ MsEidasNodeConstants.TEMPLATE_HTML_RESIDENCY),
+ MsEidasNodeConstants.ENDPOINT_RESIDENCY_INPUT,
+ resourceLoader);
+ config.putCustomParameter(null, "pendingid", pendingReqGeneration.generateExternalPendingRequestId());
+ guiBuilder.build(request, response, config, "Query Austrian residency");
+ }
+
+ /**
+ * Show the "other_login_method.html" directly.
+ * TODO Remove this after testing.
+ */
+ @RequestMapping(value = {"/olm"}, method = {RequestMethod.GET})
+ public void otherloginmethod(HttpServletRequest request, HttpServletResponse response) throws GuiBuildException,
+ EaafException {
+ final StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration(
+ basicConfig,
+ "http://localhost:8080/ms_connector/",
+ basicConfig.getBasicConfiguration(//TODO
+ MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_OTHER_LOGIN_METHOD_SELECTION,
+ MsEidasNodeConstants.TEMPLATE_HTML_OTHERLOGINMETHODS),
+ MsEidasNodeConstants.ENDPOINT_OTHER_LOGIN_METHOD_SELECTION,
+ resourceLoader);
+ config.putCustomParameter(null, "pendingid", pendingReqGeneration.generateExternalPendingRequestId());
+ guiBuilder.build(request, response, config, "Other Login Method");
+ }
+
+ /**
+ * Show the "country_selection.html" directly.
+ * TODO Remove this after testing.
+ */
+ @RequestMapping(value = {"/country"}, method = {RequestMethod.GET})
+ public void countryselection(HttpServletRequest request, HttpServletResponse response) throws GuiBuildException,
+ EaafException {
+ final StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration(
+ basicConfig,
+ "http://localhost:8080/ms_connector/",
+ basicConfig.getBasicConfiguration(//TODO
+ MsEidasNodeConstants.PROP_CONFIG_WEBCONTENT_TEMPLATES_CCSELECTION,
+ MsEidasNodeConstants.TEMPLATE_HTML_COUNTRYSELECTION),
+ MsEidasNodeConstants.ENDPOINT_COUNTRYSELECTION,
+ resourceLoader);
+ config.putCustomParameter(null, "pendingid", pendingReqGeneration.generateExternalPendingRequestId());
+ guiBuilder.build(request, response, config, "Country Selection");
+ }
+
+ /**
+ * Performs search for addresses in ZMR.
+ */
+ @RequestMapping(value = {"/residency/search"}, method = {RequestMethod.POST})
+ public ResponseEntity<AdresssucheResult> search(
+ @RequestParam(PARAM_POSTLEITZAHL) String postleitzahl,
+ @RequestParam(PARAM_MUNIPICALITY) String municipality,
+ @RequestParam(PARAM_VILLAGE) String village,
+ @RequestParam(PARAM_STREET) String street,
+ @RequestParam(PARAM_NUMBER) String number,
+ @RequestParam(EaafConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID) String pendingId) {
+ log.info("Search with '{}', '{}', '{}', '{}', '{}'",
+ postleitzahl.replaceAll("[\r\n]", ""),
+ municipality.replaceAll("[\r\n]", ""),
+ village.replaceAll("[\r\n]", ""),
+ street.replaceAll("[\r\n]", ""),
+ number.replaceAll("[\r\n]", ""));
+ try {
+ pendingReqGeneration.validateAndGetPendingRequestId(pendingId);
+
+ } catch (PendingReqIdValidationException e) {
+ log.warn("Search with pendingId '{}' is not valid", pendingId.replaceAll("[\r\n]", ""));
+ return ResponseEntity.badRequest().build();
+
+ }
+
+ try {
+ Adressdaten searchInput = buildSearchInput(postleitzahl, municipality, village, street, number);
+ ZmrAddressSoapClient.AddressInfo searchOutput = client.searchAddress(searchInput);
+ AdresssucheResult output = buildResponse(searchOutput);
+ return ResponseEntity.ok(output);
+
+ } catch (EidasSAuthenticationException e) {
+ log.warn("Search failed", e);
+ return ResponseEntity.badRequest().build();
+
+ }
+ }
+
+ private AdresssucheResult buildResponse(ZmrAddressSoapClient.AddressInfo searchOutput) {
+ if (searchOutput.getPersonResult().isEmpty()) {
+ log.warn("No result from ZMR");
+ return new AdresssucheResult(Collections.emptyList(), 0);
+
+ }
+
+ log.info("Result level is {}", searchOutput.getLevel());
+ Set<AdresssucheOutput> result = searchOutput.getPersonResult().stream()
+ .map(Adressdaten::getPostAdresse)
+ .map(it -> new AdresssucheOutput(it.getPostleitzahl(), it.getGemeinde(), it.getOrtschaft(),
+ it.getZustelladresse().getStrassenname(), it.getZustelladresse().getOrientierungsnummer()))
+ .collect(Collectors.toSet());
+ // TODO Add configuration option for the limit of 30
+ List<AdresssucheOutput> sorted = result.stream().sorted().limit(30).collect(Collectors.toList());
+ return new AdresssucheResult(sorted, result.size());
+
+ }
+
+ private Adressdaten buildSearchInput(String postleitzahl,
+ String municipality,
+ String village,
+ String street,
+ String number) {
+ PostAdresseTyp postAdresse = new PostAdresseTyp();
+ if (StringUtils.isNotBlank(postleitzahl)) {
+ postAdresse.setPostleitzahl(postleitzahl);
+ }
+ if (StringUtils.isNotBlank(municipality)) {
+ postAdresse.setGemeinde(municipality);
+ }
+ if (StringUtils.isNotBlank(village)) {
+ postAdresse.setOrtschaft(village);
+ }
+ if (StringUtils.isNotBlank(street) || StringUtils.isNotBlank(number)) {
+ ZustelladresseTyp zustelladresse = new ZustelladresseTyp();
+ if (StringUtils.isNotBlank(street)) {
+ zustelladresse.setStrassenname(street);
+ }
+ if (StringUtils.isNotBlank(number)) {
+ zustelladresse.setOrientierungsnummer(number);
+ }
+ postAdresse.setZustelladresse(zustelladresse);
+ }
+ Adressdaten searchInput = new Adressdaten();
+ searchInput.setPostAdresse(postAdresse);
+ return searchInput;
+
+ }
+
+ @Data
+ @AllArgsConstructor
+ public static class AdresssucheResult {
+ private final Collection<AdresssucheOutput> results;
+ private final int resultCount;
+ }
+
+ @Data
+ @AllArgsConstructor
+ @Builder
+ public static class AdresssucheOutput implements Comparable<AdresssucheOutput> {
+ private final String postleitzahl;
+ private final String municipality;
+ private final String village;
+ private final String street;
+ private final String number;
+
+ @Override
+ public int compareTo(@NotNull AdresssucheOutput o) {
+ return new CompareToBuilder()
+ .append(this.postleitzahl, o.postleitzahl)
+ .append(this.municipality, o.municipality)
+ .append(this.village, o.village)
+ .append(this.street, o.street)
+ .append(this.number, o.number)
+ .toComparison();
+ }
+ }
+
+}