From feaa0a61527f0eb29ce33fb9e1aa1ddb0703779d Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Wed, 2 Feb 2022 18:01:06 +0100 Subject: feature(ernp): generate ERnP client from openAPI specification --- .../main/resources/wsdl/ernp_client/openapi.json | 1886 ++++++++++++++++++++ 1 file changed, 1886 insertions(+) create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/resources') diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json new file mode 100644 index 00000000..c8276f3a --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json @@ -0,0 +1,1886 @@ +{ + "openapi" : "3.0.1", + "info" : { + "title" : "ERNP", + "version" : "1.0.0" + }, + "servers" : [ { + "url" : "https://stportal.bmi.intra.gv.at/at.gv.bmi.erpsrv-p/srv/rest/", + "description" : "Produktion", + "variables" : { } + }, { + "url" : "https://stportal.bmi.intra.gv.at/at.gv.bmi.erpsrv-e/srv/rest/", + "description" : "Entwicklung", + "variables" : { } + }, { + "url" : "https://stportal.bmi.intra.gv.at/at.gv.bmi.erpsrv-t/srv/rest/", + "description" : "Interne Test", + "variables" : { } + }, { + "url" : "https://stportal.bmi.intra.gv.at/at.gv.bmi.erpsrv-a/srv/rest/", + "description" : "Externe Test", + "variables" : { } + }, { + "url" : "https://stportal.bmi.intra.gv.at/at.gv.bmi.erpsrv-b/srv/rest/", + "description" : "Businespartner Test", + "variables" : { } + }, { + "url" : "http://localhost:29200/at.gv.bmi.erpv01-d/srv/rest/", + "description" : "Lokal", + "variables" : { } + }, { + "url" : "http://localhost:29200/at.gv.bmi.erpv01-e/srv/rest/", + "description" : "Entwicklung (kein Portal)", + "variables" : { } + }, { + "url" : "http://localhost:29200/at.gv.bmi.erpv01-t/srv/rest/", + "description" : "Interne Test (kein Portal)", + "variables" : { } + }, { + "url" : "http://localhost:29200/at.gv.bmi.erpv01-a/srv/rest/", + "description" : "Externe Test (kein Portal)", + "variables" : { } + }, { + "url" : "http://localhost:29200/at.gv.bmi.erpv11-a/srv/rest/", + "description" : "Businespartner Test (kein Portal)", + "variables" : { } + } ], + "paths" : { + "/eidas/person/aendern" : { + "post" : { + "operationId" : "aendern", + "parameters" : [ { + "name" : "Client-Request-Time", + "in" : "header", + "description" : "Client-Requestzeit im ISO-8601 Format mit optionaler Zeitzone (zb '2016-10-27T16:36:08.993')", + "schema" : { + "type" : "string", + "format" : "date-time" + } + }, { + "name" : "Client-Request-Id", + "in" : "header", + "description" : "Client-Request ID (um Systemübergreifende Fehlersuche zu vereinfache)", + "schema" : { + "type" : "string" + } + }, { + "name" : "Client-Behkz", + "in" : "header", + "description" : "Client-Behördenkennzeichen", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "Client-Name", + "in" : "header", + "description" : "Client-Name bzw Applikationskürzel und Version des aufrufenden Systems (zb 'ZMR 3.4.5')", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/PersonAendern" + } + } + } + }, + "responses" : { + "default" : { + "description" : "Erfolgreicher Response hat Status 200 wenn Responsepayload vorhanden, sonst 204", + "content" : { + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/AendernResponse" + } + } + } + }, + "4XX" : { + "description" : "Client Fehler (kann vom Client behoben werden)", + "content" : { + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + } + } + }, + "5XX" : { + "description" : "Server Fehler (normalerweise nicht vom Client behebbar)", + "content" : { + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + } + } + } + } + } + }, + "/eidas/person/anlegen" : { + "post" : { + "operationId" : "anlegen", + "parameters" : [ { + "name" : "Client-Request-Time", + "in" : "header", + "description" : "Client-Requestzeit im ISO-8601 Format mit optionaler Zeitzone (zb '2016-10-27T16:36:08.993')", + "schema" : { + "type" : "string", + "format" : "date-time" + } + }, { + "name" : "Client-Request-Id", + "in" : "header", + "description" : "Client-Request ID (um Systemübergreifende Fehlersuche zu vereinfache)", + "schema" : { + "type" : "string" + } + }, { + "name" : "Client-Behkz", + "in" : "header", + "description" : "Client-Behördenkennzeichen", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "Client-Name", + "in" : "header", + "description" : "Client-Name bzw Applikationskürzel und Version des aufrufenden Systems (zb 'ZMR 3.4.5')", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/PersonAnlegen" + } + } + } + }, + "responses" : { + "default" : { + "description" : "Erfolgreicher Response hat Status 200 wenn Responsepayload vorhanden, sonst 204", + "content" : { + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/AnlegenResponse" + } + } + } + }, + "4XX" : { + "description" : "Client Fehler (kann vom Client behoben werden)", + "content" : { + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + } + } + }, + "5XX" : { + "description" : "Server Fehler (normalerweise nicht vom Client behebbar)", + "content" : { + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + } + } + } + } + } + }, + "/eidas/person/suchen" : { + "post" : { + "operationId" : "suchen", + "parameters" : [ { + "name" : "Client-Request-Time", + "in" : "header", + "description" : "Client-Requestzeit im ISO-8601 Format mit optionaler Zeitzone (zb '2016-10-27T16:36:08.993')", + "schema" : { + "type" : "string", + "format" : "date-time" + } + }, { + "name" : "Client-Request-Id", + "in" : "header", + "description" : "Client-Request ID (um Systemübergreifende Fehlersuche zu vereinfache)", + "schema" : { + "type" : "string" + } + }, { + "name" : "Client-Behkz", + "in" : "header", + "description" : "Client-Behördenkennzeichen", + "required" : true, + "schema" : { + "type" : "string" + } + }, { + "name" : "Client-Name", + "in" : "header", + "description" : "Client-Name bzw Applikationskürzel und Version des aufrufenden Systems (zb 'ZMR 3.4.5')", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/PersonSuchen" + } + } + } + }, + "responses" : { + "default" : { + "description" : "Erfolgreicher Response hat Status 200 wenn Responsepayload vorhanden, sonst 204", + "content" : { + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/SuchenResponse" + } + } + } + }, + "4XX" : { + "description" : "Client Fehler (kann vom Client behoben werden)", + "content" : { + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + } + } + }, + "5XX" : { + "description" : "Server Fehler (normalerweise nicht vom Client behebbar)", + "content" : { + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } + } + } + } + } + } + } + }, + "components" : { + "schemas" : { + "Fault" : { + "required" : [ "message" ], + "type" : "object", + "properties" : { + "message" : { + "type" : "string", + "xml" : { + "name" : "Message" + } + }, + "faultDetails" : { + "$ref" : "#/components/schemas/FaultDetails" + } + }, + "xml" : { + "name" : "Fault" + } + }, + "FaultDetails" : { + "required" : [ "fault" ], + "type" : "object", + "properties" : { + "faultNumber" : { + "type" : "integer", + "format" : "int32", + "xml" : { + "name" : "FaultNumber" + } + }, + "fault" : { + "type" : "array", + "xml" : { + "name" : "Fault" + }, + "items" : { + "$ref" : "#/components/schemas/FaultDetailsEntry" + } + } + } + }, + "FaultDetailsEntry" : { + "type" : "object", + "properties" : { + "key" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "message" : { + "type" : "string", + "xml" : { + "attribute" : true + } + } + } + }, + "AendernResponse" : { + "required" : [ "person" ], + "type" : "object", + "properties" : { + "person" : { + "$ref" : "#/components/schemas/Person" + } + }, + "xml" : { + "name" : "AendernResponse" + } + }, + "AkademischerGrad" : { + "required" : [ "ebene", "kurzerName", "langerName", "stellung" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "ausgestelltVon" : { + "$ref" : "#/components/schemas/AusgestelltVon" + }, + "ebene" : { + "type" : "string", + "xml" : { + "name" : "Ebene" + }, + "enum" : [ "0", "1", "2", "2/3", "3" ] + }, + "stellung" : { + "type" : "string", + "xml" : { + "name" : "Stellung" + }, + "enum" : [ "Vorangestellt", "Nachgestellt" ] + }, + "langerName" : { + "type" : "string", + "xml" : { + "name" : "LangerName" + } + }, + "kurzerName" : { + "type" : "string", + "xml" : { + "name" : "KurzerName" + } + } + } + }, + "Anschrift" : { + "required" : [ "staat", "strasse", "type" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "staat" : { + "$ref" : "#/components/schemas/Staat" + }, + "gemeinde" : { + "type" : "string", + "xml" : { + "name" : "Gemeinde" + } + }, + "strasse" : { + "type" : "string", + "xml" : { + "name" : "Strasse" + } + }, + "postleitzahl" : { + "type" : "string", + "xml" : { + "name" : "Postleitzahl" + } + }, + "hausnummer" : { + "type" : "string", + "xml" : { + "name" : "Hausnummer" + } + }, + "adresszusatz" : { + "type" : "string", + "xml" : { + "name" : "Adresszusatz" + } + }, + "stiege" : { + "type" : "string", + "xml" : { + "name" : "Stiege" + } + }, + "tuer" : { + "type" : "string", + "xml" : { + "name" : "Tuer" + } + }, + "kontaktinformationen" : { + "$ref" : "#/components/schemas/Kontaktinformationen" + }, + "type" : { + "type" : "string" + } + }, + "discriminator" : { + "propertyName" : "type" + } + }, + "AnschriftInland" : { + "required" : [ "gemeinde", "hausnummer", "ort", "postleitzahl", "staat", "strasse" ], + "type" : "object", + "allOf" : [ { + "$ref" : "#/components/schemas/Anschrift" + }, { + "type" : "object", + "properties" : { + "adressstatus" : { + "type" : "string", + "xml" : { + "name" : "Adressstatus" + } + }, + "ort" : { + "type" : "string", + "xml" : { + "name" : "Ort" + } + }, + "ortZweisprachig" : { + "type" : "string", + "xml" : { + "name" : "OrtZweisprachig" + } + }, + "postort" : { + "type" : "string", + "xml" : { + "name" : "Postort" + } + }, + "codes" : { + "$ref" : "#/components/schemas/Anschriftcodes" + }, + "auskunftssperre" : { + "type" : "boolean", + "xml" : { + "name" : "Auskunftssperre" + } + }, + "wohnsitzqualitaet" : { + "type" : "string", + "xml" : { + "name" : "Wohnsitzqualitaet" + }, + "enum" : [ "H", "N", "O" ] + } + } + } ] + }, + "AnschriftInlandAgs" : { + "required" : [ "gemeinde", "hausnummer", "ort", "postleitzahl", "staat", "strasse" ], + "type" : "object", + "allOf" : [ { + "$ref" : "#/components/schemas/Anschrift" + }, { + "type" : "object", + "properties" : { + "adressstatus" : { + "type" : "string", + "xml" : { + "name" : "Adressstatus" + } + }, + "ort" : { + "type" : "string", + "xml" : { + "name" : "Ort" + } + }, + "ortZweisprachig" : { + "type" : "string", + "xml" : { + "name" : "OrtZweisprachig" + } + }, + "postort" : { + "type" : "string", + "xml" : { + "name" : "Postort" + } + }, + "codes" : { + "$ref" : "#/components/schemas/Anschriftcodes" + }, + "auskunftssperre" : { + "type" : "boolean", + "xml" : { + "name" : "Auskunftssperre" + } + }, + "wohnsitzqualitaet" : { + "type" : "string", + "xml" : { + "name" : "Wohnsitzqualitaet" + }, + "enum" : [ "H", "N", "O" ] + }, + "detailgrad" : { + "type" : "string", + "xml" : { + "name" : "Detailgrad" + } + }, + "nutzungsartCode" : { + "type" : "string", + "xml" : { + "name" : "NutzungsartCode" + } + }, + "gebaeudeeigenschaft" : { + "type" : "string", + "xml" : { + "name" : "Gebaeudeeigenschaft" + } + } + } + } ] + }, + "Anschriftcodes" : { + "type" : "object", + "properties" : { + "adresscode" : { + "type" : "string", + "xml" : { + "name" : "Adresscode", + "attribute" : true + } + }, + "subcode" : { + "type" : "string", + "xml" : { + "name" : "Subcode", + "attribute" : true + } + }, + "ortskennziffer" : { + "type" : "string", + "xml" : { + "name" : "Ortskennziffer", + "attribute" : true + } + }, + "strassenkennziffer" : { + "type" : "string", + "xml" : { + "name" : "Strassenkennziffer", + "attribute" : true + } + }, + "objektnummer" : { + "type" : "string", + "xml" : { + "name" : "Objektnummer", + "attribute" : true + } + }, + "nutzungseinheitlaufnummer" : { + "type" : "string", + "xml" : { + "name" : "Nutzungseinheitlaufnummer", + "attribute" : true + } + }, + "adrRefkey" : { + "type" : "string", + "xml" : { + "name" : "AdrRefkey", + "attribute" : true + } + }, + "gbrRefkey" : { + "type" : "string", + "xml" : { + "name" : "GbrRefkey", + "attribute" : true + } + }, + "gemeindekennziffer" : { + "type" : "string", + "xml" : { + "name" : "Gemeindekennziffer", + "attribute" : true + } + } + } + }, + "AusgestelltVon" : { + "required" : [ "behoerde", "datum", "staat" ], + "type" : "object", + "properties" : { + "datum" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "name" : "Datum" + } + }, + "behoerde" : { + "type" : "string", + "xml" : { + "name" : "Behoerde" + } + }, + "staat" : { + "$ref" : "#/components/schemas/Staat" + } + } + }, + "Benutzer" : { + "required" : [ "benutzer" ], + "type" : "object", + "properties" : { + "benutzer" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "behoerdenkennzeichen" : { + "type" : "string", + "xml" : { + "attribute" : true + } + } + } + }, + "Eidas" : { + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "art" : { + "type" : "string", + "xml" : { + "name" : "Art" + } + }, + "wert" : { + "type" : "string", + "xml" : { + "name" : "Wert" + } + }, + "ausstellDatum" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "name" : "AusstellDatum" + } + }, + "ablaufDatum" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "name" : "AblaufDatum" + } + }, + "ausstellBehoerde" : { + "type" : "string", + "xml" : { + "name" : "AusstellBehoerde" + } + }, + "staatscode2" : { + "type" : "string", + "xml" : { + "name" : "Staatscode2" + } + }, + "image" : { + "type" : "array", + "xml" : { + "name" : "Image" + }, + "items" : { + "type" : "string", + "format" : "byte", + "xml" : { + "name" : "Image" + } + } + } + } + }, + "Kontaktinformationen" : { + "type" : "object", + "properties" : { + "firmenname1" : { + "type" : "string", + "xml" : { + "name" : "Firmenname1" + } + }, + "firmenname2" : { + "type" : "string", + "xml" : { + "name" : "Firmenname2" + } + }, + "ansprechpartner" : { + "type" : "string", + "xml" : { + "name" : "Ansprechpartner" + } + }, + "telefon" : { + "type" : "string", + "xml" : { + "name" : "Telefon" + } + }, + "mobil" : { + "type" : "string", + "xml" : { + "name" : "Mobil" + } + }, + "fax" : { + "type" : "string", + "xml" : { + "name" : "Fax" + } + }, + "email" : { + "type" : "string", + "xml" : { + "name" : "Email" + } + }, + "postfach" : { + "type" : "string", + "xml" : { + "name" : "Postfach" + } + } + } + }, + "LetzteOperation" : { + "required" : [ "begruendung", "durchgefuehrtVon" ], + "type" : "object", + "properties" : { + "begruendung" : { + "type" : "string", + "xml" : { + "name" : "Begruendung" + } + }, + "durchgefuehrtVon" : { + "$ref" : "#/components/schemas/Benutzer" + }, + "vorgang" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "zeitpunkt" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + } + } + }, + "PartialDate" : { + "required" : [ "jahr" ], + "type" : "object", + "properties" : { + "jahr" : { + "type" : "integer", + "format" : "int32", + "xml" : { + "attribute" : true + } + }, + "monat" : { + "type" : "integer", + "format" : "int32", + "xml" : { + "attribute" : true + } + }, + "tag" : { + "type" : "integer", + "format" : "int32", + "xml" : { + "attribute" : true + } + } + } + }, + "Person" : { + "required" : [ "letzteOperation", "personendaten", "type" ], + "type" : "object", + "properties" : { + "letzteOperation" : { + "$ref" : "#/components/schemas/LetzteOperation" + }, + "personendaten" : { + "$ref" : "#/components/schemas/PersonendatenErgebnis" + }, + "anschrift" : { + "$ref" : "#/components/schemas/Anschrift" + }, + "akademischerGrad" : { + "type" : "array", + "xml" : { + "name" : "AkademischerGrad" + }, + "items" : { + "$ref" : "#/components/schemas/AkademischerGrad" + } + }, + "reisedokument" : { + "type" : "array", + "xml" : { + "name" : "Reisedokument" + }, + "items" : { + "$ref" : "#/components/schemas/Reisedokument" + } + }, + "sonstigesDokument" : { + "type" : "array", + "xml" : { + "name" : "SonstigesDokument" + }, + "items" : { + "$ref" : "#/components/schemas/SonstigesDokument" + } + }, + "staatsangehoerigkeit" : { + "type" : "array", + "xml" : { + "name" : "Staatsangehoerigkeit" + }, + "items" : { + "$ref" : "#/components/schemas/Staatsangehoerigkeit" + } + }, + "eidas" : { + "type" : "array", + "xml" : { + "name" : "Eidas" + }, + "items" : { + "$ref" : "#/components/schemas/Eidas" + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "version" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "type" : { + "type" : "string" + } + }, + "discriminator" : { + "propertyName" : "type" + } + }, + "PersonendatenErgebnis" : { + "required" : [ "basiszahl", "familienname", "geburtsdatum", "vorname" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "familienname" : { + "type" : "string", + "xml" : { + "name" : "Familienname" + } + }, + "nameVorEhe" : { + "type" : "string", + "xml" : { + "name" : "NameVorEhe" + } + }, + "vorname" : { + "type" : "string", + "xml" : { + "name" : "Vorname" + } + }, + "geburtsbundesland" : { + "type" : "string", + "xml" : { + "name" : "Geburtsbundesland" + }, + "enum" : [ "Burgenland", "Kärnten", "Niederösterreich", "Oberösterreich", "Salzburg", "Steiermark", "Tirol", "Vorarlberg", "Wien" ] + }, + "geburtsort" : { + "type" : "string", + "xml" : { + "name" : "Geburtsort" + } + }, + "geburtsstaat" : { + "$ref" : "#/components/schemas/Staat" + }, + "geburtsdatum" : { + "$ref" : "#/components/schemas/PartialDate" + }, + "geschlecht" : { + "type" : "string", + "xml" : { + "name" : "Geschlecht" + }, + "enum" : [ "Männlich", "Weiblich" ] + }, + "basiszahl" : { + "type" : "string", + "xml" : { + "name" : "Basiszahl" + } + }, + "kitquelle" : { + "type" : "string", + "xml" : { + "name" : "Kitquelle" + } + }, + "bpkZp" : { + "type" : "string", + "xml" : { + "name" : "BpkZp" + } + }, + "sterbedatum" : { + "$ref" : "#/components/schemas/PartialDate" + }, + "geprueft" : { + "type" : "boolean", + "xml" : { + "name" : "Geprueft" + } + } + } + }, + "Reisedokument" : { + "required" : [ "art" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "ausgestelltVon" : { + "$ref" : "#/components/schemas/AusgestelltVon" + }, + "art" : { + "type" : "string", + "xml" : { + "name" : "Art" + }, + "enum" : [ "Asylwerber", "Dienstpass", "Elektronisch", "Fremdenpass", "Konventionspass", "Personalausweis", "Reisepass", "Staatenlos", "Sonstiges" ] + }, + "nummer" : { + "type" : "string", + "xml" : { + "name" : "Nummer" + } + } + } + }, + "SonstigesDokument" : { + "required" : [ "art", "nummer" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "ausgestelltVon" : { + "$ref" : "#/components/schemas/AusgestelltVon" + }, + "art" : { + "type" : "string", + "xml" : { + "name" : "Art" + }, + "enum" : [ "Führerschein", "Geburtsurkunde", "Heiratsurkunde", "Sonstiges", "Staatsbürgerschaftsnachweis", "Sterbeurkunde", "Todeserklärung" ] + }, + "lichtbildausweis" : { + "type" : "boolean", + "xml" : { + "name" : "Lichtbildausweis" + } + }, + "nummer" : { + "type" : "string", + "xml" : { + "name" : "Nummer" + } + }, + "name" : { + "type" : "string", + "xml" : { + "name" : "Name" + } + } + } + }, + "Staat" : { + "type" : "object", + "properties" : { + "isoCode3" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "name" : { + "type" : "string", + "xml" : { + "attribute" : true + } + } + } + }, + "Staatsangehoerigkeit" : { + "required" : [ "staat" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "staat" : { + "$ref" : "#/components/schemas/Staat" + } + } + }, + "ZmrPerson" : { + "required" : [ "letzteOperation", "personendaten", "qkz" ], + "type" : "object", + "allOf" : [ { + "$ref" : "#/components/schemas/Person" + }, { + "type" : "object", + "properties" : { + "auskunftssperre" : { + "type" : "boolean", + "xml" : { + "name" : "Auskunftssperre" + } + }, + "qkz" : { + "type" : "array", + "xml" : { + "name" : "Qkz" + }, + "items" : { + "type" : "string" + } + } + } + } ] + }, + "Aendern" : { + "type" : "object", + "properties" : { + "personendaten" : { + "$ref" : "#/components/schemas/Personendaten" + }, + "anschrift" : { + "$ref" : "#/components/schemas/Anschrift" + }, + "akademischerGrad" : { + "type" : "array", + "xml" : { + "name" : "AkademischerGrad" + }, + "items" : { + "$ref" : "#/components/schemas/AkademischerGrad" + } + }, + "reisedokument" : { + "type" : "array", + "xml" : { + "name" : "Reisedokument" + }, + "items" : { + "$ref" : "#/components/schemas/Reisedokument" + } + }, + "sonstigesDokument" : { + "type" : "array", + "xml" : { + "name" : "SonstigesDokument" + }, + "items" : { + "$ref" : "#/components/schemas/SonstigesDokument" + } + }, + "staatsangehoerigkeit" : { + "type" : "array", + "xml" : { + "name" : "Staatsangehoerigkeit" + }, + "items" : { + "$ref" : "#/components/schemas/Staatsangehoerigkeit" + } + }, + "eidas" : { + "type" : "array", + "xml" : { + "name" : "Eidas" + }, + "items" : { + "$ref" : "#/components/schemas/Eidas" + } + } + } + }, + "Anlegen" : { + "type" : "object", + "properties" : { + "anschrift" : { + "$ref" : "#/components/schemas/Anschrift" + }, + "akademischerGrad" : { + "type" : "array", + "xml" : { + "name" : "AkademischerGrad" + }, + "items" : { + "$ref" : "#/components/schemas/AkademischerGrad" + } + }, + "reisedokument" : { + "type" : "array", + "xml" : { + "name" : "Reisedokument" + }, + "items" : { + "$ref" : "#/components/schemas/Reisedokument" + } + }, + "sonstigesDokument" : { + "type" : "array", + "xml" : { + "name" : "SonstigesDokument" + }, + "items" : { + "$ref" : "#/components/schemas/SonstigesDokument" + } + }, + "staatsangehoerigkeit" : { + "type" : "array", + "xml" : { + "name" : "Staatsangehoerigkeit" + }, + "items" : { + "$ref" : "#/components/schemas/Staatsangehoerigkeit" + } + }, + "eidas" : { + "type" : "array", + "xml" : { + "name" : "Eidas" + }, + "items" : { + "$ref" : "#/components/schemas/Eidas" + } + } + } + }, + "Beenden" : { + "type" : "object", + "properties" : { + "entityId" : { + "type" : "array", + "xml" : { + "name" : "EntityId" + }, + "items" : { + "type" : "string", + "xml" : { + "name" : "EntityId" + } + } + } + } + }, + "PersonAendern" : { + "required" : [ "begruendung", "entityId", "version" ], + "type" : "object", + "properties" : { + "begruendung" : { + "type" : "string", + "xml" : { + "name" : "Begruendung" + } + }, + "anlegen" : { + "$ref" : "#/components/schemas/Anlegen" + }, + "aendern" : { + "$ref" : "#/components/schemas/Aendern" + }, + "beenden" : { + "$ref" : "#/components/schemas/Beenden" + }, + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "version" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + } + }, + "xml" : { + "name" : "PersonAendern" + } + }, + "Personendaten" : { + "required" : [ "familienname", "geburtsdatum", "vorname" ], + "type" : "object", + "properties" : { + "entityId" : { + "type" : "string", + "xml" : { + "attribute" : true + } + }, + "gueltigAb" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "gueltigBis" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "attribute" : true + } + }, + "familienname" : { + "type" : "string", + "xml" : { + "name" : "Familienname" + } + }, + "nameVorEhe" : { + "type" : "string", + "xml" : { + "name" : "NameVorEhe" + } + }, + "vorname" : { + "type" : "string", + "xml" : { + "name" : "Vorname" + } + }, + "geburtsbundesland" : { + "type" : "string", + "xml" : { + "name" : "Geburtsbundesland" + }, + "enum" : [ "Burgenland", "Kärnten", "Niederösterreich", "Oberösterreich", "Salzburg", "Steiermark", "Tirol", "Vorarlberg", "Wien" ] + }, + "geburtsort" : { + "type" : "string", + "xml" : { + "name" : "Geburtsort" + } + }, + "geburtsstaat" : { + "$ref" : "#/components/schemas/Staat" + }, + "geburtsdatum" : { + "$ref" : "#/components/schemas/PartialDate" + }, + "geschlecht" : { + "type" : "string", + "xml" : { + "name" : "Geschlecht" + }, + "enum" : [ "Männlich", "Weiblich" ] + } + } + }, + "AnlegenResponse" : { + "required" : [ "person" ], + "type" : "object", + "properties" : { + "person" : { + "$ref" : "#/components/schemas/Person" + } + }, + "xml" : { + "name" : "AnlegenResponse" + } + }, + "PersonAnlegen" : { + "required" : [ "anschrift", "begruendung", "personendaten" ], + "type" : "object", + "properties" : { + "begruendung" : { + "type" : "string", + "xml" : { + "name" : "Begruendung" + } + }, + "personendaten" : { + "$ref" : "#/components/schemas/Personendaten" + }, + "anschrift" : { + "$ref" : "#/components/schemas/Anschrift" + }, + "akademischerGrad" : { + "type" : "array", + "xml" : { + "name" : "AkademischerGrad" + }, + "items" : { + "$ref" : "#/components/schemas/AkademischerGrad" + } + }, + "reisedokument" : { + "type" : "array", + "xml" : { + "name" : "Reisedokument" + }, + "items" : { + "$ref" : "#/components/schemas/Reisedokument" + } + }, + "sonstigesDokument" : { + "type" : "array", + "xml" : { + "name" : "SonstigesDokument" + }, + "items" : { + "$ref" : "#/components/schemas/SonstigesDokument" + } + }, + "staatsangehoerigkeit" : { + "type" : "array", + "xml" : { + "name" : "Staatsangehoerigkeit" + }, + "items" : { + "$ref" : "#/components/schemas/Staatsangehoerigkeit" + } + }, + "eidas" : { + "type" : "array", + "xml" : { + "name" : "Eidas" + }, + "items" : { + "$ref" : "#/components/schemas/Eidas" + } + } + }, + "xml" : { + "name" : "PersonAnlegen" + } + }, + "SuchenResponse" : { + "type" : "object", + "properties" : { + "person" : { + "type" : "array", + "xml" : { + "name" : "Person" + }, + "items" : { + "$ref" : "#/components/schemas/Person" + } + } + }, + "xml" : { + "name" : "SuchenResponse" + } + }, + "PersonSuchen" : { + "required" : [ "begruendung", "suchdaten", "suchoptionen" ], + "type" : "object", + "properties" : { + "begruendung" : { + "type" : "string", + "xml" : { + "name" : "Begruendung" + } + }, + "suchoptionen" : { + "$ref" : "#/components/schemas/Suchoptionen" + }, + "suchdaten" : { + "$ref" : "#/components/schemas/Suchdaten" + } + }, + "xml" : { + "name" : "PersonSuchen" + } + }, + "SuchAnschrift" : { + "type" : "object", + "properties" : { + "staat" : { + "$ref" : "#/components/schemas/Staat" + }, + "gemeinde" : { + "type" : "string", + "xml" : { + "name" : "Gemeinde" + } + }, + "strasse" : { + "type" : "string", + "xml" : { + "name" : "Strasse" + } + }, + "ort" : { + "type" : "string", + "xml" : { + "name" : "Ort" + } + }, + "postleitzahl" : { + "type" : "string", + "xml" : { + "name" : "Postleitzahl" + } + }, + "hausnummer" : { + "type" : "string", + "xml" : { + "name" : "Hausnummer" + } + }, + "adresszusatz" : { + "type" : "string", + "xml" : { + "name" : "Adresszusatz" + } + }, + "stiege" : { + "type" : "string", + "xml" : { + "name" : "Stiege" + } + }, + "tuer" : { + "type" : "string", + "xml" : { + "name" : "Tuer" + } + }, + "postfach" : { + "type" : "string", + "xml" : { + "name" : "Postfach" + } + } + } + }, + "SuchAusgestelltVon" : { + "type" : "object", + "properties" : { + "datum" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "name" : "Datum" + } + }, + "behoerde" : { + "type" : "string", + "xml" : { + "name" : "Behoerde" + } + }, + "staat" : { + "$ref" : "#/components/schemas/Staat" + } + } + }, + "SuchEidas" : { + "type" : "object", + "properties" : { + "art" : { + "type" : "string", + "xml" : { + "name" : "Art" + } + }, + "wert" : { + "type" : "string", + "xml" : { + "name" : "Wert" + } + }, + "ausstellDatum" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "name" : "AusstellDatum" + } + }, + "ablaufDatum" : { + "type" : "string", + "format" : "date-time", + "xml" : { + "name" : "AblaufDatum" + } + }, + "ausstellBehoerde" : { + "type" : "string", + "xml" : { + "name" : "AusstellBehoerde" + } + }, + "staatscode2" : { + "type" : "string", + "xml" : { + "name" : "Staatscode2" + } + } + } + }, + "SuchReisedokument" : { + "type" : "object", + "properties" : { + "art" : { + "type" : "string", + "xml" : { + "name" : "Art" + }, + "enum" : [ "Asylwerber", "Dienstpass", "Elektronisch", "Fremdenpass", "Konventionspass", "Personalausweis", "Reisepass", "Staatenlos", "Sonstiges" ] + }, + "ausgestelltVon" : { + "$ref" : "#/components/schemas/SuchAusgestelltVon" + }, + "nummer" : { + "type" : "string", + "xml" : { + "name" : "Nummer" + } + } + } + }, + "SuchStaatsangehoerigkeit" : { + "type" : "object", + "properties" : { + "staat" : { + "$ref" : "#/components/schemas/Staat" + } + } + }, + "Suchdaten" : { + "required" : [ "familienname", "vorname" ], + "type" : "object", + "properties" : { + "basiszahl" : { + "type" : "string", + "xml" : { + "name" : "Basiszahl" + } + }, + "bpkZp" : { + "type" : "string", + "xml" : { + "name" : "BpkZp" + } + }, + "fremdBpkBmiZp" : { + "type" : "string", + "xml" : { + "name" : "FremdBpkBmiZp" + } + }, + "entityId" : { + "type" : "string", + "xml" : { + "name" : "EntityId" + } + }, + "familienname" : { + "type" : "string", + "xml" : { + "name" : "Familienname" + } + }, + "nameVorEhe" : { + "type" : "string", + "xml" : { + "name" : "NameVorEhe" + } + }, + "vorname" : { + "type" : "string", + "xml" : { + "name" : "Vorname" + } + }, + "geburtsdatum" : { + "$ref" : "#/components/schemas/PartialDate" + }, + "geburtsort" : { + "type" : "string", + "xml" : { + "name" : "Geburtsort" + } + }, + "geburtsstaat" : { + "$ref" : "#/components/schemas/Staat" + }, + "geschlecht" : { + "type" : "string", + "xml" : { + "name" : "Geschlecht" + }, + "enum" : [ "Männlich", "Weiblich" ] + }, + "anschrift" : { + "$ref" : "#/components/schemas/SuchAnschrift" + }, + "reisedokument" : { + "$ref" : "#/components/schemas/SuchReisedokument" + }, + "staatsangehoerigkeit" : { + "$ref" : "#/components/schemas/SuchStaatsangehoerigkeit" + }, + "eidas" : { + "$ref" : "#/components/schemas/SuchEidas" + } + } + }, + "Suchoptionen" : { + "required" : [ "historisch" ], + "type" : "object", + "properties" : { + "historisch" : { + "type" : "string", + "xml" : { + "name" : "Historisch" + }, + "enum" : [ "Aktuell", "AktuellDannHistorisch", "AktuellUndHistorisch" ] + }, + "formalisiert" : { + "type" : "boolean", + "xml" : { + "name" : "Formalisiert" + } + }, + "sucheMitNamensteilen" : { + "type" : "boolean", + "xml" : { + "name" : "SucheMitNamensteilen" + } + }, + "suchwizard" : { + "type" : "boolean", + "xml" : { + "name" : "Suchwizard" + } + }, + "zmr" : { + "type" : "boolean", + "xml" : { + "name" : "Zmr" + } + } + }, + "xml" : { + "name" : "Suchoptionen", + "namespace" : "http://bmi.gv.at/ernp" + } + } + } + } +} \ No newline at end of file -- 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 +- .../src/main/resources/eidas_v2_auth.beans.xml | 9 +- 4 files changed, 409 insertions(+), 35 deletions(-) (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/resources') 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); diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml index d82ccec5..40e63a91 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml @@ -26,13 +26,8 @@ - - - - - + -- cgit v1.2.3 From 837ce1a4fbece82fd84ab77fdd1eb0284ad2106a Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Thu, 3 Feb 2022 19:05:47 +0100 Subject: refactor(ernp): update openAPI specification from BM.I to use 'application/json' instead of 'application/xml' --- .../main/resources/wsdl/ernp_client/openapi.json | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/resources') diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json index c8276f3a..fef86c1b 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json @@ -83,7 +83,7 @@ } ], "requestBody" : { "content" : { - "application/xml" : { + "application/json" : { "schema" : { "$ref" : "#/components/schemas/PersonAendern" } @@ -94,7 +94,7 @@ "default" : { "description" : "Erfolgreicher Response hat Status 200 wenn Responsepayload vorhanden, sonst 204", "content" : { - "application/xml" : { + "application/json" : { "schema" : { "$ref" : "#/components/schemas/AendernResponse" } @@ -104,7 +104,7 @@ "4XX" : { "description" : "Client Fehler (kann vom Client behoben werden)", "content" : { - "application/xml" : { + "application/json" : { "schema" : { "$ref" : "#/components/schemas/Fault" } @@ -114,7 +114,7 @@ "5XX" : { "description" : "Server Fehler (normalerweise nicht vom Client behebbar)", "content" : { - "application/xml" : { + "application/json" : { "schema" : { "$ref" : "#/components/schemas/Fault" } @@ -161,7 +161,7 @@ } ], "requestBody" : { "content" : { - "application/xml" : { + "application/json" : { "schema" : { "$ref" : "#/components/schemas/PersonAnlegen" } @@ -172,7 +172,7 @@ "default" : { "description" : "Erfolgreicher Response hat Status 200 wenn Responsepayload vorhanden, sonst 204", "content" : { - "application/xml" : { + "application/json" : { "schema" : { "$ref" : "#/components/schemas/AnlegenResponse" } @@ -182,7 +182,7 @@ "4XX" : { "description" : "Client Fehler (kann vom Client behoben werden)", "content" : { - "application/xml" : { + "application/json" : { "schema" : { "$ref" : "#/components/schemas/Fault" } @@ -192,7 +192,7 @@ "5XX" : { "description" : "Server Fehler (normalerweise nicht vom Client behebbar)", "content" : { - "application/xml" : { + "application/json" : { "schema" : { "$ref" : "#/components/schemas/Fault" } @@ -239,7 +239,7 @@ } ], "requestBody" : { "content" : { - "application/xml" : { + "application/json" : { "schema" : { "$ref" : "#/components/schemas/PersonSuchen" } @@ -250,7 +250,7 @@ "default" : { "description" : "Erfolgreicher Response hat Status 200 wenn Responsepayload vorhanden, sonst 204", "content" : { - "application/xml" : { + "application/json" : { "schema" : { "$ref" : "#/components/schemas/SuchenResponse" } @@ -260,7 +260,7 @@ "4XX" : { "description" : "Client Fehler (kann vom Client behoben werden)", "content" : { - "application/xml" : { + "application/json" : { "schema" : { "$ref" : "#/components/schemas/Fault" } @@ -270,7 +270,7 @@ "5XX" : { "description" : "Server Fehler (normalerweise nicht vom Client behebbar)", "content" : { - "application/xml" : { + "application/json" : { "schema" : { "$ref" : "#/components/schemas/Fault" } -- cgit v1.2.3 From 8d4680da725db89c5fc11767d8892f3fb16aa0e7 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Thu, 3 Feb 2022 20:30:06 +0100 Subject: test(core): fix broken tests after refactoring of ERnPClient API --- .../src/main/resources/application.properties | 10 +++++ .../messages/eidas_connector_message.properties | 4 ++ .../AlternativeSearchTaskWithRegisterTest.java | 46 +++++++++++++++++++++- .../tasks/InitialSearchTaskWithRegistersTest.java | 31 ++++++++++++--- .../resources/config/junit_config_1.properties | 19 +++++++-- .../config/junit_config_1_springboot.properties | 11 ++++++ 6 files changed, 110 insertions(+), 11 deletions(-) (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/resources') diff --git a/connector/src/main/resources/application.properties b/connector/src/main/resources/application.properties index bec125dc..0b36b103 100644 --- a/connector/src/main/resources/application.properties +++ b/connector/src/main/resources/application.properties @@ -112,6 +112,16 @@ eidas.ms.auth.eIDAS.szrclient.eidasbind.mds.inject=false #eidas.ms.auth.eIDAS.zmrclient.req.update.reason.code=PERS_AENDERN #eidas.ms.auth.eIDAS.zmrclient.req.update.reason.text=KITT for eIDAS Matching +# ERnP communication +#eidas.ms.auth.eIDAS.ernpclient.endpoint=http://localhost:1718/demoernp +#eidas.ms.auth.eIDAS.ernpclient.req.organisation.behoerdennr=jUnit123456 +#eidas.ms.auth.eIDAS.client.common.ssl.keyStore.type=jks +#eidas.ms.auth.eIDAS.client.common.ssl.keyStore.path=../keystore/junit_test.jks +#eidas.ms.auth.eIDAS.client.common.ssl.keyStore.password=password +#eidas.ms.auth.eIDAS.client.common.ssl.key.alias=meta +#eidas.ms.auth.eIDAS.client.common.ssl.key.password=password + + #Raw eIDAS Id data storage diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties index 3ccfff19..188c5a8f 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties @@ -20,4 +20,8 @@ module.eidasauth.matching.02=Matching failed, because ZMR response contains hist module.eidasauth.matching.03=Matching failed in workflow step: {0} with error: {1} module.eidasauth.matching.04=An error occurred while loading your data from official registers. Please contact the support. +module.eidasauth.matching.11=Matching failed, because of an ERnP communication error. Reason: {0} +module.eidasauth.matching.12=Matching failed, because ERnP response contains historic information which is not supported. + module.eidasauth.matching.99=Matching failed, because of an unexpected processing error. Reason: {0} + diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java index 0c6ec95d..028c0359 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java @@ -35,7 +35,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -49,6 +49,7 @@ import org.springframework.web.context.request.ServletRequestAttributes; import com.github.skjolber.mockito.soap.SoapServiceRule; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.ErnpRestClient.ErnpRegisterResult; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.ernp.IErnpClient; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.IZmrClient; import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient.ZmrRegisterResult; @@ -407,7 +408,10 @@ public class AlternativeSearchTaskWithRegisterTest { when(zmrMock.service(zmrReq.capture(), any())) .thenReturn(loadResponseFromFile("/data/zmr/seq_1-8_search_with_personalId_only_resp.xml")) .thenThrow(new RuntimeException("This request is not needed any more")); - + + Mockito.when(ernpClient.searchWithPersonIdentifier(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + // execute task TaskExecutionException exception = assertThrows(TaskExecutionException.class, () -> task.execute(pendingReq, executionContext)); @@ -470,6 +474,13 @@ public class AlternativeSearchTaskWithRegisterTest { .thenReturn(loadResponseFromFile("/data/zmr/seq_3-8_kitt_get_latest_version_resp.xml")) .thenThrow(new RuntimeException("This request is not needed any more")); + Mockito.when(ernpClient.searchWithPersonIdentifier(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(any(), any(), any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + // execute task task.execute(pendingReq, executionContext); @@ -549,6 +560,15 @@ public class AlternativeSearchTaskWithRegisterTest { .thenReturn(loadResponseFromFile("/data/zmr/seq_3-10_kitt_update_resp.xml")) .thenThrow(new RuntimeException("This request is not needed any more")); + Mockito.when(ernpClient.searchWithPersonIdentifier(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchCountrySpecific(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(any(), any(), any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + // execute task task.execute(pendingReq, executionContext); @@ -636,6 +656,9 @@ public class AlternativeSearchTaskWithRegisterTest { .thenReturn(loadResponseFromFile("/data/zmr/empty_zmr_result.xml")) .thenThrow(new RuntimeException("This request is not needed any more")); + Mockito.when(ernpClient.searchWithPersonIdentifier(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + // execute task task.execute(pendingReq, executionContext); @@ -697,6 +720,13 @@ public class AlternativeSearchTaskWithRegisterTest { .thenReturn(loadResponseFromFile("/data/zmr/search_with_personalId_only_resp_moreThanOne.xml")) .thenThrow(new RuntimeException("This request is not needed any more")); + Mockito.when(ernpClient.searchWithPersonIdentifier(any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds(any(), any(), any(), any())) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + // execute task TaskExecutionException exception = assertThrows(TaskExecutionException.class, () -> task.execute(pendingReq, executionContext)); @@ -769,6 +799,14 @@ public class AlternativeSearchTaskWithRegisterTest { .thenReturn(loadResponseFromFile("/data/zmr/empty_zmr_result.xml")) .thenThrow(new RuntimeException("This request is not needed any more")); + Mockito.when(ernpClient.searchWithPersonIdentifier("7cEYasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit", "DE")) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.searchWithMds("XXXKlaus - Maria", "XXXvon Brandenburg", "1994-12-31","DE")) + .thenReturn(emptyErnpRegisterResult()); + Mockito.when(ernpClient.update(any(), any())) + .thenThrow(new IllegalStateException("ERnP update should not be neccessary")); + + // execute task task.execute(pendingReq, executionContext); @@ -970,6 +1008,10 @@ public class AlternativeSearchTaskWithRegisterTest { } + @NotNull + private ErnpRegisterResult emptyErnpRegisterResult() { + return new ErnpRegisterResult(Collections.emptyList()); + } } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java index ea84c39c..565efe09 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/InitialSearchTaskWithRegistersTest.java @@ -47,6 +47,7 @@ import javax.xml.namespace.QName; import org.apache.commons.lang3.RandomStringUtils; import org.jetbrains.annotations.NotNull; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; @@ -54,8 +55,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -103,6 +102,8 @@ import eu.eidas.auth.commons.attribute.PersonType; import eu.eidas.auth.commons.light.impl.LightRequest; import eu.eidas.auth.commons.protocol.impl.AuthenticationResponse; import lombok.SneakyThrows; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { @@ -119,14 +120,16 @@ public class InitialSearchTaskWithRegistersTest { @Rule public SoapServiceRule soap = SoapServiceRule.newInstance(); - @Mock private IErnpClient ernpClient; - - @Autowired private IZmrClient zmrClient; - @Autowired private List handlers; + @Autowired IErnpClient ernpClient; + @Autowired IZmrClient zmrClient; + @Autowired List handlers; + private RegisterSearchService registerSearchService; private ServicePort zmrMock = null; + private static MockWebServer mockWebServer; + private final ICcSpecificEidProcessingService eidPostProcessor = createEidPostProcessor(); private InitialSearchTask task; @@ -144,13 +147,24 @@ public class InitialSearchTaskWithRegistersTest { at.gv.bmi.namespace.zmr_su.zmr._20040201.ObjectFactory.class, at.gv.bmi.namespace.zmr_su.gis._20070725.ObjectFactory.class, at.gv.bmi.namespace.zmr_su.base._20040201.ObjectFactory.class); + + mockWebServer = new MockWebServer(); + mockWebServer.start(1718); + } + @AfterClass + @SneakyThrows + public static void resetTestEnviroment() { + mockWebServer.shutdown(); + + } /** * jUnit test set-up. */ @Before + @SneakyThrows public void setUp() throws URISyntaxException, EaafStorageException { if (zmrMock == null) { zmrMock = soap.mock(ServicePort.class, "http://localhost:1234/demozmr"); @@ -167,6 +181,11 @@ public class InitialSearchTaskWithRegistersTest { pendingReq = new TestRequestImpl(); + + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody("{}") + .setHeader("Content-Type", "application/json;charset=utf-8")); + } /** diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties index be716e95..d84777f3 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1.properties @@ -8,9 +8,9 @@ eidas.ms.context.use.clustermode=true eidas.ms.monitoring.eIDASNode.metadata.url= -eidas.ms.client.http.connection.timeout.socket=1 -eidas.ms.client.http.connection.timeout.connection=1 -eidas.ms.client.http.connection.timeout.request=1 +eidas.ms.client.http.connection.timeout.socket=5 +eidas.ms.client.http.connection.timeout.connection=5 +eidas.ms.client.http.connection.timeout.request=5 ##Specific logger configuration @@ -100,6 +100,19 @@ eidas.ms.auth.eIDAS.zmrclient.req.organisation.behoerdennr=jUnit123456 eidas.ms.auth.eIDAS.zmrclient.req.update.reason.code=EIDAS-KITT + +# ERnP communication +eidas.ms.auth.eIDAS.ernpclient.endpoint=http://localhost:1718/demoernp +eidas.ms.auth.eIDAS.ernpclient.req.organisation.behoerdennr=jUnit123456 +eidas.ms.auth.eIDAS.client.common.ssl.keyStore.type=jks +eidas.ms.auth.eIDAS.client.common.ssl.keyStore.path=../keystore/junit_test.jks +eidas.ms.auth.eIDAS.client.common.ssl.keyStore.password=password +eidas.ms.auth.eIDAS.client.common.ssl.key.alias=meta +eidas.ms.auth.eIDAS.client.common.ssl.key.password=password + + + +#### SP End-Points ##### ## PVP2 S-Profile end-point configuration eidas.ms.pvp2.keystore.path=keys/..... eidas.ms.pvp2.keystore.password= diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1_springboot.properties b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1_springboot.properties index 224e1b1f..0cc89a4a 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1_springboot.properties +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/resources/config/junit_config_1_springboot.properties @@ -57,7 +57,18 @@ eidas.ms.auth.eIDAS.zmrclient.req.organisation.behoerdennr=jUnit123456 eidas.ms.auth.eIDAS.zmrclient.req.update.reason.code=EIDAS-KITT eidas.ms.auth.eIDAS.zmrclient.req.update.reason.text=KITT for eIDAS Matching +# ERnP communication +eidas.ms.auth.eIDAS.ernpclient.endpoint=http://localhost:1718/demoernp +eidas.ms.auth.eIDAS.ernpclient.req.organisation.behoerdennr=jUnit123456 +eidas.ms.auth.eIDAS.client.common.ssl.keyStore.type=jks +eidas.ms.auth.eIDAS.client.common.ssl.keyStore.path=../keystore/junit_test.jks +eidas.ms.auth.eIDAS.client.common.ssl.keyStore.password=password +eidas.ms.auth.eIDAS.client.common.ssl.key.alias=meta +eidas.ms.auth.eIDAS.client.common.ssl.key.password=password + + +#### SP End-Points ##### ## PVP2 S-Profile end-point configuration eidas.ms.pvp2.keystore.type=jks eidas.ms.pvp2.keystore.path=keys/junit.jks -- 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 +++++++++++---------- .../messages/eidas_connector_message.properties | 4 + ...eceiveAustrianResidenceGuiResponseTaskTest.java | 127 ++++++++++----- 8 files changed, 323 insertions(+), 143 deletions(-) (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/resources') 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 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(); } } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties index 188c5a8f..f1bf2128 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties @@ -23,5 +23,9 @@ module.eidasauth.matching.04=An error occurred while loading your data from offi module.eidasauth.matching.11=Matching failed, because of an ERnP communication error. Reason: {0} module.eidasauth.matching.12=Matching failed, because ERnP response contains historic information which is not supported. +module.eidasauth.matching.20=Matching be using residence information was canceled. Use another method for matching or create a new Austrian identity. +module.eidasauth.matching.21=Matching be using residence information failed by missing input information. Use another method for matching or create a new Austrian identity. +module.eidasauth.matching.22=Can not find an unique match by using residence information. Provide more or other data, use another method for matching, or create a new Austrian identity. + module.eidasauth.matching.99=Matching failed, because of an unexpected processing error. Reason: {0} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskTest.java index 64bb0d48..15edce07 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveAustrianResidenceGuiResponseTaskTest.java @@ -1,14 +1,9 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.tasks; -import static at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask.PARAM_CITY; -import static at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask.PARAM_FORMER_RESIDENCE_AVAILABLE; -import static at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask.PARAM_STREET; -import static at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask.PARAM_ZIPCODE; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.eq; -import static org.springframework.util.Assert.isInstanceOf; import java.math.BigInteger; import java.util.Arrays; @@ -21,7 +16,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.i18n.LocaleContextHolder; @@ -36,21 +30,22 @@ import com.google.common.collect.Lists; import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummyConfigMap; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.controller.AdresssucheController.AdresssucheOutput; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.MatchedPersonResult; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.ManualFixNecessaryException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService.RegisterOperationStatus; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService.RegisterStatusResults; import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks.ReceiveAustrianResidenceGuiResponseTask.UserInput; import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; -import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper; import at.gv.egiz.eaaf.core.impl.idp.module.test.TestRequestImpl; import at.gv.egiz.eaaf.core.impl.idp.process.ExecutionContextImpl; +import lombok.SneakyThrows; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { @@ -67,7 +62,7 @@ public class ReceiveAustrianResidenceGuiResponseTaskTest { private ReceiveAustrianResidenceGuiResponseTask task; - private final ExecutionContext executionContext = new ExecutionContextImpl(); + private ExecutionContext executionContext; private MockHttpServletRequest httpReq; private MockHttpServletResponse httpResp; private TestRequestImpl pendingReq; @@ -79,8 +74,9 @@ public class ReceiveAustrianResidenceGuiResponseTaskTest { */ @Before public void setUp() throws Exception { + executionContext = new ExecutionContextImpl(); task = new ReceiveAustrianResidenceGuiResponseTask(registerSearchService); - + httpReq = new MockHttpServletRequest("POST", "https://localhost/ms_connector"); httpResp = new MockHttpServletResponse(); RequestContextHolder.resetRequestAttributes(); @@ -93,9 +89,27 @@ public class ReceiveAustrianResidenceGuiResponseTaskTest { LocaleContextHolder.resetLocaleContext(); } + @Test + public void canceledByUser() throws Exception { + AdresssucheOutput userInput = setupUserInput(); + SimpleEidasData eidasData = setupEidasData(); + RegisterStatusResults registerSearchResult = buildEmptyResult(); + mockRegisterSearch(userInput, registerSearchResult, eidasData); + MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); + httpReq.setParameter(ReceiveAustrianResidenceGuiResponseTask.HTTP_PARAM_NO_RESIDENCE, "true"); + + task.execute(pendingReq, executionContext); + + assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.20", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + + } + @Test public void noRegisterResult() throws Exception { - UserInput userInput = setupUserInput(); + AdresssucheOutput userInput = setupUserInput(); SimpleEidasData eidasData = setupEidasData(); RegisterStatusResults registerSearchResult = buildEmptyResult(); mockRegisterSearch(userInput, registerSearchResult, eidasData); @@ -103,56 +117,86 @@ public class ReceiveAustrianResidenceGuiResponseTaskTest { task.execute(pendingReq, executionContext); - assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK)); + assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.22", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + } @Test - public void exactlyOneRegisterResult_Matching() throws Exception { - UserInput userInput = setupUserInput(); + public void exactlyOneRegisterResult_NoUpdate() throws Exception { + AdresssucheOutput userInput = setupUserInput(); SimpleEidasData eidasData = setupEidasData(); RegisterStatusResults registerSearchResult = buildResultWithOneMatch(buildMatchingRegisterResult(eidasData)); MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); mockRegisterSearch(userInput, registerSearchResult, eidasData); task.execute(pendingReq, executionContext); - + + // validate state assertNull("Transition To S9", executionContext.get(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK)); - Mockito.verify(registerSearchService).step7aKittProcess(eq(registerSearchResult), eq(eidasData)); - + MatchedPersonResult matchingResult = MatchingTaskUtils.getFinalMatchingResult(pendingReq); + assertNotNull("no final matching result", matchingResult); + validateMatchedPerson(matchingResult, registerSearchResult); + } @Test - public void exactlyOneRegisterResult_NotMatching() throws Exception { - UserInput userInput = setupUserInput(); + public void exactlyOneRegisterResult_UpdateRequired() throws Exception { + AdresssucheOutput userInput = setupUserInput(); SimpleEidasData eidasData = setupEidasData(); RegisterStatusResults registerSearchResult = buildResultWithOneMatch(buildNotMatchingRegisterResult(eidasData)); + RegisterStatusResults registerUpdateResult = buildResultWithOneMatch(buildRandomRegisterResult()); MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); mockRegisterSearch(userInput, registerSearchResult, eidasData); - + Mockito.when(registerSearchService.step7aKittProcess(eq(registerSearchResult), eq(eidasData))) + .thenReturn(registerUpdateResult); + + // perform test task.execute(pendingReq, executionContext); - assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK)); + // validate state + assertNull("Transition To S9", executionContext.get(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK)); + + MatchedPersonResult matchingResult = MatchingTaskUtils.getFinalMatchingResult(pendingReq); + assertNotNull("no final matching result", matchingResult); + validateMatchedPerson(matchingResult, registerUpdateResult); + } @Test public void moreThanOneRegisterResult() throws Exception { - UserInput userInput = setupUserInput(); + AdresssucheOutput userInput = setupUserInput(); SimpleEidasData eidasData = setupEidasData(); RegisterStatusResults registerSearchResult = buildResultWithTwoMatches(); MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, registerSearchResult); mockRegisterSearch(userInput, registerSearchResult, eidasData); - TaskExecutionException e = assertThrows(TaskExecutionException.class, - () -> task.execute(pendingReq, executionContext)); + task.execute(pendingReq, executionContext); - assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); - isInstanceOf(ManualFixNecessaryException.class, e.getOriginalException()); - assertNull("Transition To S16", executionContext.get(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK)); + assertEquals("Transition To S9", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.22", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + } - private void mockRegisterSearch(UserInput userInput, RegisterStatusResults registerSearchResult, SimpleEidasData eidasData ) { + @SneakyThrows + private void validateMatchedPerson(MatchedPersonResult current, + RegisterStatusResults registerUpdateResult) { + RegisterResult expected = registerUpdateResult.getResult(); + assertEquals("familyName", expected.getFamilyName(), current.getFamilyName()); + assertEquals("givenName", expected.getGivenName(), current.getGivenName()); + assertEquals("birthday", expected.getDateOfBirth(), current.getDateOfBirth()); + assertEquals("bpk", expected.getBpk(), current.getBpk()); + + } + + @SneakyThrows + private void mockRegisterSearch(AdresssucheOutput userInput, RegisterStatusResults registerSearchResult, SimpleEidasData eidasData ) { Mockito.when(registerSearchService.searchWithResidence(eq(registerSearchResult.getOperationStatus()), eq(eidasData), - eq(userInput.getZipcode()), eq(userInput.getCity()), eq(userInput.getStreet()))).thenReturn(registerSearchResult); + eq(userInput))).thenReturn(registerSearchResult); } @NotNull @@ -216,11 +260,13 @@ public class ReceiveAustrianResidenceGuiResponseTaskTest { } - private void setHttpParameters(UserInput input) { - httpReq.setParameter(PARAM_FORMER_RESIDENCE_AVAILABLE, String.valueOf(input.isFormerResidenceAvailable())); - httpReq.setParameter(PARAM_STREET, input.getStreet()); - httpReq.setParameter(PARAM_CITY, input.getCity()); - httpReq.setParameter(PARAM_ZIPCODE, input.getZipcode()); + private void setHttpParameters(AdresssucheOutput input) { + httpReq.setParameter(AdresssucheController.PARAM_STREET, input.getStreet()); + httpReq.setParameter(AdresssucheController.PARAM_MUNIPICALITY, input.getMunicipality()); + httpReq.setParameter(AdresssucheController.PARAM_NUMBER, input.getNumber()); + httpReq.setParameter(AdresssucheController.PARAM_VILLAGE, input.getVillage()); + httpReq.setParameter(AdresssucheController.PARAM_POSTLEITZAHL, input.getPostleitzahl()); + } @NotNull @@ -237,8 +283,13 @@ public class ReceiveAustrianResidenceGuiResponseTaskTest { } @NotNull - private UserInput setupUserInput() { - UserInput result = new UserInput(true, RandomStringUtils.randomAlphabetic(8), RandomStringUtils.randomAlphabetic(8), RandomStringUtils.randomAlphabetic(8)); + private AdresssucheOutput setupUserInput() { + AdresssucheOutput result = new AdresssucheOutput( + RandomStringUtils.randomAlphabetic(8), + RandomStringUtils.randomAlphabetic(8), + RandomStringUtils.randomAlphabetic(8), + RandomStringUtils.randomAlphabetic(8), + RandomStringUtils.randomAlphabetic(8)); setHttpParameters(result); return result; } -- cgit v1.2.3 From 00d30953a4da41d7c41e21ccffd5dc8db5e7bd79 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 8 Feb 2022 14:52:32 +0100 Subject: feature(matching): update process-definition for matching to optimize interaction between manual matching steps - return to 'otherLoginMethod' screen in any matching error case. - add change-language functionality --- .../src/main/resources/eIDAS.Authentication.process.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/resources') diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml index c9bdad94..05c42fce 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml @@ -35,6 +35,8 @@ + - + + - + from="receiveAustrianResidenceGuiResponseTask" to="generateOtherLoginMethodGuiTask" /> -- 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 +++++++++-- .../src/main/resources/eIDAS.Authentication.process.xml | 2 +- .../resources/messages/eidas_connector_message.properties | 2 ++ .../tasks/ReceiveMobilePhoneSignatureResponseTaskTest.java | 10 ++++++++-- 4 files changed, 20 insertions(+), 5 deletions(-) (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/resources') 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; } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml index 05c42fce..6ca21550 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eIDAS.Authentication.process.xml @@ -56,7 +56,7 @@ - diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties index f1bf2128..8d65d63f 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties @@ -26,6 +26,8 @@ module.eidasauth.matching.12=Matching failed, because ERnP response contains his module.eidasauth.matching.20=Matching be using residence information was canceled. Use another method for matching or create a new Austrian identity. module.eidasauth.matching.21=Matching be using residence information failed by missing input information. Use another method for matching or create a new Austrian identity. module.eidasauth.matching.22=Can not find an unique match by using residence information. Provide more or other data, use another method for matching, or create a new Austrian identity. +module.eidasauth.matching.23=Matching be using Austrian Identity was canceled. Use another method for matching or create a new Austrian identity. +module.eidasauth.matching.24=Matching be using Austrian Identity not possible. Use another method for matching or create a new Austrian identity. module.eidasauth.matching.99=Matching failed, because of an unexpected processing error. Reason: {0} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseTaskTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseTaskTest.java index d5400695..b9133392 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseTaskTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseTaskTest.java @@ -282,7 +282,10 @@ public class ReceiveMobilePhoneSignatureResponseTaskTest { task.execute(pendingReq, executionContext); - assertEquals("Transition To S16", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_GUI_QUERY_AUSTRIAN_RESIDENCE_TASK)); + assertEquals("Transition To S16", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.23", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); } @@ -326,7 +329,10 @@ public class ReceiveMobilePhoneSignatureResponseTaskTest { task.execute(pendingReq, executionContext); assertEquals("Next task", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); - assertEquals("advancedMatchingError flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.24", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + assertNull("no final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + } //TODO: implement new test that this test makes no sense any more -- 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 ++++++ .../src/main/resources/messages/eidas_connector_message.properties | 1 + .../eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java | 3 +++ 3 files changed, 10 insertions(+) (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/resources') diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java index f021fae9..96aa9c51 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java @@ -23,6 +23,8 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks; +import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED; +import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON; import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK; import java.util.Map; @@ -78,6 +80,8 @@ import lombok.extern.slf4j.Slf4j; @SuppressWarnings("PMD.TooManyStaticImports") public class AlternativeSearchTask extends AbstractAuthServletTask { + private static final String MSG_PROP_25 = "module.eidasauth.matching.25"; + private final RegisterSearchService registerSearchService; private final ICcSpecificEidProcessingService eidPostProcessor; @@ -200,6 +204,8 @@ public class AlternativeSearchTask extends AbstractAuthServletTask { log.trace("'step12CountrySpecificSearch' ends with no result. Forward to GUI based matching step ... "); log.debug("Forward to GUI based matching steps ... "); executionContext.put(TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK, true); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON, MSG_PROP_25); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); } else if (ccAltSearchResult.getResultCount() == 1) { log.debug("'step12CountrySpecificSearch' find single result. Starting KITT operation ... "); diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties index 8d65d63f..3942f30a 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties @@ -28,6 +28,7 @@ module.eidasauth.matching.21=Matching be using residence information failed by m module.eidasauth.matching.22=Can not find an unique match by using residence information. Provide more or other data, use another method for matching, or create a new Austrian identity. module.eidasauth.matching.23=Matching be using Austrian Identity was canceled. Use another method for matching or create a new Austrian identity. module.eidasauth.matching.24=Matching be using Austrian Identity not possible. Use another method for matching or create a new Austrian identity. +module.eidasauth.matching.25=Matching be using alternative eIDAS authentication not possible. Provide more or other data, use another method for matching, or create a new Austrian identity. module.eidasauth.matching.99=Matching failed, because of an unexpected processing error. Reason: {0} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java index 79b2532b..66807ee0 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java @@ -815,6 +815,9 @@ public class AlternativeSearchTaskWithRegisterTest { assertNull("final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); assertEquals("wrong executionContextFlag 'alternative eIDAS result'", true, executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.25", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); + // validate request -- 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 +++++-- .../main/resources/wsdl/ernp_client/openapi.json | 82 ++++++++++++++++++---- 2 files changed, 89 insertions(+), 18 deletions(-) (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/resources') 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. * diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json index fef86c1b..9e09240f 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/wsdl/ernp_client/openapi.json @@ -87,6 +87,11 @@ "schema" : { "$ref" : "#/components/schemas/PersonAendern" } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/PersonAendern" + } } } }, @@ -98,6 +103,11 @@ "schema" : { "$ref" : "#/components/schemas/AendernResponse" } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/AendernResponse" + } } } }, @@ -108,6 +118,11 @@ "schema" : { "$ref" : "#/components/schemas/Fault" } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } } } }, @@ -118,6 +133,11 @@ "schema" : { "$ref" : "#/components/schemas/Fault" } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } } } } @@ -165,6 +185,11 @@ "schema" : { "$ref" : "#/components/schemas/PersonAnlegen" } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/PersonAnlegen" + } } } }, @@ -176,6 +201,11 @@ "schema" : { "$ref" : "#/components/schemas/AnlegenResponse" } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/AnlegenResponse" + } } } }, @@ -186,6 +216,11 @@ "schema" : { "$ref" : "#/components/schemas/Fault" } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } } } }, @@ -196,6 +231,11 @@ "schema" : { "$ref" : "#/components/schemas/Fault" } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } } } } @@ -243,6 +283,11 @@ "schema" : { "$ref" : "#/components/schemas/PersonSuchen" } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/PersonSuchen" + } } } }, @@ -254,6 +299,11 @@ "schema" : { "$ref" : "#/components/schemas/SuchenResponse" } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/SuchenResponse" + } } } }, @@ -264,6 +314,11 @@ "schema" : { "$ref" : "#/components/schemas/Fault" } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } } } }, @@ -274,6 +329,11 @@ "schema" : { "$ref" : "#/components/schemas/Fault" } + }, + "application/xml" : { + "schema" : { + "$ref" : "#/components/schemas/Fault" + } } } } @@ -716,6 +776,7 @@ } }, "Eidas" : { + "required" : [ "art", "staatscode2", "wert" ], "type" : "object", "properties" : { "entityId" : { @@ -775,19 +836,6 @@ "xml" : { "name" : "Staatscode2" } - }, - "image" : { - "type" : "array", - "xml" : { - "name" : "Image" - }, - "items" : { - "type" : "string", - "format" : "byte", - "xml" : { - "name" : "Image" - } - } } } }, @@ -1836,7 +1884,13 @@ "$ref" : "#/components/schemas/SuchStaatsangehoerigkeit" }, "eidas" : { - "$ref" : "#/components/schemas/SuchEidas" + "type" : "array", + "xml" : { + "name" : "Eidas" + }, + "items" : { + "$ref" : "#/components/schemas/SuchEidas" + } } } }, -- cgit v1.2.3