Skip to content

Commit 31a61b6

Browse files
committed
merge
2 parents 99b1d03 + eb8efdd commit 31a61b6

File tree

15 files changed

+112
-38
lines changed

15 files changed

+112
-38
lines changed

.github/workflows/jobs.yaml

+7-7
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ jobs:
2121
password: ${{ secrets.GITHUB_TOKEN }}
2222
- name: "Pull push docker image"
2323
run: "docker pull ghcr.io/curl/curl-container/curl:master && docker tag ghcr.io/curl/curl-container/curl:master ghcr.io/${{ github.repository }}/curl:master && docker push ghcr.io/${{ github.repository }}/curl:master"
24-
- name: "Naisjob Readmail"
25-
uses: "nais/deploy/actions/deploy@v1"
26-
env:
27-
APIKEY: "${{ secrets.NAIS_DEPLOY_APIKEY }}"
28-
CLUSTER: "dev-fss"
29-
RESOURCE: ".nais/naisjob-readmail.yaml"
30-
IMAGE: "ghcr.io/${{ github.repository }}/curl:master"
24+
#- name: "Naisjob Readmail"
25+
# uses: "nais/deploy/actions/deploy@v1"
26+
# env:
27+
# APIKEY: "${{ secrets.NAIS_DEPLOY_APIKEY }}"
28+
# CLUSTER: "dev-fss"
29+
# RESOURCE: ".nais/naisjob-readmail.yaml"
30+
# IMAGE: "ghcr.io/${{ github.repository }}/curl:master"
3131
- name: "Naisjob CpaSync"
3232
uses: "nais/deploy/actions/deploy@v1"
3333
env:

.nais/ebms-send-in-prod.yaml

+15
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@ spec:
1111
enabled: true
1212
webproxy: true
1313
image: {{image}}
14+
liveness:
15+
path: "/internal/health/liveness"
16+
port: 8080
17+
initialDelay: 30
18+
timeout: 10
19+
failureThreshold: 10
20+
readiness:
21+
path: "/internal/health/readiness"
22+
port: 8080
23+
initialDelay: 30
24+
timeout: 10
25+
failureThreshold: 10
26+
prometheus:
27+
enabled: true
28+
path: /prometheus
1429
replicas:
1530
min: 1
1631
max: 1

.nais/ebms-send-in.yaml

+15
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@ spec:
1111
enabled: true
1212
webproxy: true
1313
image: {{image}}
14+
liveness:
15+
path: "/internal/health/liveness"
16+
port: 8080
17+
initialDelay: 30
18+
timeout: 10
19+
failureThreshold: 10
20+
readiness:
21+
path: "/internal/health/readiness"
22+
port: 8080
23+
initialDelay: 30
24+
timeout: 10
25+
failureThreshold: 10
26+
prometheus:
27+
enabled: true
28+
path: /prometheus
1429
replicas:
1530
min: 2
1631
max: 6

cpa-repo/src/main/kotlin/no/nav/emottak/cpa/validation/SertifikatValidering.kt

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class SertifikatValidering(
9191
try {
9292
builder.build(pkixParams) as PKIXCertPathBuilderResult
9393
} catch (e: CertPathBuilderException) {
94+
log.warn("Sertifikatvalidering feilet <${certificate.serialNumber}> <${certificate.subjectX500Principal.name}> utstedt av <${certificate.issuerX500Principal.name}>", e)
9495
throw CertificateValidationException("Sertifikatvalidering feilet for sertifikat utstedt av <${certificate.issuerX500Principal.name}>", e)
9596
}
9697
}

cpa-repo/src/main/kotlin/no/nav/emottak/cpa/validation/TrustStoreExt.kt

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ import no.nav.emottak.util.isSelfSigned
55
import java.security.cert.X509Certificate
66

77
fun KeyStore.getTrustedRootCerts(): Set<X509Certificate> {
8-
return this.getPublicCertificates().values.filter { isSelfSigned(it) }.toSet()
8+
return this.getPublicCertificates().values.filter { isSelfSigned(it) }.toSet().onEach {
9+
log.info("Loaded root certificate: <${it.serialNumber}> <${it.subjectX500Principal.name}> <${it.issuerX500Principal}>")
10+
}
911
}
1012

1113
internal fun KeyStore.getIntermediateCerts(): Set<X509Certificate> {
12-
return this.getPublicCertificates().values.filter { !isSelfSigned(it) }.toSet()
14+
return this.getPublicCertificates().values.filter { !isSelfSigned(it) }.toSet().onEach {
15+
log.info("Loaded intermediate certificate: <${it.serialNumber}> <${it.subjectX500Principal.name}> <${it.issuerX500Principal}>")
16+
}
1317
}

