mirror of
https://github.com/pcvolkmer/etl-processor.git
synced 2025-04-19 17:26:51 +00:00
feat: remove SSL-CA-Location config (#99)
This commit is contained in:
parent
9d4786fae3
commit
66cc818755
@ -52,8 +52,6 @@ Soll noch das alte bwHC-Backend verwendet werden, so ist die Umgebungsvariable
|
||||
|
||||
In Versionen des ETL-Processors **nach Version 0.10** werden die folgenden Konfigurationsoptionen entfernt:
|
||||
|
||||
* `APP_PSEUDONYMIZE_GPAS_SSLCALOCATION`: Nutzen Sie hier, wie unter [_Integration eines eigenen Root CA
|
||||
Zertifikats_](#integration-eines-eigenen-root-ca-zertifikats) beschrieben, das Einbinden eigener Zertifikate.
|
||||
* `APP_KAFKA_TOPIC`: Nutzen Sie nun die Konfigurationsoption `APP_KAFKA_OUTPUT_TOPIC`
|
||||
* `APP_KAFKA_RESPONSE_TOPIC`: Nutzen Sie nun die Konfigurationsoption `APP_KAFKA_OUTPUT_RESPONSE_TOPIC`
|
||||
|
||||
@ -90,13 +88,6 @@ Wurde die Verwendung von gPAS konfiguriert, so sind weitere Angaben zu konfiguri
|
||||
* `APP_PSEUDONYMIZE_GPAS_TARGET`: gPas Domänenname
|
||||
* `APP_PSEUDONYMIZE_GPAS_USERNAME`: gPas Basic-Auth Benutzername
|
||||
* `APP_PSEUDONYMIZE_GPAS_PASSWORD`: gPas Basic-Auth Passwort
|
||||
* ~~`APP_PSEUDONYMIZE_GPAS_SSLCALOCATION`~~: **Veraltet** - Root Zertifikat für gPas, falls es dediziert hinzugefügt werden muss.
|
||||
**Wird in nach Version 0.10 entfernt**
|
||||
|
||||
Der Konfigurationsparameter `APP_PSEUDONYMIZE_GPAS_SSLCALOCATION` sollte nicht mehr verwendet werden und wird nach
|
||||
Version 0.10 entfernt.
|
||||
Stattdessen sollte das Root Zertifikat wie unter [_Integration eines eigenen Root CA
|
||||
Zertifikats_](#integration-eines-eigenen-root-ca-zertifikats) beschrieben eingebunden werden.
|
||||
|
||||
### Anmeldung mit einem Passwort
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of ETL-Processor
|
||||
*
|
||||
* Copyright (c) 2024 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
|
||||
* Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
@ -47,10 +47,9 @@ class GpasPseudonymGeneratorTest {
|
||||
fun setup() {
|
||||
val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(1)).build()
|
||||
val gPasConfigProperties = GPasConfigProperties(
|
||||
"http://localhost/ttp-fhir/fhir/gpas/\$pseudonymizeAllowCreate",
|
||||
"https://localhost/ttp-fhir/fhir/gpas/\$pseudonymizeAllowCreate",
|
||||
"test",
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
|
||||
@ -63,7 +62,7 @@ class GpasPseudonymGeneratorTest {
|
||||
fun shouldReturnExpectedPseudonym() {
|
||||
this.mockRestServiceServer.expect {
|
||||
method(HttpMethod.POST)
|
||||
requestTo("http://localhost/ttp-fhir/fhir/gpas/\$pseudonymizeAllowCreate")
|
||||
requestTo("https://localhost/ttp-fhir/fhir/gpas/\$pseudonymizeAllowCreate")
|
||||
}.andRespond {
|
||||
withStatus(HttpStatus.OK).body(getDummyResponseBody("1234", "test", "test1234ABCDEF567890"))
|
||||
.createResponse(it)
|
||||
@ -76,7 +75,7 @@ class GpasPseudonymGeneratorTest {
|
||||
fun shouldThrowExceptionIfGpasNotAvailable() {
|
||||
this.mockRestServiceServer.expect {
|
||||
method(HttpMethod.POST)
|
||||
requestTo("http://localhost/ttp-fhir/fhir/gpas/\$pseudonymizeAllowCreate")
|
||||
requestTo("https://localhost/ttp-fhir/fhir/gpas/\$pseudonymizeAllowCreate")
|
||||
}.andRespond {
|
||||
withException(IOException("Simulated IO error")).createResponse(it)
|
||||
}
|
||||
@ -88,7 +87,7 @@ class GpasPseudonymGeneratorTest {
|
||||
fun shouldThrowExceptionIfGpasDoesNotReturn2xxResponse() {
|
||||
this.mockRestServiceServer.expect {
|
||||
method(HttpMethod.POST)
|
||||
requestTo("http://localhost/ttp-fhir/fhir/gpas/\$pseudonymizeAllowCreate")
|
||||
requestTo("https://localhost/ttp-fhir/fhir/gpas/\$pseudonymizeAllowCreate")
|
||||
}.andRespond {
|
||||
withStatus(HttpStatus.FOUND)
|
||||
.header(HttpHeaders.LOCATION, "https://localhost/ttp-fhir/fhir/gpas/\$pseudonymizeAllowCreate")
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of ETL-Processor
|
||||
*
|
||||
* Copyright (c) 2024 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
|
||||
* Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
@ -56,10 +56,6 @@ data class GPasConfigProperties(
|
||||
val target: String = "etl-processor",
|
||||
val username: String?,
|
||||
val password: String?,
|
||||
@get:DeprecatedConfigurationProperty(
|
||||
reason = "Deprecated in favor of including Root CA"
|
||||
)
|
||||
val sslCaLocation: String?
|
||||
) {
|
||||
companion object {
|
||||
const val NAME = "app.pseudonymize.gpas"
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of ETL-Processor
|
||||
*
|
||||
* Copyright (c) 2024 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
|
||||
* Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
@ -32,12 +32,6 @@ import dev.dnpm.etl.processor.security.TokenRepository
|
||||
import dev.dnpm.etl.processor.security.TokenService
|
||||
import dev.dnpm.etl.processor.services.Transformation
|
||||
import dev.dnpm.etl.processor.services.TransformationService
|
||||
import org.apache.hc.client5.http.impl.classic.HttpClients
|
||||
import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager
|
||||
import org.apache.hc.client5.http.socket.ConnectionSocketFactory
|
||||
import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory
|
||||
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
|
||||
@ -45,7 +39,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory
|
||||
import org.springframework.retry.RetryCallback
|
||||
import org.springframework.retry.RetryContext
|
||||
import org.springframework.retry.RetryListener
|
||||
@ -58,13 +51,6 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager
|
||||
import org.springframework.web.client.HttpClientErrorException
|
||||
import org.springframework.web.client.RestTemplate
|
||||
import reactor.core.publisher.Sinks
|
||||
import java.io.BufferedInputStream
|
||||
import java.io.FileInputStream
|
||||
import java.security.KeyStore
|
||||
import java.security.cert.CertificateFactory
|
||||
import java.security.cert.X509Certificate
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.TrustManagerFactory
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import kotlin.time.toJavaDuration
|
||||
|
||||
@ -90,18 +76,6 @@ class AppConfiguration {
|
||||
@ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
|
||||
@Bean
|
||||
fun gpasPseudonymGenerator(configProperties: GPasConfigProperties, retryTemplate: RetryTemplate, restTemplate: RestTemplate): Generator {
|
||||
try {
|
||||
if (!configProperties.sslCaLocation.isNullOrBlank()) {
|
||||
return GpasPseudonymGenerator(
|
||||
configProperties,
|
||||
retryTemplate,
|
||||
createCustomGpasRestTemplate(configProperties)
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
|
||||
return GpasPseudonymGenerator(configProperties, retryTemplate, restTemplate)
|
||||
}
|
||||
|
||||
@ -115,81 +89,9 @@ class AppConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
@Bean
|
||||
fun gpasPseudonymGeneratorOnDeprecatedProperty(configProperties: GPasConfigProperties, retryTemplate: RetryTemplate, restTemplate: RestTemplate): Generator {
|
||||
try {
|
||||
if (!configProperties.sslCaLocation.isNullOrBlank()) {
|
||||
return GpasPseudonymGenerator(
|
||||
configProperties,
|
||||
retryTemplate,
|
||||
createCustomGpasRestTemplate(configProperties)
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
|
||||
return GpasPseudonymGenerator(configProperties, retryTemplate, restTemplate)
|
||||
}
|
||||
|
||||
private fun createCustomGpasRestTemplate(configProperties: GPasConfigProperties): RestTemplate {
|
||||
fun getSslContext(certificateLocation: String): SSLContext? {
|
||||
val ks = KeyStore.getInstance(KeyStore.getDefaultType())
|
||||
|
||||
val fis = FileInputStream(certificateLocation)
|
||||
val ca = CertificateFactory.getInstance("X.509")
|
||||
.generateCertificate(BufferedInputStream(fis)) as X509Certificate
|
||||
|
||||
ks.load(null, null)
|
||||
ks.setCertificateEntry(1.toString(), ca)
|
||||
|
||||
val tmf = TrustManagerFactory.getInstance(
|
||||
TrustManagerFactory.getDefaultAlgorithm()
|
||||
)
|
||||
tmf.init(ks)
|
||||
|
||||
val sslContext = SSLContext.getInstance("TLS")
|
||||
sslContext.init(null, tmf.trustManagers, null)
|
||||
|
||||
return sslContext
|
||||
}
|
||||
|
||||
fun getCustomRestTemplate(customSslContext: SSLContext): RestTemplate {
|
||||
val sslsf = SSLConnectionSocketFactory(customSslContext)
|
||||
val socketFactoryRegistry = RegistryBuilder.create<ConnectionSocketFactory>()
|
||||
.register("https", sslsf).register("http", PlainConnectionSocketFactory()).build()
|
||||
|
||||
val connectionManager = BasicHttpClientConnectionManager(
|
||||
socketFactoryRegistry
|
||||
)
|
||||
val httpClient = HttpClients.custom()
|
||||
.setConnectionManager(connectionManager).build()
|
||||
|
||||
val requestFactory = HttpComponentsClientHttpRequestFactory(
|
||||
httpClient
|
||||
)
|
||||
return RestTemplate(requestFactory)
|
||||
}
|
||||
|
||||
try {
|
||||
if (!configProperties.sslCaLocation.isNullOrBlank()) {
|
||||
val customSslContext = getSslContext(configProperties.sslCaLocation)
|
||||
logger.warn(
|
||||
String.format(
|
||||
"%s has been initialized with SSL certificate %s. This is deprecated in favor of including Root CA.",
|
||||
this.javaClass.name, configProperties.sslCaLocation
|
||||
)
|
||||
)
|
||||
|
||||
if (customSslContext != null) {
|
||||
return getCustomRestTemplate(customSslContext)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
|
||||
throw RuntimeException("Custom SSL configuration for gPAS not usable")
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(value = ["app.pseudonymizer"], havingValue = "BUILDIN")
|
||||
@ConditionalOnMissingBean
|
||||
@Bean
|
||||
|
Loading…
x
Reference in New Issue
Block a user