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

Disable DSFWebserviceClient requests logs by default #249

Merged
merged 1 commit into from
Jan 15, 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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
| QUERY_VALIDATION_ENABLED | When enabled, any structured query submitted via the `run-query` endpoint is validated against the JSON schema located in `src/main/resources/query/query-schema.json` | true / false | true |
| QUERYRESULT_EXPIRY_MINUTES | How many minutes should query results be kept in memory? | | 5 |
| QUERYRESULT_PUBLIC_KEY | The public key in Base64-encoded DER format without banners and line breaks. Mandatory if _QUERYRESULT_DISABLE_LOG_FILE_ENCRYPTION_ is _false_ |
| QUERYRESULT_DISABLE_LOG_FILE_ENCRYPTION | Disable encryption of the result log file. | true / false | |
| QUERYRESULT_DISABLE_LOG_FILE_ENCRYPTION | Disable encryption of the result log file. | true / false | |
| ALLOWED_ORIGINS | Allowed origins for cross-origin requests. This should at least cover the frontend address. | | http://localhost |
| MAX_SAVED_QUERIES_PER_USER | How many slots does a user have to store saved queries. | | 10 |

Expand Down Expand Up @@ -94,10 +94,10 @@ In order to run the backend using the DSF path, the following environment variab
| DSF_PROXY_USERNAME | Proxy username to be used. | | |
| DSF_PROXY_PASSWORD | Proxy password to be used. | | |
| DSF_WEBSERVICE_BASE_URL | Base URL pointing to the local ZARS FHIR server. | `https://zars/fhir` | |
| DSF_WEBSERVICE_LOG_REQUESTS | Log webservice client communication at log level INFO or below (**WARNING**: potentially contains sensitive data) | `true` | `false` |
| DSF_WEBSOCKET_URL | URL pointing to the local ZARS FHIR server websocket endpoint. | `wss://zars/fhir/ws` | |
| DSF_ORGANIZATION_ID | Identifier for the local organization this backend is part of. | `MY ZARS` | |


### Privacy and Obfuscation

In order to prevent potentially malicious attempts to obtain critical patient data, several
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,22 @@ class DSFFhirWebClientProvider implements FhirWebClientProvider {
private final FhirSecurityContextProvider securityContextProvider;
private FhirSecurityContext securityContext;
private final FhirProxyContext proxyContext;
private boolean logRequests;


public DSFFhirWebClientProvider(FhirContext fhirContext, String webserviceBaseUrl, int webserviceReadTimeout,
int webserviceConnectTimeout, String websocketUrl,
FhirSecurityContextProvider securityContextProvider,
FhirProxyContext proxyContext) {
FhirProxyContext proxyContext,
boolean logRequests) {
this.fhirContext = fhirContext;
this.webserviceBaseUrl = webserviceBaseUrl;
this.webserviceReadTimeout = webserviceReadTimeout;
this.webserviceConnectTimeout = webserviceConnectTimeout;
this.websocketUrl = websocketUrl;
this.securityContextProvider = securityContextProvider;
this.proxyContext = proxyContext;
this.logRequests = logRequests;
}

@Override
Expand All @@ -76,7 +79,7 @@ public FhirWebserviceClient provideFhirWebserviceClient() throws FhirWebClientPr
proxyContext.getPassword(),
webserviceConnectTimeout,
webserviceReadTimeout,
true,
logRequests,
null,
fhirContext,
cleaner);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public class DSFSpringConfig {
@Value("${app.broker.dsf.webservice.connectTimeout}")
private int webserviceConnectTimeout;

@Value("${app.broker.dsf.webservice.logRequests}")
private boolean logRequests;

@Value("${app.broker.dsf.websocket.url}")
private String websocketUrl;

Expand Down Expand Up @@ -102,7 +105,7 @@ FhirWebClientProvider fhirWebClientProvider(FhirContext fhirContext,
FhirSecurityContextProvider securityContextProvider,
FhirProxyContext proxyContext) {
return new DSFFhirWebClientProvider(fhirContext, webserviceBaseUrl, webserviceReadTimeout,
webserviceConnectTimeout, websocketUrl, securityContextProvider, proxyContext);
webserviceConnectTimeout, websocketUrl, securityContextProvider, proxyContext, logRequests);
}

}
1 change: 1 addition & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ app:
baseUrl: ${DSF_WEBSERVICE_BASE_URL}
readTimeout: 20000
connectTimeout: 2000
logRequests: ${DSF_WEBSERVICE_LOG_REQUESTS:false}
websocket:
url: ${DSF_WEBSOCKET_URL}
organizationId: ${DSF_ORGANIZATION_ID}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package de.numcodex.feasibility_gui_backend.query.broker.dsf;

import ca.uhn.fhir.context.FhirContext;
import dev.dsf.fhir.client.FhirWebserviceClient;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

import static java.lang.String.format;
import static org.assertj.core.api.Assertions.assertThat;

@Testcontainers
@ExtendWith(OutputCaptureExtension.class)
public class DSFFhirWebClientProviderTest {

@Container
private GenericContainer<?> blaze = new GenericContainer<>("samply/blaze:0.23.3")
.withExposedPorts(8080)
.withNetwork(Network.newNetwork())
.withReuse(true);

@Test
void settingLogRequestsFlagToTrueEnablesRequestLogs(CapturedOutput output) throws Exception {
String webserviceBaseUrl = format("http://%s:%s/fhir", blaze.getHost(), blaze.getFirstMappedPort());
String websocketBaseUrl = format("ws://%s:%s/fhir", blaze.getHost(), blaze.getFirstMappedPort());
FhirSecurityContextProvider securityContextProvider = () -> new FhirSecurityContext(null, null, null);
FhirProxyContext proxyContext = new FhirProxyContext(null, null, null);
DSFFhirWebClientProvider clientProvider = new DSFFhirWebClientProvider(FhirContext.forR4(), webserviceBaseUrl,
20000, 2000, websocketBaseUrl, securityContextProvider, proxyContext, true);
FhirWebserviceClient client = clientProvider.provideFhirWebserviceClient();

client.getConformance();

assertThat(output)
.containsIgnoringCase("sending client request")
.containsIgnoringCase("client response received");
}

@Test
void settingLogRequestsFlagToFalseDisablesRequestLogs(CapturedOutput output) throws Exception {
String webserviceBaseUrl = format("http://%s:%s/fhir", blaze.getHost(), blaze.getFirstMappedPort());
String websocketBaseUrl = format("ws://%s:%s/fhir", blaze.getHost(), blaze.getFirstMappedPort());
FhirSecurityContextProvider securityContextProvider = () -> new FhirSecurityContext(null, null, null);
FhirProxyContext proxyContext = new FhirProxyContext(null, null, null);
DSFFhirWebClientProvider clientProvider = new DSFFhirWebClientProvider(FhirContext.forR4(), webserviceBaseUrl,
20000, 2000, websocketBaseUrl, securityContextProvider, proxyContext, false);
FhirWebserviceClient client = clientProvider.provideFhirWebserviceClient();

client.getConformance();

assertThat(output)
.doesNotContainIgnoringCase("sending client request")
.doesNotContainIgnoringCase("client response received");
}

}
Loading