Merge pull request #1096 from hapifhir/gg-202301-npm-auth

Rework Package API to allow for authentication on package servers
This commit is contained in:
Grahame Grieve 2023-01-31 18:38:05 +11:00 committed by GitHub
commit 54a883254d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 85 additions and 33 deletions

View File

@ -24,6 +24,7 @@ import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.utilities.npm.NpmPackage;
import org.hl7.fhir.utilities.npm.PackageClient; import org.hl7.fhir.utilities.npm.PackageClient;
import org.hl7.fhir.utilities.npm.PackageInfo; import org.hl7.fhir.utilities.npm.PackageInfo;
import org.hl7.fhir.utilities.npm.PackageServer;
import org.hl7.fhir.utilities.npm.ToolsVersion; import org.hl7.fhir.utilities.npm.ToolsVersion;
import org.hl7.fhir.utilities.xml.XMLUtil; import org.hl7.fhir.utilities.xml.XMLUtil;
import org.w3c.dom.Document; import org.w3c.dom.Document;
@ -108,7 +109,7 @@ public class PackageVisitor {
public void visitPackages() throws IOException, ParserConfigurationException, SAXException { public void visitPackages() throws IOException, ParserConfigurationException, SAXException {
System.out.println("Finding packages"); System.out.println("Finding packages");
pc = new PackageClient(PackageClient.PRIMARY_SERVER); pc = new PackageClient(PackageServer.primaryServer());
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION); pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
Map<String, String> cpidMap = getAllCIPackages(); Map<String, String> cpidMap = getAllCIPackages();

View File

@ -18,8 +18,8 @@ import org.slf4j.LoggerFactory;
public abstract class BasePackageCacheManager implements IPackageCacheManager { public abstract class BasePackageCacheManager implements IPackageCacheManager {
private static final Logger ourLog = LoggerFactory.getLogger(BasePackageCacheManager.class); private static final Logger ourLog = LoggerFactory.getLogger(BasePackageCacheManager.class);
private List<String> myPackageServers = new ArrayList<>(); protected List<PackageServer> myPackageServers = new ArrayList<>();
private Function<String, PackageClient> myClientFactory = address -> new PackageClient(address); private Function<PackageServer, PackageClient> myClientFactory = server -> new PackageClient(server);
protected boolean silent; protected boolean silent;
/** /**
@ -32,20 +32,20 @@ public abstract class BasePackageCacheManager implements IPackageCacheManager {
/** /**
* Provide a new client factory implementation * Provide a new client factory implementation
*/ */
public void setClientFactory(Function<String, PackageClient> theClientFactory) { public void setClientFactory(Function<PackageServer, PackageClient> theClientFactory) {
Validate.notNull(theClientFactory, "theClientFactory must not be null"); Validate.notNull(theClientFactory, "theClientFactory must not be null");
myClientFactory = theClientFactory; myClientFactory = theClientFactory;
} }
public List<String> getPackageServers() { public List<PackageServer> getPackageServers() {
return myPackageServers; return myPackageServers;
} }
/** /**
* Add a package server that can be used to fetch remote packages * Add a package server that can be used to fetch remote packages
*/ */
public void addPackageServer(@Nonnull String thePackageServer) { public void addPackageServer(@Nonnull PackageServer thePackageServer) {
Validate.notBlank(thePackageServer, "thePackageServer must not be null or empty"); Validate.notNull(thePackageServer, "thePackageServer must not be null or empty");
if (!myPackageServers.contains(thePackageServer)) { if (!myPackageServers.contains(thePackageServer)) {
myPackageServers.add(thePackageServer); myPackageServers.add(thePackageServer);
} }
@ -66,8 +66,8 @@ public abstract class BasePackageCacheManager implements IPackageCacheManager {
@Nullable @Nullable
protected InputStreamWithSrc loadFromPackageServer(String id, String version) { protected InputStreamWithSrc loadFromPackageServer(String id, String version) {
for (String nextPackageServer : getPackageServers()) { for (PackageServer nextPackageServer : getPackageServers()) {
if (okToUsePackageServer(nextPackageServer, id)) { if (okToUsePackageServer(nextPackageServer.getUrl(), id)) {
PackageClient packageClient = myClientFactory.apply(nextPackageServer); PackageClient packageClient = myClientFactory.apply(nextPackageServer);
try { try {
if (Utilities.noString(version)) { if (Utilities.noString(version)) {
@ -110,7 +110,7 @@ public abstract class BasePackageCacheManager implements IPackageCacheManager {
return npm.canonical(); return npm.canonical();
} }
for (String nextPackageServer : getPackageServers()) { for (PackageServer nextPackageServer : getPackageServers()) {
result = getPackageUrl(packageId, nextPackageServer); result = getPackageUrl(packageId, nextPackageServer);
if (result != null) { if (result != null) {
return result; return result;
@ -121,7 +121,7 @@ public abstract class BasePackageCacheManager implements IPackageCacheManager {
} }
private String getPackageUrl(String packageId, String server) throws IOException { private String getPackageUrl(String packageId, PackageServer server) throws IOException {
PackageClient pc = myClientFactory.apply(server); PackageClient pc = myClientFactory.apply(server);
List<PackageInfo> res = pc.search(packageId, null, null, false); List<PackageInfo> res = pc.search(packageId, null, null, false);
if (res.size() == 0) { if (res.size() == 0) {
@ -136,7 +136,7 @@ public abstract class BasePackageCacheManager implements IPackageCacheManager {
public String getPackageId(String canonicalUrl) throws IOException { public String getPackageId(String canonicalUrl) throws IOException {
String result = null; String result = null;
for (String nextPackageServer : getPackageServers()) { for (PackageServer nextPackageServer : getPackageServers()) {
result = getPackageId(canonicalUrl, nextPackageServer); result = getPackageId(canonicalUrl, nextPackageServer);
if (result != null) { if (result != null) {
break; break;
@ -146,7 +146,7 @@ public abstract class BasePackageCacheManager implements IPackageCacheManager {
return result; return result;
} }
private String getPackageId(String canonical, String server) throws IOException { private String getPackageId(String canonical, PackageServer server) throws IOException {
if (canonical == null) { if (canonical == null) {
return null; return null;
} }

View File

@ -107,8 +107,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
*/ */
@Deprecated @Deprecated
public FilesystemPackageCacheManager(boolean userMode, int toolsVersion) throws IOException { public FilesystemPackageCacheManager(boolean userMode, int toolsVersion) throws IOException {
addPackageServer(PackageClient.PRIMARY_SERVER); myPackageServers.addAll(PackageServer.publicServers());
addPackageServer(PackageClient.SECONDARY_SERVER);
if (userMode) if (userMode)
cacheFolder = Utilities.path(System.getProperty("user.home"), ".fhir", "packages"); cacheFolder = Utilities.path(System.getProperty("user.home"), ".fhir", "packages");
@ -122,8 +121,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
} }
public FilesystemPackageCacheManager(boolean userMode) throws IOException { public FilesystemPackageCacheManager(boolean userMode) throws IOException {
addPackageServer(PackageClient.PRIMARY_SERVER); myPackageServers.addAll(PackageServer.publicServers());
addPackageServer(PackageClient.SECONDARY_SERVER);
if (userMode) if (userMode)
cacheFolder = Utilities.path(System.getProperty("user.home"), ".fhir", "packages"); cacheFolder = Utilities.path(System.getProperty("user.home"), ".fhir", "packages");
@ -218,7 +216,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
} }
} }
private void listSpecs(Map<String, String> specList, String server) throws IOException { private void listSpecs(Map<String, String> specList, PackageServer server) throws IOException {
PackageClient pc = new PackageClient(server); PackageClient pc = new PackageClient(server);
List<PackageInfo> matches = pc.search(null, null, null, false); List<PackageInfo> matches = pc.search(null, null, null, false);
for (PackageInfo m : matches) { for (PackageInfo m : matches) {
@ -244,9 +242,9 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
} }
public String getLatestVersion(String id) throws IOException { public String getLatestVersion(String id) throws IOException {
for (String nextPackageServer : getPackageServers()) { for (PackageServer nextPackageServer : getPackageServers()) {
// special case: // special case:
if (!(Utilities.existsInList(id,CommonPackages.ID_PUBPACK, "hl7.terminology.r5") && PackageClient.PRIMARY_SERVER.equals(nextPackageServer))) { if (!(Utilities.existsInList(id,CommonPackages.ID_PUBPACK, "hl7.terminology.r5") && PackageServer.PRIMARY_SERVER.equals(nextPackageServer.getUrl()))) {
PackageClient pc = new PackageClient(nextPackageServer); PackageClient pc = new PackageClient(nextPackageServer);
try { try {
return pc.getLatestVersion(id); return pc.getLatestVersion(id);
@ -488,7 +486,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
for (NpmPackage p : temporaryPackages) { for (NpmPackage p : temporaryPackages) {
specList.put(p.name(), p.canonical()); specList.put(p.name(), p.canonical());
} }
for (String next : getPackageServers()) { for (PackageServer next : getPackageServers()) {
listSpecs(specList, next); listSpecs(specList, next);
} }
addCIBuildSpecs(specList); addCIBuildSpecs(specList);
@ -945,7 +943,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
if (packageInstalled(id, ver)) { if (packageInstalled(id, ver)) {
return true; return true;
} }
for (String s : getPackageServers()) { for (PackageServer s : getPackageServers()) {
if (new PackageClient(s).exists(id, ver)) { if (new PackageClient(s).exists(id, ver)) {
return true; return true;
} }

View File

@ -26,16 +26,15 @@ public class PackageClient {
public static final String PRIMARY_SERVER = "http://packages.fhir.org"; private PackageServer server;
public static final String SECONDARY_SERVER = "https://packages2.fhir.org/packages";
private String address;
private String cacheFolder; private String cacheFolder;
private String address;
public PackageClient(String address) { public PackageClient(PackageServer server) {
super(); super();
this.address = address; this.server = server;
address = server.getUrl();
try { try {
cacheFolder = Utilities.path(System.getProperty("user.home"), ".fhir", "package-client"); cacheFolder = Utilities.path(System.getProperty("user.home"), ".fhir", "package-client");
Utilities.createDirectory(cacheFolder); Utilities.createDirectory(cacheFolder);

View File

@ -20,8 +20,8 @@ public class PackageScanner {
List<String> output = new ArrayList<>(); List<String> output = new ArrayList<>();
Set<String> packages = new HashSet<>(); Set<String> packages = new HashSet<>();
processServer("http://packages.fhir.org", output, packages); processServer(PackageServer.primaryServer(), output, packages);
processServer("http://packages2.fhir.org/packages", output, packages); processServer(PackageServer.secondaryServer(), output, packages);
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
for (String s : output) { for (String s : output) {
@ -32,7 +32,7 @@ public class PackageScanner {
TextFile.stringToFile(b.toString(), Utilities.path("[tmp]", "packages.csv")); TextFile.stringToFile(b.toString(), Utilities.path("[tmp]", "packages.csv"));
} }
public static void processServer(String server, List<String> output, Set<String> packages) throws IOException { public static void processServer(PackageServer server, List<String> output, Set<String> packages) throws IOException {
System.out.println("Server: "+server); System.out.println("Server: "+server);
PackageClient client = new PackageClient(server); PackageClient client = new PackageClient(server);
List<PackageInfo> list = client.search(null, null, null, false); List<PackageInfo> list = client.search(null, null, null, false);

View File

@ -0,0 +1,53 @@
package org.hl7.fhir.utilities.npm;
import java.util.ArrayList;
import java.util.List;
public class PackageServer {
public enum PackageServerAuthenticationMode {
NONE
}
public PackageServer(String url) {
this.url = url;
mode = PackageServerAuthenticationMode.NONE;
}
private String url;
private PackageServerAuthenticationMode mode;
private String username;
private String password;
public String getUrl() {
return url;
}
public PackageServerAuthenticationMode getMode() {
return mode;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public static final String PRIMARY_SERVER = "http://packages.fhir.org";
public static final String SECONDARY_SERVER = "https://packages2.fhir.org/packages";
public static PackageServer primaryServer() {
return new PackageServer(PRIMARY_SERVER);
}
public static PackageServer secondaryServer() {
return new PackageServer(SECONDARY_SERVER);
}
public static List<PackageServer> publicServers() {
List<PackageServer> servers = new ArrayList<>();
servers.add(primaryServer());
servers.add(secondaryServer());
return servers;
}
}

View File

@ -13,7 +13,7 @@ import org.junit.jupiter.api.Test;
public class PackageClientTest implements ResourceLoaderTests { public class PackageClientTest implements ResourceLoaderTests {
PackageClient packageClient = new PackageClient(PackageClient.PRIMARY_SERVER); PackageClient packageClient = new PackageClient(PackageServer.primaryServer());
private void assertExpectedFields(final PackageInfo packageInfo) { private void assertExpectedFields(final PackageInfo packageInfo) {
assertEquals("dummy.package", packageInfo.getId()); assertEquals("dummy.package", packageInfo.getId());

View File

@ -11,6 +11,7 @@ import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.utilities.npm.NpmPackage;
import org.hl7.fhir.utilities.npm.PackageClient; import org.hl7.fhir.utilities.npm.PackageClient;
import org.hl7.fhir.utilities.npm.PackageInfo; import org.hl7.fhir.utilities.npm.PackageInfo;
import org.hl7.fhir.utilities.npm.PackageServer;
import org.hl7.fhir.utilities.npm.ToolsVersion; import org.hl7.fhir.utilities.npm.ToolsVersion;
public class PackageValidator { public class PackageValidator {
@ -22,7 +23,7 @@ public class PackageValidator {
private void execute() throws IOException { private void execute() throws IOException {
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION); FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
PackageClient pc = new PackageClient(PackageClient.PRIMARY_SERVER); PackageClient pc = new PackageClient(PackageServer.primaryServer());
for (PackageInfo t : pc.search(null, null, null, false)) { for (PackageInfo t : pc.search(null, null, null, false)) {
System.out.println("Check Package "+t.getId()); System.out.println("Check Package "+t.getId());
List<PackageInfo> vl = pc.getVersions(t.getId()); List<PackageInfo> vl = pc.getVersions(t.getId());