Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues/16 oauth2 client credentials flow #17

Merged
merged 6 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>de.medizininformatik-initiative</groupId>
<artifactId>mii-process-data-transfer</artifactId>
<version>1.0.1.1-SNAPSHOT</version>
<version>1.0.2.0-SNAPSHOT</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down Expand Up @@ -45,7 +45,7 @@
<dependency>
<groupId>de.medizininformatik-initiative</groupId>
<artifactId>mii-processes-common</artifactId>
<version>1.0.1.0</version>
<version>1.0.2.0-SNAPSHOT</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

public class DataTransferProcessPluginDefinition implements ProcessPluginDefinition
{
public static final String VERSION = "1.0.1.1";
public static final String VERSION = "1.0.2.0";
public static final LocalDate RELEASE_DATE = LocalDate.of(2024, 6, 11);

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,22 @@
import ca.uhn.fhir.context.FhirContext;
import de.medizininformatik_initiative.processes.common.fhir.client.FhirClientFactory;
import de.medizininformatik_initiative.processes.common.fhir.client.logging.DataLogger;
import de.medizininformatik_initiative.processes.common.fhir.client.token.OAuth2TokenClient;
import de.medizininformatik_initiative.processes.common.fhir.client.token.OAuth2TokenProvider;
import de.medizininformatik_initiative.processes.common.fhir.client.token.TokenClient;
import de.medizininformatik_initiative.processes.common.fhir.client.token.TokenProvider;
import dev.dsf.bpe.v1.ProcessPluginApi;
import dev.dsf.bpe.v1.documentation.ProcessDocumentation;

@Configuration
public class DicFhirClientConfig
{
// TODO: use default proxy config from DSF
@Autowired
private FhirContext fhirContext;

@Autowired
private ProcessPluginApi api;

@ProcessDocumentation(required = true, processNames = {
"medizininformatik-initiativede_dataSend" }, description = "The base address of the DIC FHIR server to read/store FHIR resources", example = "http://foo.bar/fhir")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.base.url:#{null}}")
Expand Down Expand Up @@ -81,20 +88,65 @@ public class DicFhirClientConfig
private boolean fhirStoreHapiClientVerbose;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "Proxy location, set if the server containing the FHIR data can only be reached through a proxy", example = "http://proxy.foo:8080")
"medizininformatik-initiativede_dataSend" }, description = "Proxy location, set if the server containing the FHIR data can only be reached through a proxy, uses value from DEV_DSF_PROXY_URL if not set", example = "http://proxy.foo:8080")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.proxy.url:#{null}}")
private String fhirStoreProxyUrl;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "Proxy username, set if the server containing the FHIR data can only be reached through a proxy which requests authentication")
"medizininformatik-initiativede_dataSend" }, description = "Proxy username, set if the server containing the FHIR data can only be reached through a proxy which requests authentication, uses value from DEV_DSF_PROXY_USERNAME if not set")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.proxy.username:#{null}}")
private String fhirStoreProxyUsername;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "Proxy password, set if the server containing the FHIR data can only be reached through a proxy which requests authentication", recommendation = "Use docker secret file to configure by using *${env_variable}_FILE*")
"medizininformatik-initiativede_dataSend" }, description = "Proxy password, set if the server containing the FHIR data can only be reached through a proxy which requests authentication, uses value from DEV_DSF_PROXY_PASSWORD if not set", recommendation = "Use docker secret file to configure by using *${env_variable}_FILE*")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.proxy.password:#{null}}")
private String fhirStoreProxyPassword;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "The url of the oidc provider to request access tokens (token endpoint)", example = "http://foo.baz/realms/fhir-realm/protocol/openid-connect/token")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.oauth2.issuer.url:#{null}}")
private String fhirStoreOAuth2IssuerUrl;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "Identifier of the client (username) used for authentication when accessing the oidc provider token endpoint")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.oauth2.client.id:#{null}}")
private String fhirStoreOAuth2ClientId;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "Secret of the client (password) used for authentication when accessing the oidc provider token endpoint", recommendation = "Use docker secret file to configure by using *${env_variable}_FILE*")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.oauth2.client.password:#{null}}")
private String fhirStoreOAuth2ClientSecret;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "The timeout in milliseconds until a connection is established between the client and the oidc provider", recommendation = "Change default value only if timeout exceptions occur")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.oauth2.timeout.connect:20000}")
private int fhirStoreOAuth2ConnectTimeout;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "Maximum period of inactivity in milliseconds between two consecutive data packets of the client and the oidc provider", recommendation = "Change default value only if timeout exceptions occur")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.oauth2.timeout.socket:60000}")
private int fhirStoreOAuth2SocketTimeout;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "PEM encoded file with one or more trusted root certificate to validate the oidc provider server certificate when connecting via https", recommendation = "Use docker secret file to configure", example = "/run/secrets/hospital_ca.pem")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.oauth2.trust.certificates:#{null}}")
private String fhirStoreOAuth2TrustStore;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "Proxy location, set if the oidc provider can only be reached through a proxy, uses value from DEV_DSF_PROXY_URL if not set", example = "http://proxy.foo:8080")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.oauth2.proxy.url:#{null}}")
private String fhirStoreOAuth2ProxyUrl;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "Proxy username, set if the oidc provider can only be reached through a proxy which requests authentication, uses value from DEV_DSF_PROXY_USERNAME if not set")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.oauth2.proxy.username:#{null}}")
private String fhirStoreOAuth2ProxyUsername;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "Proxy password, set if the oidc provider can only be reached through a proxy which requests authentication, uses value from DEV_DSF_PROXY_PASSWORD if not set", recommendation = "Use docker secret file to configure by using *${env_variable}_FILE*")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.server.oauth2.proxy.password:#{null}}")
private String fhirStoreOAuth2ProxyPassword;