cpa-repo/src/test/kotlin/no/nav/emottak/cpa/validation/SertifikatValideringTest.kt

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class SertifikatValideringTest : FunSpec({
2929
every {
3030
crlChecker.getCRLRevocationInfo(any(), any())
3131
} just runs
32+
System.setProperty("TRUSTSTORE_PATH", "truststore.p12")
3233
val sertifikatValidering = SertifikatValidering(crlChecker, trustStoreConfig)
3334

3435
withData(

ebms-provider/src/main/kotlin/no/nav/emottak/ebms/App.kt

+4-3
Original file line numberDiff line numberDiff line change
@@ -236,12 +236,12 @@ suspend fun ApplicationCall.respondEbmsDokument(ebmsDokument: EbMSDocument) {
236236
if (ebmsDokument.dokumentType() == DokumentType.ACKNOWLEDGMENT) {
237237
log.info("Successfuly processed Payload Message")
238238
}
239-
val ebxml = Base64.getMimeEncoder().encodeToString(ebmsDokument.dokument.asString().toByteArray())
240239

241240
this.response.headers.apply {
242241
this.append(MimeHeaders.CONTENT_TYPE, ContentType.Text.Xml.toString())
243242
}
244243
if (ebmsDokument.dokumentType() == DokumentType.PAYLOAD) {
244+
val ebxml = Base64.getMimeEncoder().encodeToString(ebmsDokument.dokument.asString().toByteArray())
245245
val ebxmlFormItem = PartData.FormItem(
246246
ebxml,
247247
{},
@@ -278,7 +278,8 @@ suspend fun ApplicationCall.respondEbmsDokument(ebmsDokument: EbMSDocument) {
278278
)
279279
} else {
280280
this.response.headers.append(MimeHeaders.CONTENT_TYPE, ContentType.Text.Xml.toString())
281-
this.response.headers.append(MimeHeaders.CONTENT_TRANSFER_ENCODING, "base64")
282-
this.respondText(status = HttpStatusCode.OK, text = ebxml)
281+
this.response.headers.append(MimeHeaders.CONTENT_TRANSFER_ENCODING, "8bit")
282+
this.response.headers.append(MimeHeaders.SOAP_ACTION, "ebXML")
283+
this.respondText(status = HttpStatusCode.OK, text = ebmsDokument.dokument.asString())
283284
}
284285
}

ebms-provider/src/test/kotlin/no/nav/emottak/ebms/EbmsRoutFellesIT.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import io.mockk.coVerify
1616
import io.mockk.just
1717
import io.mockk.mockk
1818
import io.mockk.runs
19-
import no.nav.emottak.cpa.decodeBase64Mime
2019
import no.nav.emottak.ebms.ebxml.errorList
2120
import no.nav.emottak.ebms.ebxml.messageHeader
2221
import no.nav.emottak.ebms.processing.ProcessingService
@@ -94,7 +93,7 @@ abstract class EbmsRoutFellesIT(val endpoint: String) {
9493
@Test
9594
fun `Feil på signature should answer with Feil Signal`() = validationTestApp {
9695
val response = client.post("/ebms", validMultipartRequest.asHttpRequest())
97-
val envelope = xmlMarshaller.unmarshal(response.bodyAsText().decodeBase64Mime(), Envelope::class.java)
96+
val envelope = xmlMarshaller.unmarshal(response.bodyAsText(), Envelope::class.java)
9897
with(envelope.assertErrorAndGet().error.first()) {
9998
Assertions.assertEquals("Signature Fail", this.description.value)
10099
Assertions.assertEquals(

ebms-provider/src/test/kotlin/no/nav/emottak/ebms/EbmsRouteAsyncIT.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import io.mockk.coVerify
1111
import io.mockk.every
1212
import io.mockk.mockkObject
1313
import no.nav.emottak.constants.SMTPHeaders
14-
import no.nav.emottak.cpa.decodeBase64Mime
1514
import no.nav.emottak.ebms.ebxml.acknowledgment
1615
import no.nav.emottak.ebms.ebxml.messageHeader
1716
import no.nav.emottak.ebms.validation.MimeHeaders
@@ -36,7 +35,7 @@ class EbmsRouteAsyncIT : EbmsRoutFellesIT("/ebms") {
3635
coVerify(exactly = 1) {
3736
processingService.processAsync(any(), any())
3837
}
39-
val envelope = xmlMarshaller.unmarshal(response.bodyAsText().decodeBase64Mime(), Envelope::class.java)
38+
val envelope = xmlMarshaller.unmarshal(response.bodyAsText(), Envelope::class.java)
4039
envelope.assertAcknowledgmen()
4140
assertEquals(HttpStatusCode.OK, response.status)
4241
}

ebms-provider/src/test/kotlin/no/nav/emottak/ebms/validation/MimeValidationIT.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class MimeValidationIT {
9292
} returns validationResult
9393

9494
val response = client.post("/ebms", validMultipartRequest.asHttpRequest())
95-
val envelope = xmlMarshaller.unmarshal(response.bodyAsText().decodeBase64Mime(), Envelope::class.java)
95+
val envelope = xmlMarshaller.unmarshal(response.bodyAsText(), Envelope::class.java)
9696
with(envelope.assertErrorAndGet().error.first()) {
9797
assertEquals("Signature Fail", this.description?.value)
9898
assertEquals(ErrorCode.SECURITY_FAILURE.value, this.errorCode)
@@ -107,7 +107,7 @@ class MimeValidationIT {
107107
} returns validationResult
108108

109109
val response = client.post("/ebms", validMultipartRequest.asHttpRequest())
110-
val envelope = xmlMarshaller.unmarshal(response.bodyAsText().decodeBase64Mime(), Envelope::class.java)
110+
val envelope = xmlMarshaller.unmarshal(response.bodyAsText(), Envelope::class.java)
111111
with(envelope.assertErrorAndGet().error.first()) {
112112
assertEquals("Signature Fail", this.description?.value)
113113
assertEquals(

ebms-send-in/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ dependencies {
5858
implementation(libs.labai.jsr305x.annotations)
5959
implementation(libs.bundles.exposed)
6060
implementation(libs.bundles.logging)
61+
implementation(libs.bundles.prometheus)
6162
implementation(libs.ebxml.protokoll)
6263
implementation(libs.emottak.payload.xsd)
6364
implementation(libs.jaxb.runtime)

ebms-send-in/src/main/kotlin/no/nav/emottak/ebms/App.kt

+12-8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import io.ktor.server.application.install
88
import io.ktor.server.auth.Authentication
99
import io.ktor.server.auth.authenticate
1010
import io.ktor.server.engine.embeddedServer
11+
import io.ktor.server.metrics.micrometer.MicrometerMetrics
1112
import io.ktor.server.netty.Netty
1213
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
1314
import io.ktor.server.request.receive
@@ -16,6 +17,8 @@ import io.ktor.server.response.respondText
1617
import io.ktor.server.routing.get
1718
import io.ktor.server.routing.post
1819
import io.ktor.server.routing.routing
20+
import io.micrometer.prometheus.PrometheusConfig
21+
import io.micrometer.prometheus.PrometheusMeterRegistry
1922
import no.nav.emottak.auth.AZURE_AD_AUTH
2023
import no.nav.emottak.auth.AuthConfig
2124
import no.nav.emottak.fellesformat.addressing
@@ -34,6 +37,8 @@ import org.xmlsoap.schemas.soap.envelope.Envelope
3437

3538
internal val log = LoggerFactory.getLogger("no.nav.emottak.ebms.App")
3639
fun main() {
40+
// val database = Database(mapHikariConfig(DatabaseConfig()))
41+
// database.migrate()
3742
System.setProperty("io.ktor.http.content.multipart.skipTempFile", "true")
3843
embeddedServer(Netty, port = 8080, module = Application::ebmsSendInModule, configure = {
3944
this.maxChunkSize = 100000
@@ -47,6 +52,10 @@ fun Application.ebmsSendInModule() {
4752
install(Authentication) {
4853
tokenValidationSupport(AZURE_AD_AUTH, AuthConfig.getEbmsSendInConfig())
4954
}
55+
val appMicrometerRegistry = PrometheusMeterRegistry(PrometheusConfig.DEFAULT)
56+
install(MicrometerMetrics) {
57+
registry = appMicrometerRegistry
58+
}
5059
routing {
5160
get("/testFrikortEndepunkt") {
5261
val testCpaString = String(this::class.java.classLoader.getResource("frikortRequest.xml")!!.readBytes())
@@ -64,14 +73,7 @@ fun Application.ebmsSendInModule() {
6473
frikortsporring(wrapMessageInEIFellesFormat(request))
6574
}.onSuccess {
6675
log.info(request.marker(), "Payload ${request.payloadId} videresendt til fagsystem")
67-
call.respond(
68-
SendInResponse(
69-
request.messageId,
70-
request.conversationId,
71-
it.eiFellesformat.addressing(request.addressing.from),
72-
marshal(it.eiFellesformat.msgHead).toByteArray()
73-
)
74-
)
76+
call.respond(SendInResponse(request.messageId, request.conversationId, it.eiFellesformat.addressing(request.addressing.from), marshal(it.eiFellesformat.msgHead).toByteArray()))
7577
}.onFailure {
7678
log.error(request.marker(), "Payload ${request.payloadId} videresending feilet", it)
7779
call.respond(HttpStatusCode.BadRequest, it.localizedMessage)
@@ -83,5 +85,7 @@ fun Application.ebmsSendInModule() {
8385
call.respondText("Hello world, but securely")
8486
}
8587
}
88+
89+
registerHealthEndpoints(appMicrometerRegistry)
8690
}
8791
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package no.nav.emottak.ebms
2+
3+
import io.ktor.server.application.call
4+
import io.ktor.server.response.respond
5+
import io.ktor.server.response.respondText
6+
import io.ktor.server.routing.Routing
7+
import io.ktor.server.routing.get
8+
import io.micrometer.prometheus.PrometheusMeterRegistry
9+
10+
fun Routing.registerHealthEndpoints(
11+
collectorRegistry: PrometheusMeterRegistry
12+
) {
13+
get("/internal/health/liveness") {
14+
call.respondText("I'm alive! :)")
15+
}
16+
get("/internal/health/readiness") {
17+
call.respondText("I'm ready! :)")
18+
}
19+
get("/prometheus") {
20+
call.respond(collectorRegistry.scrape())
21+
}
22+
}

felles/src/main/kotlin/no/nav/emottak/crypto/KeyStore.kt

+12-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package no.nav.emottak.crypto
22

33
import java.io.ByteArrayInputStream
44
import java.io.FileInputStream
5-
import java.io.FileNotFoundException
65
import java.security.KeyPair
76
import java.security.KeyStore
87
import java.security.PrivateKey
@@ -11,6 +10,7 @@ import java.security.cert.X509Certificate
1110
import java.util.HashMap
1211
import org.bouncycastle.jce.provider.BouncyCastleProvider
1312
import org.slf4j.LoggerFactory
13+
import java.io.File
1414

1515
internal val log = LoggerFactory.getLogger("no.nav.emottak.crypto.KeyStore")
1616
interface KeyStoreConfig {
@@ -33,11 +33,18 @@ class KeyStore(private val keyStoreConfig: KeyStoreConfig) {
3333
val keyStore = KeyStore.getInstance(keyStoreConfig.keyStoreStype)
3434
val fileContent =
3535
try {
36-
FileInputStream(storePath)
37-
} catch (e: FileNotFoundException) {
36+
log.debug("Getting store file from $storePath")
37+
if (File(storePath).exists()) {
38+
log.debug("Getting store file from file <$storePath>")
39+
FileInputStream(storePath)
40+
} else {
41+
log.debug("Getting store file from resources <$storePath>")
42+
ByteArrayInputStream(this::class.java.classLoader.getResourceAsStream(storePath).readBytes())
43+
}
44+
} catch (e: Exception) {
3845
//TODO Kast exception om keystore ikke kan leses
39-
log.error("Unable to load keystore $storePath falling back to truststore",e)
40-
ByteArrayInputStream(this::class.java.classLoader.getResourceAsStream("truststore.p12").readBytes())
46+
log.error("Unable to load keystore $storePath falling back to truststore", e)
47+
ByteArrayInputStream(this::class.java.classLoader.getResourceAsStream("truststore_test.p12").readBytes())
4148
}
4249
keyStore!!.load(fileContent, storePass)
4350
return keyStore

smtp-listeners/src/main/kotlin/no/nav/emottak/smtp/Routes.kt

+12-7
Original file line numberDiff line numberDiff line change
@@ -303,12 +303,17 @@ fun Folder.batchDelete(batchSize: Int) { // fixme: Skriv en test for denne før
303303
fun Folder.deleteAll() {
304304
if (this is IMAPFolder) {
305305
if (isOpen) close()
306-
val deleteMeFolder = getFolder("DeleteMe")
307-
if (!deleteMeFolder.exists()) create(HOLDS_MESSAGES)
308-
this.renameTo(deleteMeFolder)
309-
deleteMeFolder.delete(true)
310-
log.info("${this.fullName} deleted.")
311-
return
306+
if (name.lowercase().contains("inbox")) {
307+
val deleteMeFolder = getFolder("DeleteMe")
308+
if (!deleteMeFolder.exists()) create(HOLDS_MESSAGES)
309+
this.renameTo(deleteMeFolder)
310+
deleteMeFolder.delete(true)
311+
log.info("${this.fullName} deleted.")
312+
} else {
313+
delete(true)
314+
log.info("${this.fullName} deleted.")
315+
}
316+
} else {
317+
log.warn("DeleteAll strategy only valid for IMAP")
312318
}
313-
log.warn("DeleteAll strategy only valid for IMAP")
314319
}

0 commit comments

Comments
 (0)