From 0ae3e0f5675988d517fa414dd5c29c1475692013 Mon Sep 17 00:00:00 2001 From: terjenilssen Date: Wed, 27 Nov 2024 16:45:37 +0100 Subject: [PATCH 1/3] =?UTF-8?q?Implementert=20henting=20av=20epostadresser?= =?UTF-8?q?=20for=20avsender=20(defaultMshChannelId)=20og=20mottaker=20(Se?= =?UTF-8?q?rviceBinding=20=3D>=20CanReceive=20=3D>=20ChannelId,=20med=20mi?= =?UTF-8?q?ndre=20den=20er=20null,=20is=C3=A5fall=20defaultMshChannelId).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/kotlin/no/nav/emottak/cpa/CPAUtil.kt | 55 +++++++++++++++++-- .../main/kotlin/no/nav/emottak/cpa/Routes.kt | 17 ++++-- .../nav/emottak/cpa/CPARepoIntegrationTest.kt | 55 ++++++++++++++++++- .../no/nav/emottak/message/model/Payload.kt | 2 + 4 files changed, 116 insertions(+), 13 deletions(-) diff --git a/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/CPAUtil.kt b/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/CPAUtil.kt index 9d0bca71..467b3f1f 100644 --- a/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/CPAUtil.kt +++ b/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/CPAUtil.kt @@ -10,6 +10,7 @@ import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.Certificate import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.CollaborationProtocolAgreement import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.DeliveryChannel import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.DocExchange +import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.EndpointTypeType import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.PartyInfo import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.ProtocolType import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.Transport @@ -17,7 +18,7 @@ import org.w3._2000._09.xmldsig_.X509DataType import javax.xml.bind.JAXBElement fun PartyInfo.getCertificateForEncryption(): ByteArray { - // @TODO match role service action. ".first()" er ikke nokk + // @TODO match role service action. ".first()" er ikke nok val encryptionCert = this.collaborationRole.first().applicationCertificateRef.first().certId as Certificate return encryptionCert.getX509Certificate() } @@ -49,6 +50,23 @@ fun PartyInfo.getSendDeliveryChannel( } } +fun PartyInfo.getReceiveDeliveryChannel( + role: String, + service: String, + action: String +): DeliveryChannel { + return if (EBMS_SERVICE_URI == service) { + this.getDefaultDeliveryChannel(action) + } else { + val roles = this.collaborationRole.filter { it.role.name == role && it.serviceBinding.service.value == service } + val canReceive = roles.flatMap { it.serviceBinding.canReceive.filter { cs -> cs.thisPartyActionBinding.action == action } } + .also { if (it.size > 1) log.warn("Found more than 1 CanReceive (role='$role', service='$service', action='$action')") } + val channel = canReceive.firstOrNull()?.thisPartyActionBinding?.channelId + .also { if (it != null && it.size > 1) log.warn("Found more than 1 ChannelId (role='$role', service='$service', action='$action')") } + return if (channel != null) channel.first().value as DeliveryChannel else this.getDefaultDeliveryChannel(action) + } +} + private fun PartyInfo.getDefaultDeliveryChannel( action: String ): DeliveryChannel { @@ -56,6 +74,33 @@ private fun PartyInfo.getDefaultDeliveryChannel( ?: this.defaultMshChannelId as DeliveryChannel } +fun PartyInfo.getReceiveEmailAddress( + role: String, + service: String, + action: String +): String? { + val deliveryChannel = this.getReceiveDeliveryChannel(role, service, action) + return getReceiverEmailAddress(deliveryChannel) +} + +fun PartyInfo.getSignalEmailAddress( + action: String +): String? { + val deliveryChannel = this.getDefaultDeliveryChannel(action) + return getReceiverEmailAddress(deliveryChannel) +} + +private fun getReceiverEmailAddress(deliveryChannel: DeliveryChannel): String? { + val transport = deliveryChannel.getTransport() // SecurityException + val transportReceiver = transport.transportReceiver + if (transportReceiver == null || transportReceiver.transportProtocol.value != "SMTP") return null + val endpoints = transportReceiver.endpoint + .also { if (it.size > 1) log.warn("Found more than 1 email address (transportId='${transport.transportId}')") } + val allPurpose = endpoints.filter { endpoint -> endpoint.type == EndpointTypeType.ALL_PURPOSE } + return allPurpose.firstOrNull()?.uri ?: endpoints.firstOrNull()?.uri + .also { if (endpoints.size > 0) log.warn("Did not find an allPurpose email address (transportId='${transport.transportId}') - using first() instead (${endpoints[0].type})") } +} + fun DeliveryChannel.getSigningCertificate(): Certificate { val docExchange = this.docExchangeId as DocExchange? ?: throw SecurityException("Fant ikke DocExchange") return if ( @@ -69,14 +114,14 @@ fun DeliveryChannel.getSigningCertificate(): Certificate { } } +fun DeliveryChannel.getTransport(): Transport = this.transportId as Transport? ?: throw SecurityException("Fant ikke transportkanal") + fun DeliveryChannel.getSenderTransportProtocolType(): ProtocolType { - val transport = this.transportId as Transport? ?: throw SecurityException("Fant ikke transportkanal") - return transport.transportSender?.transportProtocol ?: throw SecurityException("Fant ikke transportkanal") + return this.getTransport().transportSender?.transportProtocol ?: throw SecurityException("Fant ikke transportkanal") } fun DeliveryChannel.getReceiverTransportProtocolType(): ProtocolType { - val transport = this.transportId as Transport? ?: throw CpaValidationException("Fant ikke transportkanal") - return transport.transportReceiver?.transportProtocol ?: throw CpaValidationException("Fant ikke transportkanal") + return this.getTransport().transportReceiver?.transportProtocol ?: throw CpaValidationException("Fant ikke transportkanal") } fun DeliveryChannel.getSignatureAlgorithm(): String { diff --git a/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt b/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt index cb4216e5..44f3a026 100644 --- a/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt +++ b/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt @@ -41,6 +41,7 @@ import no.nav.emottak.util.getEnvVar import no.nav.emottak.util.marker import no.nav.security.token.support.v2.TokenValidationContextPrincipal import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.CollaborationProtocolAgreement +import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.PartyInfo import java.util.Date fun Route.whoAmI(): Route = get("/whoami") { @@ -182,21 +183,25 @@ fun Route.validateCpa(cpaRepository: CPARepository) = post("/cpa/validate/{$CONT val cpa = cpaRepository.findCpa(validateRequest.cpaId) ?: throw NotFoundException("Fant ikke CPA (${validateRequest.cpaId})") cpa.validate(validateRequest) // Delivery Failure - val partyInfo = cpa.getPartyInfoByTypeAndID(validateRequest.addressing.from.partyId) // Delivery Failure - + val fromParty = cpa.getPartyInfoByTypeAndID(validateRequest.addressing.from.partyId) // Delivery Failure val encryptionCertificate = when (validateRequest.direction) { - IN -> partyInfo.getCertificateForEncryption() // Security Failure + IN -> fromParty.getCertificateForEncryption() // Security Failure OUT -> cpa .getPartyInfoByTypeAndID(validateRequest.addressing.to.partyId) .getCertificateForEncryption() } - val signingCertificate = partyInfo.getCertificateForSignatureValidation( + val signingCertificate = fromParty.getCertificateForSignatureValidation( validateRequest.addressing.from.role, validateRequest.addressing.service, validateRequest.addressing.action ) // Security Failure + + val signalEmail = fromParty.getSignalEmailAddress(validateRequest.addressing.action) + val toParty = cpa.getPartyInfoByTypeAndID(validateRequest.addressing.to.partyId) // Delivery Failure + val receiverEmail = toParty.getReceiveEmailAddress(validateRequest.addressing.to.role, validateRequest.addressing.service, validateRequest.addressing.action) + runCatching { createX509Certificate(signingCertificate.certificate).validate() }.onFailure { @@ -215,7 +220,9 @@ fun Route.validateCpa(cpaRepository: CPARepository) = post("/cpa/validate/{$CONT validateRequest.addressing.service, validateRequest.addressing.action ) - ) + ), + signalEmail, + receiverEmail ) ) } catch (ebmsEx: EbmsException) { diff --git a/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt b/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt index 93d20a41..bb593abb 100644 --- a/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt +++ b/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt @@ -29,15 +29,19 @@ import no.nav.emottak.cpa.auth.AuthConfig import no.nav.emottak.cpa.databasetest.PostgresTest import no.nav.emottak.message.model.Addressing import no.nav.emottak.message.model.Direction.IN +import no.nav.emottak.message.model.ErrorCode import no.nav.emottak.message.model.Party import no.nav.emottak.message.model.PartyId import no.nav.emottak.message.model.SignatureDetails import no.nav.emottak.message.model.SignatureDetailsRequest import no.nav.emottak.message.model.ValidationRequest +import no.nav.emottak.message.model.ValidationResult import no.nav.emottak.util.getEnvVar import no.nav.security.mock.oauth2.MockOAuth2Server import org.apache.commons.lang3.StringUtils import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.CollaborationProtocolAgreement @@ -109,11 +113,16 @@ class CPARepoIntegrationTest : PostgresTest() { contentType(Json) } - println(String(response.readBytes())) + // println(String(response.readBytes())) + val validationResult = response.body() + assertNotNull(validationResult) + + assertEquals(validationResult.signalEmailAddress, "mailto://TEST_A1_Haugerud_t1@edi.nhn.no") + assertNull(validationResult.receiverEmailAddress) // Channel-protokoll er HTTP } @Test - fun `Byt from og to - role service action matcher ikke`() = cpaRepoTestApp { + fun `Bytt from og to - role service action matcher ikke`() = cpaRepoTestApp { val httpClient = createClient { install(ContentNegotiation) { json() @@ -137,7 +146,47 @@ class CPARepoIntegrationTest : PostgresTest() { contentType(Json) } - println(String(response.readBytes())) + // println(String(response.readBytes())) + val validationResult = response.body() + assertNotNull(validationResult) + + assertNotNull(validationResult.error) + assertEquals(validationResult.error?.size, 1) + assertEquals(validationResult.error?.first()?.code, ErrorCode.DELIVERY_FAILURE) + assertEquals(validationResult.error?.first()?.descriptionText, "Action EgenandelForesporsel matcher ikke service HarBorgerEgenandelFritak for sending party NAV") + } + + @Test + fun `Test hente epost`() = cpaRepoTestApp { + val httpClient = createClient { + install(ContentNegotiation) { + json() + } + } + + val validationRequest = ValidationRequest( + IN, + "e17eb03e-9e43-43fb-874c-1fde9a28c308", + "1234", + "nav:qass:31162", + Addressing( + Party(listOf(PartyId("HER", "79768")), "KontrollUtbetaler"), + Party(listOf(PartyId("HER", "8090595")), "Utleverer"), + "OppgjorsKontroll", + "Oppgjorskrav" + ) + ) + val response = httpClient.post("/cpa/validate/121212") { + setBody(validationRequest) + contentType(Json) + } + + // println(String(response.readBytes())) + val validationResult = response.body() + assertNotNull(validationResult) + + assertEquals(validationResult.signalEmailAddress, "mailto://TEST_A1_Haugerud_t1@edi.nhn.no") + assertEquals(validationResult.receiverEmailAddress, "mailto://mottak-qass@test-es.nav.no") } @Test diff --git a/ebxml-processing-model/src/main/kotlin/no/nav/emottak/message/model/Payload.kt b/ebxml-processing-model/src/main/kotlin/no/nav/emottak/message/model/Payload.kt index e6c44645..a533d072 100644 --- a/ebxml-processing-model/src/main/kotlin/no/nav/emottak/message/model/Payload.kt +++ b/ebxml-processing-model/src/main/kotlin/no/nav/emottak/message/model/Payload.kt @@ -86,6 +86,8 @@ data class ValidationRequest( data class ValidationResult( val ebmsProcessing: EbmsProcessing? = null, val payloadProcessing: PayloadProcessing? = null, + val signalEmailAddress: String? = null, + val receiverEmailAddress: String? = null, val error: List? = null ) { From 3b56d103783fa31c96d69076e9f4411088c44e02 Mon Sep 17 00:00:00 2001 From: terjenilssen Date: Wed, 27 Nov 2024 16:53:36 +0100 Subject: [PATCH 2/3] Ryddet litt i imports og warnings. --- cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt | 1 - .../kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt | 9 ++------- .../main/kotlin/no/nav/emottak/message/model/Payload.kt | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt b/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt index 44f3a026..8fb76ff9 100644 --- a/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt +++ b/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt @@ -41,7 +41,6 @@ import no.nav.emottak.util.getEnvVar import no.nav.emottak.util.marker import no.nav.security.token.support.v2.TokenValidationContextPrincipal import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.CollaborationProtocolAgreement -import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.PartyInfo import java.util.Date fun Route.whoAmI(): Route = get("/whoami") { diff --git a/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt b/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt index bb593abb..febd5834 100644 --- a/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt +++ b/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt @@ -16,7 +16,6 @@ import io.ktor.client.request.headers import io.ktor.client.request.post import io.ktor.client.request.setBody import io.ktor.client.statement.bodyAsText -import io.ktor.client.statement.readBytes import io.ktor.http.ContentType.Application.Json import io.ktor.http.HttpStatusCode import io.ktor.http.contentType @@ -39,17 +38,16 @@ import no.nav.emottak.message.model.ValidationResult import no.nav.emottak.util.getEnvVar import no.nav.security.mock.oauth2.MockOAuth2Server import org.apache.commons.lang3.StringUtils -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertNotNull -import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.CollaborationProtocolAgreement import java.time.Instant import java.time.temporal.ChronoUnit import kotlin.test.assertContains +import kotlin.test.assertEquals import kotlin.test.assertNotEquals import kotlin.test.assertNotNull +import kotlin.test.assertNull import kotlin.test.assertTrue @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -113,7 +111,6 @@ class CPARepoIntegrationTest : PostgresTest() { contentType(Json) } - // println(String(response.readBytes())) val validationResult = response.body() assertNotNull(validationResult) @@ -146,7 +143,6 @@ class CPARepoIntegrationTest : PostgresTest() { contentType(Json) } - // println(String(response.readBytes())) val validationResult = response.body() assertNotNull(validationResult) @@ -181,7 +177,6 @@ class CPARepoIntegrationTest : PostgresTest() { contentType(Json) } - // println(String(response.readBytes())) val validationResult = response.body() assertNotNull(validationResult) diff --git a/ebxml-processing-model/src/main/kotlin/no/nav/emottak/message/model/Payload.kt b/ebxml-processing-model/src/main/kotlin/no/nav/emottak/message/model/Payload.kt index a533d072..dfea0927 100644 --- a/ebxml-processing-model/src/main/kotlin/no/nav/emottak/message/model/Payload.kt +++ b/ebxml-processing-model/src/main/kotlin/no/nav/emottak/message/model/Payload.kt @@ -222,6 +222,6 @@ fun List.asErro errorList.id // "May be used for error tracking" errorList.highestSeverity = this.sortedBy { it.severity == SeverityType.ERROR }.first().severity - errorList.isMustUnderstand = true; // Alltid + errorList.isMustUnderstand = true // Alltid return errorList } From daf3260ac62f45e06cf56160d9bd32e42a17ff28 Mon Sep 17 00:00:00 2001 From: terjenilssen Date: Fri, 29 Nov 2024 16:21:30 +0100 Subject: [PATCH 3/3] =?UTF-8?q?Endret=20responsen=20til=20=C3=A5=20returne?= =?UTF-8?q?re=20en=20liste=20av=20epostadresser=20-=20i=20tilfelle=20Trans?= =?UTF-8?q?port-taggen=20i=20CPA=20har=20angitt=20flere.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/kotlin/no/nav/emottak/cpa/CPAUtil.kt | 59 +- .../main/kotlin/no/nav/emottak/cpa/Routes.kt | 8 +- .../nav/emottak/cpa/CPARepoIntegrationTest.kt | 82 ++- .../databasetest/setup/PostgresTestSetup.kt | 2 +- ...ultipleChannels_and_multiple_endpoints.xml | 599 ++++++++++++++++++ .../no/nav/emottak/message/model/Payload.kt | 11 +- 6 files changed, 719 insertions(+), 42 deletions(-) create mode 100644 cpa-repo/src/test/resources/cpa/nav-qass-31162_multipleChannels_and_multiple_endpoints.xml diff --git a/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/CPAUtil.kt b/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/CPAUtil.kt index 467b3f1f..4d4e1cc4 100644 --- a/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/CPAUtil.kt +++ b/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/CPAUtil.kt @@ -4,13 +4,14 @@ import no.nav.emottak.cpa.feil.CpaValidationException import no.nav.emottak.cpa.feil.SecurityException import no.nav.emottak.message.ebxml.EbXMLConstants.EBMS_SERVICE_URI import no.nav.emottak.message.ebxml.PartyTypeEnum +import no.nav.emottak.message.model.EmailAddress import no.nav.emottak.message.model.PartyId import no.nav.emottak.message.model.SignatureDetails +import no.nav.emottak.message.model.ValidationRequest import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.Certificate import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.CollaborationProtocolAgreement import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.DeliveryChannel import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.DocExchange -import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.EndpointTypeType import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.PartyInfo import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.ProtocolType import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.Transport @@ -50,20 +51,19 @@ fun PartyInfo.getSendDeliveryChannel( } } -fun PartyInfo.getReceiveDeliveryChannel( +fun PartyInfo.getReceiveDeliveryChannels( role: String, service: String, action: String -): DeliveryChannel { +): List { return if (EBMS_SERVICE_URI == service) { - this.getDefaultDeliveryChannel(action) + listOf(this.getDefaultDeliveryChannel(action)) } else { val roles = this.collaborationRole.filter { it.role.name == role && it.serviceBinding.service.value == service } val canReceive = roles.flatMap { it.serviceBinding.canReceive.filter { cs -> cs.thisPartyActionBinding.action == action } } .also { if (it.size > 1) log.warn("Found more than 1 CanReceive (role='$role', service='$service', action='$action')") } - val channel = canReceive.firstOrNull()?.thisPartyActionBinding?.channelId - .also { if (it != null && it.size > 1) log.warn("Found more than 1 ChannelId (role='$role', service='$service', action='$action')") } - return if (channel != null) channel.first().value as DeliveryChannel else this.getDefaultDeliveryChannel(action) + val channels = canReceive.firstOrNull()?.thisPartyActionBinding?.channelId + return channels?.map { it.value as DeliveryChannel } ?: emptyList() } } @@ -74,31 +74,30 @@ private fun PartyInfo.getDefaultDeliveryChannel( ?: this.defaultMshChannelId as DeliveryChannel } -fun PartyInfo.getReceiveEmailAddress( - role: String, - service: String, - action: String -): String? { - val deliveryChannel = this.getReceiveDeliveryChannel(role, service, action) - return getReceiverEmailAddress(deliveryChannel) +fun PartyInfo.getReceiveEmailAddress(validateRequest: ValidationRequest): List { + val deliveryChannels = this.getReceiveDeliveryChannels(validateRequest.addressing.to.role, validateRequest.addressing.service, validateRequest.addressing.action) + return getReceiverEmailAddress(validateRequest, validateRequest.addressing.to.role, deliveryChannels) } -fun PartyInfo.getSignalEmailAddress( - action: String -): String? { - val deliveryChannel = this.getDefaultDeliveryChannel(action) - return getReceiverEmailAddress(deliveryChannel) -} - -private fun getReceiverEmailAddress(deliveryChannel: DeliveryChannel): String? { - val transport = deliveryChannel.getTransport() // SecurityException - val transportReceiver = transport.transportReceiver - if (transportReceiver == null || transportReceiver.transportProtocol.value != "SMTP") return null - val endpoints = transportReceiver.endpoint - .also { if (it.size > 1) log.warn("Found more than 1 email address (transportId='${transport.transportId}')") } - val allPurpose = endpoints.filter { endpoint -> endpoint.type == EndpointTypeType.ALL_PURPOSE } - return allPurpose.firstOrNull()?.uri ?: endpoints.firstOrNull()?.uri - .also { if (endpoints.size > 0) log.warn("Did not find an allPurpose email address (transportId='${transport.transportId}') - using first() instead (${endpoints[0].type})") } +fun PartyInfo.getSignalEmailAddress(validateRequest: ValidationRequest): List { + val deliveryChannels = listOf(this.getDefaultDeliveryChannel(validateRequest.addressing.action)) + return getReceiverEmailAddress(validateRequest, validateRequest.addressing.from.role, deliveryChannels) +} + +private fun getReceiverEmailAddress(req: ValidationRequest, role: String, deliveryChannels: List): List { + // TODO: I stedet for å logge ut warning: Hent heller ut alle epostadresser fra alle SMTP-kanaler. + val smtpChannel = deliveryChannels.filter { + it.getTransport().transportReceiver?.transportProtocol?.value == "SMTP" + }.also { + if (it.size > 1) { + log.warn( + "Found more than 1 SMTP Channels (cpaId: '${req.cpaId}', role='$role', service='${req.addressing.service}', action='${req.addressing.action}', transportIds: ${ + it.map { channel -> "'${(channel.transportId as Transport).transportId}'" } + }) - using the first one." + ) + } + }.firstOrNull() + return smtpChannel?.getTransport()?.transportReceiver?.endpoint?.map { EmailAddress(it.uri, it.type!!) } ?: emptyList() } fun DeliveryChannel.getSigningCertificate(): Certificate { diff --git a/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt b/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt index 8fb76ff9..5b419bf4 100644 --- a/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt +++ b/cpa-repo/src/main/kotlin/no/nav/emottak/cpa/Routes.kt @@ -197,9 +197,9 @@ fun Route.validateCpa(cpaRepository: CPARepository) = post("/cpa/validate/{$CONT validateRequest.addressing.action ) // Security Failure - val signalEmail = fromParty.getSignalEmailAddress(validateRequest.addressing.action) + val signalEmails = fromParty.getSignalEmailAddress(validateRequest) val toParty = cpa.getPartyInfoByTypeAndID(validateRequest.addressing.to.partyId) // Delivery Failure - val receiverEmail = toParty.getReceiveEmailAddress(validateRequest.addressing.to.role, validateRequest.addressing.service, validateRequest.addressing.action) + val receiverEmails = toParty.getReceiveEmailAddress(validateRequest) runCatching { createX509Certificate(signingCertificate.certificate).validate() @@ -220,8 +220,8 @@ fun Route.validateCpa(cpaRepository: CPARepository) = post("/cpa/validate/{$CONT validateRequest.addressing.action ) ), - signalEmail, - receiverEmail + signalEmails, + receiverEmails ) ) } catch (ebmsEx: EbmsException) { diff --git a/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt b/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt index febd5834..0aaff10e 100644 --- a/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt +++ b/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/CPARepoIntegrationTest.kt @@ -28,6 +28,7 @@ import no.nav.emottak.cpa.auth.AuthConfig import no.nav.emottak.cpa.databasetest.PostgresTest import no.nav.emottak.message.model.Addressing import no.nav.emottak.message.model.Direction.IN +import no.nav.emottak.message.model.EmailAddress import no.nav.emottak.message.model.ErrorCode import no.nav.emottak.message.model.Party import no.nav.emottak.message.model.PartyId @@ -41,13 +42,13 @@ import org.apache.commons.lang3.StringUtils import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.CollaborationProtocolAgreement +import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.EndpointTypeType import java.time.Instant import java.time.temporal.ChronoUnit import kotlin.test.assertContains import kotlin.test.assertEquals import kotlin.test.assertNotEquals import kotlin.test.assertNotNull -import kotlin.test.assertNull import kotlin.test.assertTrue @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -114,8 +115,9 @@ class CPARepoIntegrationTest : PostgresTest() { val validationResult = response.body() assertNotNull(validationResult) - assertEquals(validationResult.signalEmailAddress, "mailto://TEST_A1_Haugerud_t1@edi.nhn.no") - assertNull(validationResult.receiverEmailAddress) // Channel-protokoll er HTTP + assertEquals(1, validationResult.signalEmailAddress.size) + assertEquals("mailto://TEST_A1_Haugerud_t1@edi.nhn.no", validationResult.signalEmailAddress.first().emailAddress) + assertTrue(validationResult.receiverEmailAddress.isEmpty()) // Channel-protokoll er HTTP } @Test @@ -180,8 +182,78 @@ class CPARepoIntegrationTest : PostgresTest() { val validationResult = response.body() assertNotNull(validationResult) - assertEquals(validationResult.signalEmailAddress, "mailto://TEST_A1_Haugerud_t1@edi.nhn.no") - assertEquals(validationResult.receiverEmailAddress, "mailto://mottak-qass@test-es.nav.no") + assertEquals(1, validationResult.signalEmailAddress.size) + assertEquals("mailto://TEST_A1_Haugerud_t1@edi.nhn.no", validationResult.signalEmailAddress.first().emailAddress) + assertEquals(1, validationResult.receiverEmailAddress.size) + assertEquals("mailto://mottak-qass@test-es.nav.no", validationResult.receiverEmailAddress.first().emailAddress) + } + + @Test + fun `Test hente epost - flere ChannelId'er og flere endpoints (epostadresser)`() = cpaRepoTestApp { + val httpClient = createClient { + install(ContentNegotiation) { + json() + } + } + + val validationRequest = ValidationRequest( + IN, + "e17eb03e-9e43-43fb-874c-1fde9a28c308", + "1234", + "multiple_channels_and_multiple_endpoints", + Addressing( + Party(listOf(PartyId("HER", "79768")), "KontrollUtbetaler"), + Party(listOf(PartyId("HER", "8090595")), "Utleverer"), + "OppgjorsKontroll", + "Oppgjorskrav" + ) + ) + val response = httpClient.post("/cpa/validate/121212") { + setBody(validationRequest) + contentType(Json) + } + + val validationResult = response.body() + assertNotNull(validationResult) + + assertEquals(2, validationResult.signalEmailAddress.size) + assertContains( + validationResult.signalEmailAddress, + EmailAddress("mailto://allPurpose@edi.nhn.no", EndpointTypeType.ALL_PURPOSE), + "''signalEmailAddress'' inneholdt IKKE allPurpose-epostadresse" + ) + assertContains( + validationResult.signalEmailAddress, + EmailAddress("mailto://error@edi.nhn.no", EndpointTypeType.ERROR), + "''signalEmailAddress'' inneholdt IKKE error-epostadresse" + ) + + assertEquals(4, validationResult.receiverEmailAddress.size) + /*assertContains( + validationResult.receiverEmailAddress, + EmailAddress("mailto://allPurpose@test-es.nav.no", EndpointTypeType.ALL_PURPOSE), + "''receiverEmailAddress'' inneholdt IKKE allPurpose-epostadresse" + )*/ + assertContains( + validationResult.receiverEmailAddress, + EmailAddress("mailto://request@test-es.nav.no", EndpointTypeType.REQUEST), + "''receiverEmailAddress'' inneholdt IKKE request-epostadresse" + ) + assertContains( + validationResult.receiverEmailAddress, + EmailAddress("mailto://response@test-es.nav.no", EndpointTypeType.RESPONSE), + "''receiverEmailAddress'' inneholdt IKKE response-epostadresse" + ) + assertContains( + validationResult.receiverEmailAddress, + EmailAddress("mailto://error@test-es.nav.no", EndpointTypeType.ERROR), + "''receiverEmailAddress'' inneholdt IKKE error-epostadresse" + ) + assertContains( + validationResult.receiverEmailAddress, + EmailAddress("mailto://login@test-es.nav.no", EndpointTypeType.LOGIN), + "''receiverEmailAddress'' inneholdt IKKE login-epostadresse" + ) } @Test diff --git a/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/databasetest/setup/PostgresTestSetup.kt b/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/databasetest/setup/PostgresTestSetup.kt index 45276e5f..ac167cdb 100644 --- a/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/databasetest/setup/PostgresTestSetup.kt +++ b/cpa-repo/src/test/kotlin/no/nav/emottak/cpa/databasetest/setup/PostgresTestSetup.kt @@ -69,7 +69,7 @@ class PostgresTestSetup { tables.forEach { it.deleteAll() } } - val cpasToInsert = listOf("nav-qass-35065.xml", "nav-qass-31162.xml") + val cpasToInsert = listOf("nav-qass-35065.xml", "nav-qass-31162.xml", "nav-qass-31162_multipleChannels_and_multiple_endpoints.xml") transaction(postgres.db) { cpasToInsert.forEach { cpaToInsert -> CPA.insert { diff --git a/cpa-repo/src/test/resources/cpa/nav-qass-31162_multipleChannels_and_multiple_endpoints.xml b/cpa-repo/src/test/resources/cpa/nav-qass-31162_multipleChannels_and_multiple_endpoints.xml new file mode 100644 index 00000000..f62ee473 --- /dev/null +++ b/cpa-repo/src/test/resources/cpa/nav-qass-31162_multipleChannels_and_multiple_endpoints.xml @@ -0,0 +1,599 @@ + + + + 2023-09-26T11:19:19.000Z + 2025-09-07T21:59:00.000Z + + 8090595 + 984886136 + 984886136 + + + + + + + OppgjorsKontroll + + + + Partner_channelSMTP0_partner + + NAV_Oppgjorskrav6 + + + + + Partner_channelSMTP0_partner + + NAV_A076 + + + + + Partner_channelSMTP0_partner + + NAV_Oppgjorsresultat6 + + + + + Partner_channelSMTP0_partner + + NAV_Utbetaling6 + + + + + Partner_channelSMTP0_partner + + NAV_Bekreftelse6 + + + + + + + + + HarBorgerEgenandelFritak + + + + Partner_channelHTTP1_partner + + NAV_EgenandelFritak_EgenandelForesporsel + + + + + Partner_channelHTTP1_partner + + NAV_EgenandelFritak_Svar + + + + + Partner_channelHTTP1_partner + + NAV_EgenandelFritak_Avvisning + + + + + + + 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 + + + + + + + + + + + + + SMTP + + + SMTP + + + + + + + HTTP + + SSL + + + + HTTP + + + + + + + 4 + PT240M + NotGuaranteed + + P2D + + http://www.w3.org/2000/09/xmldsig# + http://www.w3.org/2001/04/xmlenc#sha256 + http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 + + + + + + 4 + PT240M + NotGuaranteed + + P2D + + http://www.w3.org/2000/09/xmldsig# + http://www.w3.org/2001/04/xmlenc#sha256 + http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 + + + + + + + http://www.w3.org/2000/09/xmldsig# + http://www.w3.org/2001/04/xmlenc#sha256 + http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 + + + + + + + http://www.w3.org/2000/09/xmldsig# + + http://www.w3.org/2001/04/xmlenc#sha256 + http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 + + + + + + 79768 + 889640782 + 889640782 + + + + + + + OppgjorsKontroll + + + + NAV_asyncSMTPChannelA2 + + Partner_Oppgjorsresultat62 + + + + + NAV_asyncSMTPChannelA2 + + Partner_Utbetaling63 + + + + + NAV_asyncSMTPChannelA2 + + Partner_Bekreftelse64 + + + + + NAV_SyncHttpChannelB1 + NAV_asyncSMTPChannelA2 + NAV_asyncSMTPChannelA3 + + Partner_Oppgjorskrav60 + + + + + NAV_asyncSMTPChannelA2 + + Partner_A0761 + + + + + + + + + HarBorgerEgenandelFritak + + + + NAV_SyncHttpChannelB1 + + Partner_EgenandelFritak_Svar1 + + + + + NAV_SyncHttpChannelB1 + + Partner_EgenandelFritak_Avvisning2 + + + + + NAV_SyncHttpChannelB1 + + Partner_EgenandelFritak_EgenandelForesporsel0 + + + + + + + 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 + + + + + + + + + + + + + + + + SMTP + + + SMTP + + + + + + + + + SMTP + + + SMTP + + + + + + HTTP + + SSL + + + + HTTP + + + SSL + + + + + + + + 4 + PT240M + NotGuaranteed + + P2D + + http://www.w3.org/2000/09/xmldsig# + http://www.w3.org/2001/04/xmlenc#sha256 + http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 + + + + + + 4 + PT240M + NotGuaranteed + + P2D + + http://www.w3.org/2000/09/xmldsig# + http://www.w3.org/2001/04/xmlenc#sha256 + http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 + + + + + + + + http://www.w3.org/2000/09/xmldsig# + + http://www.w3.org/2001/04/xmlenc#sha256 + http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 + + + + + + http://www.w3.org/2000/09/xmldsig# + http://www.w3.org/2001/04/xmlenc#sha256 + http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 + + + + + + http://www.oasis-open.org/committees/ebxml-msg/schema + + + http://www.kith.no/xmlstds/apprec/2004-11-21 + + + http://www.kith.no/xmlstds/msghead/2006-05-24 + http://www.kith.no/xmlstds/eresept/m18/2013-04-16 + + + http://www.kith.no/xmlstds/msghead/2006-05-24 + http://www.kith.no/xmlstds/eresept/m22/2006-10-06 + + + http://www.kith.no/xmlstds/msghead/2006-05-24 + http://www.kith.no/xmlstds/eresept/m23/2006-10-06 + + + http://www.kith.no/xmlstds/msghead/2006-05-24 + http://www.kith.no/xmlstds/nav/egenandel/2010-02-01 + + + http://www.kith.no/xmlstds/msghead/2006-05-24 + http://www.kith.no/xmlstds/nav/egenandel/2010-02-01 + + + http://www.oasis-open.org/committees/ebxml-msg/schema + + + http://www.kith.no/xmlstds/apprec/2004-11-21 + + + http://www.kith.no/xmlstds/msghead/2006-05-24 + http://www.kith.no/xmlstds/eresept/m18/2013-04-16 + + + http://www.kith.no/xmlstds/msghead/2006-05-24 + http://www.kith.no/xmlstds/eresept/m22/2006-10-06 + + + http://www.kith.no/xmlstds/msghead/2006-05-24 + http://www.kith.no/xmlstds/eresept/m23/2006-10-06 + + + http://www.kith.no/xmlstds/msghead/2006-05-24 + http://www.kith.no/xmlstds/nav/egenandel/2010-02-01 + + + http://www.kith.no/xmlstds/msghead/2006-05-24 + http://www.kith.no/xmlstds/nav/egenandel/2010-02-01 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ebxml-processing-model/src/main/kotlin/no/nav/emottak/message/model/Payload.kt b/ebxml-processing-model/src/main/kotlin/no/nav/emottak/message/model/Payload.kt index dfea0927..3f38b92c 100644 --- a/ebxml-processing-model/src/main/kotlin/no/nav/emottak/message/model/Payload.kt +++ b/ebxml-processing-model/src/main/kotlin/no/nav/emottak/message/model/Payload.kt @@ -2,6 +2,7 @@ package no.nav.emottak.message.model import kotlinx.serialization.Serializable import no.nav.emottak.message.util.createUniqueMimeMessageId +import org.oasis_open.committees.ebxml_cppa.schema.cpp_cpa_2_0.EndpointTypeType import org.oasis_open.committees.ebxml_msg.schema.msg_header_2_0.Description import org.oasis_open.committees.ebxml_msg.schema.msg_header_2_0.ErrorList import org.oasis_open.committees.ebxml_msg.schema.msg_header_2_0.SeverityType @@ -86,8 +87,8 @@ data class ValidationRequest( data class ValidationResult( val ebmsProcessing: EbmsProcessing? = null, val payloadProcessing: PayloadProcessing? = null, - val signalEmailAddress: String? = null, - val receiverEmailAddress: String? = null, + val signalEmailAddress: List = emptyList(), + val receiverEmailAddress: List = emptyList(), val error: List? = null ) { @@ -154,6 +155,12 @@ data class PartyId( val value: String, ) +@Serializable +data class EmailAddress( + val emailAddress: String, + var type: EndpointTypeType, +) + @Serializable data class Payload(val bytes: ByteArray, val contentType: String, val contentId: String = "att-${createUniqueMimeMessageId()}", val signedOf :String? = null)