From 4911f4fef8e5d1ac11ceb8c877fbea7391cb5b21 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 18 May 2024 14:58:33 +1000 Subject: [PATCH] updates for ManagedWebAccess --- .../fhir/convertors/misc/ICD11Generator.java | 7 +- .../TerminologyCacheManager.java | 10 +- .../hl7/fhir/r5/elementmodel/SHLParser.java | 1 - .../TerminologyCacheManager.java | 10 +- .../http/HTTPAuthenticationMode.java | 7 + .../hl7/fhir/utilities/http/HTTPResult.java | 1 - .../utilities/http/HTTPResultException.java | 24 ++++ .../fhir/utilities/http/ManagedWebAccess.java | 71 +++------- .../http/ManagedWebAccessBuilder.java | 125 ++++++++++++++++++ .../fhir/utilities/http/SimpleHTTPClient.java | 34 +---- .../utilities/json/JsonTrackingParser.java | 1 - .../utilities/json/parser/JsonParser.java | 1 - .../npm/FilesystemPackageCacheManager.java | 1 - .../hl7/fhir/utilities/npm/NpmPackage.java | 1 - .../hl7/fhir/utilities/npm/PackageClient.java | 23 ++-- .../hl7/fhir/utilities/npm/PackageServer.java | 13 +- .../fhir/utilities/settings/FhirSettings.java | 6 + .../npm/BasePackageCacheManagerTests.java | 8 +- .../fhir/utilities/npm/PackageServerTest.java | 6 +- .../org/hl7/fhir/validation/IgLoader.java | 1 - .../java/org/hl7/fhir/validation/Scanner.java | 1 - .../hl7/fhir/validation/ValidationEngine.java | 1 - .../validation/cli/utils/ProfileLoader.java | 1 - .../hl7/fhir/validation/ipa/IPAValidator.java | 1 - .../validation/tests/ValidationTests.java | 1 - pom.xml | 2 +- security.md | 9 +- 27 files changed, 226 insertions(+), 141 deletions(-) create mode 100644 org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/HTTPAuthenticationMode.java create mode 100644 org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/HTTPResultException.java create mode 100644 org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/ManagedWebAccessBuilder.java diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/ICD11Generator.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/ICD11Generator.java index e986b3570..2999ec012 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/ICD11Generator.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/ICD11Generator.java @@ -28,7 +28,7 @@ import org.hl7.fhir.r4.utils.ToolingExtensions; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.filesystem.ManagedFileAccess; import org.hl7.fhir.utilities.http.HTTPResult; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; +import org.hl7.fhir.utilities.http.ManagedWebAccess; import org.hl7.fhir.utilities.json.model.JsonElement; import org.hl7.fhir.utilities.json.model.JsonObject; import org.hl7.fhir.utilities.json.parser.JsonParser; @@ -395,10 +395,7 @@ public class ICD11Generator { private JsonObject fetchJson(String source) throws IOException { - SimpleHTTPClient http = new SimpleHTTPClient(); - http.addHeader("API-Version", "v2"); - http.addHeader("Accept-Language", "en"); - HTTPResult res = http.get(source, "application/json"); + HTTPResult res = ManagedWebAccess.builder().withAccept("application/json").withHeader("API-Version", "v2").withHeader("Accept-Language", "en").get(source); res.checkThrowException(); return JsonParser.parseObject(res.getContent()); } diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/terminologies/TerminologyCacheManager.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/terminologies/TerminologyCacheManager.java index 3d6b21878..68b94ed83 100644 --- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/terminologies/TerminologyCacheManager.java +++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/terminologies/TerminologyCacheManager.java @@ -29,7 +29,6 @@ import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.filesystem.ManagedFileAccess; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; public class TerminologyCacheManager { @@ -156,11 +155,10 @@ public class TerminologyCacheManager { // post it to String url = "https://tx.fhir.org/post/tx-cache/" + ghOrg + "/" + ghRepo + "/" + ghBranch + ".zip"; System.out.println("Sending tx-cache to " + url + " (" + Utilities.describeSize(bs.toByteArray().length) + ")"); - SimpleHTTPClient http = new SimpleHTTPClient(); - http.setAuthenticationMode(SimpleHTTPClient.AuthenticationMode.BASIC); - http.setUsername(token.substring(0, token.indexOf(':'))); - http.setPassword(token.substring(token.indexOf(':') + 1)); - HTTPResult res = http.put(url, "application/zip", bs.toByteArray(), null); // accept doesn't matter + + HTTPResult res = ManagedWebAccess.builder() + .withBasicAuth(token.substring(0, token.indexOf(':')), token.substring(token.indexOf(':') + 1)) + .withAccept("application/zip").put(url, bs.toByteArray(), null); if (res.getCode() >= 300) { System.out.println("sending cache failed: " + res.getCode()); } else { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHLParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHLParser.java index 8c5b1c017..bbbf0e851 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHLParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHLParser.java @@ -34,7 +34,6 @@ import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; import org.hl7.fhir.utilities.json.model.JsonArray; import org.hl7.fhir.utilities.json.model.JsonElement; import org.hl7.fhir.utilities.json.model.JsonElementType; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyCacheManager.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyCacheManager.java index e483a7c79..3e63ac0a8 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyCacheManager.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyCacheManager.java @@ -29,7 +29,6 @@ import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.filesystem.ManagedFileAccess; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; public class TerminologyCacheManager { @@ -157,11 +156,10 @@ public class TerminologyCacheManager { // post it to String url = "https://tx.fhir.org/post/tx-cache/"+ghOrg+"/"+ghRepo+"/"+ghBranch+".zip"; System.out.println("Sending tx-cache to "+url+" ("+Utilities.describeSize(bs.toByteArray().length)+")"); - SimpleHTTPClient http = new SimpleHTTPClient(); - http.setAuthenticationMode(SimpleHTTPClient.AuthenticationMode.BASIC); - http.setUsername(token.substring(0, token.indexOf(':'))); - http.setPassword(token.substring(token.indexOf(':')+1)); - HTTPResult res = http.put(url, "application/zip", bs.toByteArray(), null); // accept doesn't matter + HTTPResult res = ManagedWebAccess.builder() + .withBasicAuth(token.substring(0, token.indexOf(':')), token.substring(token.indexOf(':') + 1)) + .withAccept("application/zip").put(url, bs.toByteArray(), null); + if (res.getCode() >= 300) { System.out.println("sending cache failed: "+res.getCode()); } else { diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/HTTPAuthenticationMode.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/HTTPAuthenticationMode.java new file mode 100644 index 000000000..401c1cd15 --- /dev/null +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/HTTPAuthenticationMode.java @@ -0,0 +1,7 @@ +package org.hl7.fhir.utilities.http; + +public enum HTTPAuthenticationMode { + NONE, + BASIC, + TOKEN +} \ No newline at end of file diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/HTTPResult.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/HTTPResult.java index 5957979ca..0a3986ec1 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/HTTPResult.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/HTTPResult.java @@ -5,7 +5,6 @@ import java.nio.charset.StandardCharsets; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.utilities.http.SimpleHTTPClient.HTTPResultException; public class HTTPResult { private int code; diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/HTTPResultException.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/HTTPResultException.java new file mode 100644 index 000000000..dce4d00e5 --- /dev/null +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/HTTPResultException.java @@ -0,0 +1,24 @@ +package org.hl7.fhir.utilities.http; + +public class HTTPResultException extends Exception{ + public final int httpCode; + + public final String message; + + public final String url; + public final String logPath; + + public HTTPResultException(int httpCode, String message, String url, String logPath) { + this.httpCode = httpCode; + this.message = message; + this.url = url; + this.logPath = logPath; + } + + public String getMessage() { + return "Invalid HTTP response "+httpCode+" from "+url+" ("+message+") (" + ( + logPath != null ? "Response in " + logPath : "No response content") + + ")"; + } + +} \ No newline at end of file diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/ManagedWebAccess.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/ManagedWebAccess.java index 93863d1b0..6c90c3a44 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/ManagedWebAccess.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/ManagedWebAccess.java @@ -40,6 +40,7 @@ import java.io.InputStream; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Map; import org.hl7.fhir.utilities.Utilities; @@ -57,9 +58,9 @@ import org.hl7.fhir.utilities.Utilities; public class ManagedWebAccess { public interface IWebAccessor { - HTTPResult get(String url, String accept, String userAgent, String authenticationHeader) throws IOException; - HTTPResult post(String url, byte[] bytes, String contentType, String accept, String userAgent, String authenticationHeader) throws IOException; - HTTPResult put(String url, byte[] bytes, String contentType, String accept, String userAgent, String authenticationHeader) throws IOException; + HTTPResult get(String url, String accept, Map headers) throws IOException; + HTTPResult post(String url, byte[] bytes, String contentType, String accept, Map headers) throws IOException; + HTTPResult put(String url, byte[] bytes, String contentType, String accept, Map headers) throws IOException; } public enum WebAccessPolicy { @@ -82,7 +83,7 @@ public class ManagedWebAccess { ManagedWebAccess.accessPolicy = accessPolicy; } - private static boolean inAllowedPaths(String pathname) { + static boolean inAllowedPaths(String pathname) { if (allowedDomains.isEmpty()) { return true; } @@ -102,63 +103,29 @@ public class ManagedWebAccess { ManagedWebAccess.userAgent = userAgent; } + public static IWebAccessor getAccessor() { + return accessor; + } + + public static ManagedWebAccessBuilder builder() { + return new ManagedWebAccessBuilder(userAgent); + } + public static HTTPResult get(String url) throws IOException { - return get(url, null, null, null); + return builder().get(url); } public static HTTPResult get(String url, String accept) throws IOException { - return get(url, accept, null, null); - } - - public static HTTPResult get(String url, String accept, String userAgent, String authenticationHeader) throws IOException { - switch (accessPolicy) { - case DIRECT: - if (!inAllowedPaths(url)) { - throw new IOException("The pathname '"+url+"' cannot be accessed by policy"); - } - return new SimpleHTTPClient().get(url, accept); - case MANAGED: - return accessor.get(url, accept, userAgent, authenticationHeader); - case PROHIBITED: - throw new IOException("Access the internet is not allowed by local security policy"); - default: - throw new IOException("Internal Error"); - } + return builder().withAccept(accept).get(url); } public static HTTPResult post(String url, byte[] content, String contentType, String accept) throws IOException { - return post(url, content, contentType, accept, null, null); + return builder().withAccept(accept).post(url, content, contentType); } - public static HTTPResult post(String url, byte[] content, String contentType, String accept, String userAgent, String authenticationHeader) throws IOException { - switch (accessPolicy) { - case DIRECT: - if (!inAllowedPaths(url)) { - throw new IOException("The pathname '"+url+"' cannot be accessed by policy"); - } - return new SimpleHTTPClient().post(url, contentType, content, accept); - case MANAGED: - return accessor.get(url, accept, userAgent, authenticationHeader); - case PROHIBITED: - throw new IOException("Access the internet is not allowed by local security policy"); - default: - throw new IOException("Internal Error"); - } + + public static HTTPResult put(String url, byte[] content, String contentType, String accept) throws IOException { + return builder().withAccept(accept).put(url, content, contentType); } - public static HTTPResult put(String url, byte[] content, String contentType, String accept, String userAgent, String authenticationHeader) throws IOException { - switch (accessPolicy) { - case DIRECT: - if (!inAllowedPaths(url)) { - throw new IOException("The pathname '"+url+"' cannot be accessed by policy"); - } - return new SimpleHTTPClient().put(url, contentType, content, accept); - case MANAGED: - return accessor.get(url, accept, userAgent, authenticationHeader); - case PROHIBITED: - throw new IOException("Access the internet is not allowed by local security policy"); - default: - throw new IOException("Internal Error"); - } - } } \ No newline at end of file diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/ManagedWebAccessBuilder.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/ManagedWebAccessBuilder.java new file mode 100644 index 000000000..5dea6280f --- /dev/null +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/ManagedWebAccessBuilder.java @@ -0,0 +1,125 @@ +package org.hl7.fhir.utilities.http; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; + + +public class ManagedWebAccessBuilder { + + private String userAgent; + private HTTPAuthenticationMode authenticationMode; + private String username; + private String password; + private String token; + private String accept; + private Map headers = new HashMap(); + + public ManagedWebAccessBuilder(String userAgent) { + this.userAgent = userAgent; + } + + public ManagedWebAccessBuilder withAccept(String accept) { + this.accept = accept; + return this; + } + + public ManagedWebAccessBuilder withHeader(String name, String value) { + headers.put(name, value); + return this; + } + + public ManagedWebAccessBuilder withBasicAuth(String username, String password) { + this.authenticationMode = HTTPAuthenticationMode.BASIC; + this.username = username; + this.password = password; + return this; + } + + public ManagedWebAccessBuilder withToken(String token) { + this.authenticationMode = HTTPAuthenticationMode.TOKEN; + this.token = token; + return this; + } + + private Map headers() { + Map headers = new HashMap(); + headers.putAll(this.headers); + if (authenticationMode == HTTPAuthenticationMode.TOKEN) { + headers.put("Authorization", "Bearer " + token); + } else if (authenticationMode == HTTPAuthenticationMode.BASIC) { + String auth = username+":"+password; + byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8)); + headers.put("Authorization", "Basic " + new String(encodedAuth)); + } + + if (userAgent != null) { + headers.put("User-Agent", userAgent); + } + + return headers; + } + + private SimpleHTTPClient setupClient(String url) throws IOException { + if (!ManagedWebAccess.inAllowedPaths(url)) { + throw new IOException("The pathname '"+url+"' cannot be accessed by policy"); + } + SimpleHTTPClient client = new SimpleHTTPClient(); + if (userAgent != null) { + client.addHeader("User-Agent", userAgent); + } + if (username != null) { + client.setUsername(username); + client.setPassword(password); + client.setAuthenticationMode(authenticationMode); + } + return client; + } + + + public HTTPResult get(String url) throws IOException { + switch (ManagedWebAccess.getAccessPolicy()) { + case DIRECT: + SimpleHTTPClient client = setupClient(url); + return client.get(url, accept); + case MANAGED: + return ManagedWebAccess.getAccessor().get(url, accept, headers()); + case PROHIBITED: + throw new IOException("Access to the internet is not allowed by local security policy"); + default: + throw new IOException("Internal Error"); + } + } + + + public HTTPResult post(String url, byte[] content, String contentType) throws IOException { + switch (ManagedWebAccess.getAccessPolicy()) { + case DIRECT: + SimpleHTTPClient client = setupClient(url); + return client.post(url, contentType, content, accept); + case MANAGED: + return ManagedWebAccess.getAccessor().post(url, content, contentType, accept, headers()); + case PROHIBITED: + throw new IOException("Access to the internet is not allowed by local security policy"); + default: + throw new IOException("Internal Error"); + } + } + + public HTTPResult put(String url, byte[] content, String contentType) throws IOException { + switch (ManagedWebAccess.getAccessPolicy()) { + case DIRECT: + SimpleHTTPClient client = setupClient(url); + return client.put(url, contentType, content, accept); + case MANAGED: + return ManagedWebAccess.getAccessor().put(url, content, contentType, accept, headers()); + case PROHIBITED: + throw new IOException("Access to the internet is not allowed by local security policy"); + default: + throw new IOException("Internal Error"); + } + } + +} diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/SimpleHTTPClient.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/SimpleHTTPClient.java index 0e9f1de49..ad3f5c7d5 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/SimpleHTTPClient.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/http/SimpleHTTPClient.java @@ -20,11 +20,6 @@ import lombok.Setter; public class SimpleHTTPClient { - public enum AuthenticationMode { - NONE, - BASIC, - TOKEN - } public static class Header { private String name; @@ -45,33 +40,10 @@ public class SimpleHTTPClient { private static final int MAX_REDIRECTS = 5; private static int counter = 1; - public static class HTTPResultException extends Exception{ - public final int httpCode; - - public final String message; - - public final String url; - public final String logPath; - - public HTTPResultException(int httpCode, String message, String url, String logPath) { - this.httpCode = httpCode; - this.message = message; - this.url = url; - this.logPath = logPath; - } - - public String getMessage() { - return "Invalid HTTP response "+httpCode+" from "+url+" ("+message+") (" + ( - logPath != null ? "Response in " + logPath : "No response content") - + ")"; - } - - } - private List
headers = new ArrayList<>(); @Getter @Setter - private AuthenticationMode authenticationMode; + private HTTPAuthenticationMode authenticationMode; @Getter @Setter private String username; @@ -148,9 +120,9 @@ public class SimpleHTTPClient { private void setAuthenticationHeader(HttpURLConnection c) { String authHeaderValue = null; - if (authenticationMode == AuthenticationMode.TOKEN) { + if (authenticationMode == HTTPAuthenticationMode.TOKEN) { authHeaderValue = "Bearer " + new String(token); - } else if (authenticationMode == AuthenticationMode.BASIC) { + } else if (authenticationMode == HTTPAuthenticationMode.BASIC) { String auth = username+":"+password; byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8)); authHeaderValue = "Basic " + new String(encodedAuth); diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/json/JsonTrackingParser.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/json/JsonTrackingParser.java index f73ce6433..893aba96c 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/json/JsonTrackingParser.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/json/JsonTrackingParser.java @@ -44,7 +44,6 @@ import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; import com.google.gson.Gson; import com.google.gson.GsonBuilder; diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/json/parser/JsonParser.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/json/parser/JsonParser.java index cdc02db94..f795b6bdf 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/json/parser/JsonParser.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/json/parser/JsonParser.java @@ -13,7 +13,6 @@ import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.filesystem.ManagedFileAccess; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; import org.hl7.fhir.utilities.json.JsonException; import org.hl7.fhir.utilities.json.model.JsonArray; import org.hl7.fhir.utilities.json.model.JsonBoolean; diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java index f65c1aa48..c3ad924f2 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java @@ -33,7 +33,6 @@ import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.filesystem.ManagedFileAccess; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; import org.hl7.fhir.utilities.json.model.JsonArray; import org.hl7.fhir.utilities.json.model.JsonElement; import org.hl7.fhir.utilities.json.model.JsonObject; diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java index cf278228f..387240cdd 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java @@ -73,7 +73,6 @@ import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.filesystem.ManagedFileAccess; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; import org.hl7.fhir.utilities.json.JsonException; import org.hl7.fhir.utilities.json.model.JsonArray; import org.hl7.fhir.utilities.json.model.JsonElement; diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/PackageClient.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/PackageClient.java index 7374f8edc..1dbab8248 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/PackageClient.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/PackageClient.java @@ -21,8 +21,10 @@ import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; +import org.hl7.fhir.utilities.http.HTTPAuthenticationMode; import org.hl7.fhir.utilities.http.HTTPResult; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; +import org.hl7.fhir.utilities.http.ManagedWebAccess; +import org.hl7.fhir.utilities.http.ManagedWebAccessBuilder; import org.hl7.fhir.utilities.json.model.JsonArray; import org.hl7.fhir.utilities.json.model.JsonObject; import org.hl7.fhir.utilities.json.model.JsonProperty; @@ -174,22 +176,17 @@ public class PackageClient { } private InputStream fetchUrl(String source, String accept) throws IOException { - SimpleHTTPClient http = getSimpleHTTPClient(); - HTTPResult res = http.get(source, accept); + ManagedWebAccessBuilder client = ManagedWebAccess.builder().withAccept(accept); + if (server.getAuthenticationMode() == HTTPAuthenticationMode.TOKEN) { + client.withToken(server.getToken()); + } else if (server.getAuthenticationMode() == HTTPAuthenticationMode.BASIC) { + client.withBasicAuth(server.getUsername(), server.getPassword()); + } + HTTPResult res = client.get(source); res.checkThrowException(); return new ByteArrayInputStream(res.getContent()); } - @Nonnull - private SimpleHTTPClient getSimpleHTTPClient() { - SimpleHTTPClient client = new SimpleHTTPClient(); - client.setAuthenticationMode(server.getAuthenticationMode()); - client.setUsername(server.getUsername()); - client.setPassword(server.getPassword()); - client.setToken(server.getToken()); - return client; - } - private JsonObject fetchJson(String source) throws IOException { String src = TextFile.streamToString(fetchUrl(source, "application/json")); //System.out.println(src); diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/PackageServer.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/PackageServer.java index 341d9ce11..3a343eed1 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/PackageServer.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/PackageServer.java @@ -6,6 +6,7 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; +import org.hl7.fhir.utilities.http.HTTPAuthenticationMode; import org.hl7.fhir.utilities.http.SimpleHTTPClient; import org.hl7.fhir.utilities.settings.FhirSettings; import org.hl7.fhir.utilities.settings.PackageServerPOJO; @@ -22,14 +23,14 @@ public class PackageServer { public PackageServer(String url) { this.url = url; - authenticationMode = SimpleHTTPClient.AuthenticationMode.NONE; + authenticationMode = HTTPAuthenticationMode.NONE; serverType = PackageServerType.FHIR; } private String url; @Getter - private SimpleHTTPClient.AuthenticationMode authenticationMode; + private HTTPAuthenticationMode authenticationMode; @Getter private PackageServerType serverType; @@ -76,9 +77,9 @@ public class PackageServer { } @Nullable - private static SimpleHTTPClient.AuthenticationMode getModeFromPOJO(PackageServerPOJO pojo) { - if (pojo.getAuthenticationType().equalsIgnoreCase("basic")) return SimpleHTTPClient.AuthenticationMode.BASIC; - if (pojo.getAuthenticationType().equalsIgnoreCase("token")) return SimpleHTTPClient.AuthenticationMode.TOKEN; + private static HTTPAuthenticationMode getModeFromPOJO(PackageServerPOJO pojo) { + if (pojo.getAuthenticationType().equalsIgnoreCase("basic")) return HTTPAuthenticationMode.BASIC; + if (pojo.getAuthenticationType().equalsIgnoreCase("token")) return HTTPAuthenticationMode.TOKEN; return null; } @@ -103,7 +104,7 @@ public class PackageServer { return packageServer; } - public PackageServer withAuthenticationMode( SimpleHTTPClient.AuthenticationMode mode) { + public PackageServer withAuthenticationMode(HTTPAuthenticationMode mode) { PackageServer packageServer = this.copy(); packageServer.authenticationMode = mode; return packageServer; diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettings.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettings.java index 0509041f1..ac1bc04f4 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettings.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettings.java @@ -135,6 +135,12 @@ public class FhirSettings { : instance.fhirSettings.getProhibitNetworkAccess(); } + /** + * See ManagedWebAccess and use that to control network access + * + * @param value + */ + @Deprecated public static void setProhibitNetworkAccess(boolean value) { prohibitNetworkAccess = value; } diff --git a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/npm/BasePackageCacheManagerTests.java b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/npm/BasePackageCacheManagerTests.java index 7d963a819..dfb3589ed 100644 --- a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/npm/BasePackageCacheManagerTests.java +++ b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/npm/BasePackageCacheManagerTests.java @@ -9,7 +9,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; +import org.hl7.fhir.utilities.http.HTTPAuthenticationMode; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -26,7 +26,7 @@ public class BasePackageCacheManagerTests { server.enqueueDummyPackage(); PackageServer testServer = new PackageServer(packageServerUrl) - .withAuthenticationMode(SimpleHTTPClient.AuthenticationMode.BASIC) + .withAuthenticationMode(HTTPAuthenticationMode.BASIC) .withServerType(PackageServer.PackageServerType.NPM) .withUsername(MockPackageServer.DUMMY_USERNAME) .withPassword(MockPackageServer.DUMMY_PASSWORD); @@ -57,11 +57,11 @@ public class BasePackageCacheManagerTests { String packageServerBUrl = serverB.getPackageServerUrl(); PackageServer testServerA = new PackageServer(packageServerAUrl) - .withAuthenticationMode(SimpleHTTPClient.AuthenticationMode.BASIC) + .withAuthenticationMode(HTTPAuthenticationMode.BASIC) .withServerType(PackageServer.PackageServerType.NPM); PackageServer testServerB = new PackageServer(packageServerBUrl) - .withAuthenticationMode(SimpleHTTPClient.AuthenticationMode.BASIC) + .withAuthenticationMode(HTTPAuthenticationMode.BASIC) .withServerType(PackageServer.PackageServerType.NPM); basePackageCacheManager.addPackageServer(testServerA); diff --git a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/npm/PackageServerTest.java b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/npm/PackageServerTest.java index 1de2b1521..d9694bc9e 100644 --- a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/npm/PackageServerTest.java +++ b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/npm/PackageServerTest.java @@ -10,7 +10,7 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Base64; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; +import org.hl7.fhir.utilities.http.HTTPAuthenticationMode; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -41,7 +41,7 @@ public class PackageServerTest { server.enqueueDummyPackage(); PackageServer testServer = new PackageServer(packageServerUrl) - .withAuthenticationMode(SimpleHTTPClient.AuthenticationMode.BASIC) + .withAuthenticationMode(HTTPAuthenticationMode.BASIC) .withServerType(PackageServer.PackageServerType.NPM) .withUsername(MockPackageServer.DUMMY_USERNAME) .withPassword(MockPackageServer.DUMMY_PASSWORD); @@ -74,7 +74,7 @@ public class PackageServerTest { server.enqueueDummyPackage(); PackageServer testServer = new PackageServer(packageServerUrl) - .withAuthenticationMode(SimpleHTTPClient.AuthenticationMode.TOKEN) + .withAuthenticationMode(HTTPAuthenticationMode.TOKEN) .withServerType(PackageServer.PackageServerType.NPM) .withToken(MockPackageServer.DUMMY_TOKEN); PackageClient packageClient = new PackageClient(testServer); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/IgLoader.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/IgLoader.java index 60c802a90..aadf0b80f 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/IgLoader.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/IgLoader.java @@ -38,7 +38,6 @@ import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.filesystem.ManagedFileAccess; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.utilities.turtle.Turtle; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Scanner.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Scanner.java index bd78e36e5..5dd66f704 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Scanner.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Scanner.java @@ -36,7 +36,6 @@ import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.filesystem.ManagedFileAccess; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.xhtml.XhtmlComposer; import org.hl7.fhir.validation.ValidatorUtils.SourceFile; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java index 6660e8f23..895bbd2b2 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java @@ -89,7 +89,6 @@ import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.filesystem.ManagedFileAccess; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; import org.hl7.fhir.utilities.npm.CommonPackages; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.NpmPackage; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/ProfileLoader.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/ProfileLoader.java index 539598ad8..b73684eb6 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/ProfileLoader.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/ProfileLoader.java @@ -9,7 +9,6 @@ import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.filesystem.ManagedFileAccess; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; public class ProfileLoader { public static byte[] loadProfileSource(String src) throws FHIRException, IOException { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ipa/IPAValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ipa/IPAValidator.java index 828b03d47..327567cc0 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ipa/IPAValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ipa/IPAValidator.java @@ -9,7 +9,6 @@ import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.elementmodel.JsonParser; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java index 808baf51e..ded31ec63 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java @@ -76,7 +76,6 @@ import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.filesystem.ManagedFileAccess; import org.hl7.fhir.utilities.http.HTTPResult; import org.hl7.fhir.utilities.http.ManagedWebAccess; -import org.hl7.fhir.utilities.http.SimpleHTTPClient; import org.hl7.fhir.utilities.json.JsonException; import org.hl7.fhir.utilities.json.JsonTrackingParser; import org.hl7.fhir.utilities.json.JsonUtilities; diff --git a/pom.xml b/pom.xml index df6326f1c..8316373e6 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ 1.26.0 32.0.1-jre 6.4.1 - 1.5.7 + 1.5.8-SNAPSHOT 2.17.0 5.9.2 1.8.2 diff --git a/security.md b/security.md index b277a6740..71af2368f 100644 --- a/security.md +++ b/security.md @@ -21,8 +21,13 @@ restricting path access to particular directories. # Network access The library will access the web to download needed collateral, or to access terminology resources or servers. -All access is by http(s) using the Apache... library, and is controlled by the class XXXX where you can -turn all network access off. +All access is by http(s) using base java http library, and is controlled by the class ManagedWebAccess. You can +set the static features of this class to completely cut the library off from the +web, or provide your own web accessor, or limit the web resources accessed +to particular domains or sub-domains. See ManagedWebAccess for details. + +Note that for legacy reasons, network access can also be prohibited using +FhirSettings.setProhibitNetworkAccess(), but this is deprecated. # Logging