@ProcessDocumentation(processNames = {
"medizininformatik-initiativede_dataSend" }, description = "To enable debug logging of FHIR resources set to `true`")
@Value("${de.medizininformatik.initiative.data.transfer.dic.fhir.dataLoggingEnabled:false}")
Expand All @@ -109,10 +161,46 @@ public FhirClientFactory fhirClientFactory()
Path certificatePath = checkExists(fhirStoreCertificate);
Path privateKeyPath = checkExists(fhirStorePrivateKey);

String proxyUrl = fhirStoreProxyUrl, proxyUsername = fhirStoreProxyUsername,
proxyPassword = fhirStoreProxyPassword;
if (proxyUrl == null && api.getProxyConfig().isEnabled()
&& !api.getProxyConfig().isNoProxyUrl(fhirStoreBaseUrl))
{
proxyUrl = api.getProxyConfig().getUrl();
proxyUsername = api.getProxyConfig().getUsername();
proxyPassword = api.getProxyConfig().getPassword() == null ? null
: new String(api.getProxyConfig().getPassword());
}

return new FhirClientFactory(trustStorePath, certificatePath, privateKeyPath, fhirStorePrivateKeyPassword,
fhirStoreConnectTimeout, fhirStoreSocketTimeout, fhirStoreConnectionRequestTimeout, fhirStoreBaseUrl,
fhirStoreUsername, fhirStorePassword, fhirStoreBearerToken, fhirStoreProxyUrl, fhirStoreProxyUsername,
fhirStoreProxyPassword, fhirStoreHapiClientVerbose, fhirContext, localIdentifierValue, dataLogger());
fhirStoreUsername, fhirStorePassword, fhirStoreBearerToken, tokenProvider(), proxyUrl, proxyUsername,
proxyPassword, fhirStoreHapiClientVerbose, fhirContext, localIdentifierValue, dataLogger());
}

public TokenProvider tokenProvider()
{
return new OAuth2TokenProvider(tokenClient());
}

public TokenClient tokenClient()
{
Path trustStoreOAuth2Path = checkExists(fhirStoreOAuth2TrustStore);

String proxyUrl = fhirStoreOAuth2ProxyUrl, proxyUsername = fhirStoreOAuth2ProxyUsername,
proxyPassword = fhirStoreOAuth2ProxyPassword;
if (proxyUrl == null && api.getProxyConfig().isEnabled()
&& !api.getProxyConfig().isNoProxyUrl(fhirStoreOAuth2IssuerUrl))
{
proxyUrl = api.getProxyConfig().getUrl();
proxyUsername = api.getProxyConfig().getUsername();
proxyPassword = api.getProxyConfig().getPassword() == null ? null
: new String(api.getProxyConfig().getPassword());
}

return new OAuth2TokenClient(fhirStoreOAuth2IssuerUrl, fhirStoreOAuth2ClientId, fhirStoreOAuth2ClientSecret,
fhirStoreOAuth2ConnectTimeout, fhirStoreOAuth2SocketTimeout, trustStoreOAuth2Path, proxyUrl,
proxyUsername, proxyPassword);
}

public DataLogger dataLogger()
Expand Down
Loading
Loading