[java-identity-provider] branch main updated: IDP-1664 - Support Module service API
Scott Cantor
cantor.2 at osu.edu
Wed Sep 2 17:35:06 UTC 2020
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=28150d57dcb952e82e0956e27de57e7b2451623c
The following commit(s) were added to refs/heads/main by this push:
new 28150d57d IDP-1664 - Support Module service API
28150d57d is described below
commit 28150d57dcb952e82e0956e27de57e7b2451623c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Sep 2 13:34:55 2020 -0400
IDP-1664 - Support Module service API
https://issues.shibboleth.net/jira/browse/IDP-1664
Add HTTP/HTTPS source support and adjust tests.
---
idp-admin-api/pom.xml | 11 +++++
.../shibboleth/idp/module/AbstractIdPModule.java | 55 +++++++++++++++++++++-
.../net/shibboleth/idp/module/IdPModuleTest.java | 39 +++++++++++++--
idp-admin-api/src/test/resources/logback-test.xml | 2 +-
.../net/shibboleth/idp/module/module.properties | 2 +-
.../net/shibboleth/idp/module/repo-entity.crt | 39 +++++++++++++++
6 files changed, 140 insertions(+), 8 deletions(-)
diff --git a/idp-admin-api/pom.xml b/idp-admin-api/pom.xml
index ef6112f69..d5820914d 100644
--- a/idp-admin-api/pom.xml
+++ b/idp-admin-api/pom.xml
@@ -71,6 +71,17 @@
<!-- Runtime Dependencies -->
<!-- Test Dependencies -->
+ <dependency>
+ <groupId>net.shibboleth.utilities</groupId>
+ <artifactId>java-support</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${opensaml.groupId}</groupId>
+ <artifactId>opensaml-security-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
diff --git a/idp-admin-api/src/main/java/net/shibboleth/idp/module/AbstractIdPModule.java b/idp-admin-api/src/main/java/net/shibboleth/idp/module/AbstractIdPModule.java
index 2883d073a..94532d1d1 100644
--- a/idp-admin-api/src/main/java/net/shibboleth/idp/module/AbstractIdPModule.java
+++ b/idp-admin-api/src/main/java/net/shibboleth/idp/module/AbstractIdPModule.java
@@ -22,6 +22,8 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
@@ -36,6 +38,11 @@ import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.opensaml.security.httpclient.HttpClientSecuritySupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -225,12 +232,56 @@ public abstract class AbstractIdPModule implements IdPModule {
throws IOException {
if (source.startsWith("https://") || source.startsWith("http://")) {
- // TODO http
- return null;
+ try {
+ return connect(moduleContext, new URI(source));
+ } catch (final URISyntaxException e) {
+ throw new IOException(e);
+ }
}
return getClass().getResourceAsStream(source);
}
+ /**
+ * Connect to the given URI and return the HTTP response stream.
+ *
+ * @param moduleContext module context
+ * @param uri resource location
+ *
+ * @return input stream of response
+ *
+ * @throws IOException on errors
+ */
+ @Nonnull private InputStream connect(@Nonnull final ModuleContext moduleContext, @Nonnull final URI uri)
+ throws IOException {
+
+ final HttpClientContext clientContext = HttpClientContext.create();
+ HttpClientSecuritySupport.marshalSecurityParameters(clientContext,
+ moduleContext.getHttpClientSecurityParameters(), true);
+ HttpResponse response = null;
+ try {
+ log.debug("Module {} fetching HTTP resource {}", getId(), uri);
+ final HttpGet request = new HttpGet(uri);
+ response = moduleContext.getHttpClient().execute(request, clientContext);
+ HttpClientSecuritySupport.checkTLSCredentialEvaluated(clientContext, request.getURI().getScheme());
+ if (response.getStatusLine().getStatusCode() != 200) {
+ throw new IOException("HTTP request was unsuccessful");
+ }
+
+ // The response socket should be closed after the stream is closed.
+ final InputStream ret = response.getEntity().getContent();
+ response = null;
+ return ret;
+ } finally {
+ if (response != null && CloseableHttpResponse.class.isInstance(response)) {
+ try {
+ CloseableHttpResponse.class.cast(response).close();
+ } catch (final IOException e) {
+ log.debug("Error closing HttpResponse", e);
+ }
+ }
+ }
+ }
+
/**
* Access the destination as a stream.
*
diff --git a/idp-admin-api/src/test/java/net/shibboleth/idp/module/IdPModuleTest.java b/idp-admin-api/src/test/java/net/shibboleth/idp/module/IdPModuleTest.java
index dbdffd0b7..75a02ee78 100644
--- a/idp-admin-api/src/test/java/net/shibboleth/idp/module/IdPModuleTest.java
+++ b/idp-admin-api/src/test/java/net/shibboleth/idp/module/IdPModuleTest.java
@@ -17,24 +17,40 @@ package net.shibboleth.idp.module;
*/
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
+import java.net.URISyntaxException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.Optional;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.ServiceLoader.Provider;
+import org.opensaml.security.credential.impl.StaticCredentialResolver;
+import org.opensaml.security.httpclient.HttpClientSecurityParameters;
+import org.opensaml.security.httpclient.impl.SecurityEnhancedHttpClientSupport;
+import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.security.trust.impl.ExplicitKeyTrustEngine;
+import org.opensaml.security.x509.BasicX509Credential;
+import org.opensaml.security.x509.X509Credential;
+import org.opensaml.security.x509.X509Support;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import com.google.common.io.ByteStreams;
+
import net.shibboleth.idp.module.IdPModule.ModuleResource;
+import net.shibboleth.utilities.java.support.httpclient.HttpClientBuilder;
+import net.shibboleth.utilities.java.support.repository.RepositorySupport;
/**
* Unit tests exercising module code.
@@ -51,7 +67,7 @@ public class IdPModuleTest {
private ModuleContext context;
@BeforeMethod
- public void setUp() throws IOException {
+ public void setUp() throws Exception {
final ServiceLoader<IdPModule> loader = ServiceLoader.load(IdPModule.class);
final Optional<Provider<IdPModule>> opt =
loader.stream().filter(p -> TestModule.class.equals(p.type())).findFirst();
@@ -61,6 +77,14 @@ public class IdPModuleTest {
testHome = Files.createTempDirectory("test-idp-home-");
context = new ModuleContext(testHome);
+
+ final HttpClientBuilder builder = new HttpClientBuilder();
+ builder.setTLSSocketFactory(SecurityEnhancedHttpClientSupport.buildTLSSocketFactory(true, false));
+ context.setHttpClient(builder.buildClient());
+
+ final HttpClientSecurityParameters params = new HttpClientSecurityParameters();
+ params.setTLSTrustEngine(buildExplicitKeyTrustEngine());
+ context.setHttpClientSecurityParameters(params);
}
@AfterMethod
@@ -92,7 +116,6 @@ public class IdPModuleTest {
@Test
public void testBadModules() {
-
final ServiceLoader<IdPModule> loader = ServiceLoader.load(IdPModule.class);
Optional<Provider<IdPModule>> opt =
@@ -117,7 +140,6 @@ public class IdPModuleTest {
@Test
public void testModule() {
-
Assert.assertEquals(testModule.getId(), TestModule.class.getName());
Assert.assertEquals(testModule.getName(), "Test module");
Assert.assertEquals(testModule.getURL().toString(), "https://wiki.shibboleth.net/confluence/display/IDP4/Home");
@@ -130,7 +152,8 @@ public class IdPModuleTest {
Assert.assertEquals(resource.getDestination(), Path.of("conf/test.xml"));
resource = resources.next();
- Assert.assertEquals(resource.getSource(), "/net/shibboleth/idp/module/test.vm");
+ Assert.assertEquals(resource.getSource(),
+ RepositorySupport.buildHTTPSResourceURL("java-identity-provider", "idp-admin-api/src/test/resources/net/shibboleth/idp/module/test.vm"));
Assert.assertEquals(resource.getDestination(), Path.of("views/test.vm"));
}
@@ -226,4 +249,12 @@ public class IdPModuleTest {
Assert.assertEquals(vel, VEL_DATA);
}
+ private static TrustEngine<? super X509Credential> buildExplicitKeyTrustEngine() throws URISyntaxException, CertificateException, IOException {
+
+ final InputStream certStream = IdPModuleTest.class.getResourceAsStream("/net/shibboleth/idp/module/repo-entity.crt");
+ final X509Certificate entityCert = X509Support.decodeCertificate(ByteStreams.toByteArray(certStream));
+ final X509Credential entityCredential = new BasicX509Credential(entityCert);
+ return new ExplicitKeyTrustEngine(new StaticCredentialResolver(entityCredential));
+
+ }
}
\ No newline at end of file
diff --git a/idp-admin-api/src/test/resources/logback-test.xml b/idp-admin-api/src/test/resources/logback-test.xml
index 8f891b483..ec68238c5 100644
--- a/idp-admin-api/src/test/resources/logback-test.xml
+++ b/idp-admin-api/src/test/resources/logback-test.xml
@@ -10,7 +10,7 @@
</appender>
<root>
- <level value="DEBUG" />
+ <level value="INFO" />
<appender-ref ref="STDOUT" />
</root>
diff --git a/idp-admin-api/src/test/resources/net/shibboleth/idp/module/module.properties b/idp-admin-api/src/test/resources/net/shibboleth/idp/module/module.properties
index ad2b75892..feff89f4a 100644
--- a/idp-admin-api/src/test/resources/net/shibboleth/idp/module/module.properties
+++ b/idp-admin-api/src/test/resources/net/shibboleth/idp/module/module.properties
@@ -10,7 +10,7 @@ net.shibboleth.idp.module.TestModule.1.src = /net/shibboleth/idp/module/test.xml
net.shibboleth.idp.module.TestModule.1.dest = conf/test.xml
net.shibboleth.idp.module.TestModule.1.replace = true
-net.shibboleth.idp.module.TestModule.2.src = /net/shibboleth/idp/module/test.vm
+net.shibboleth.idp.module.TestModule.2.src = https://test.shibboleth.net/git/view/?p=java-identity-provider.git&a=blob_plain&f=idp-admin-api/src/test/resources/net/shibboleth/idp/module/test.vm&hb=HEAD
net.shibboleth.idp.module.TestModule.2.dest = views/test.vm
# Broken modules due to dangerous resources
diff --git a/idp-admin-api/src/test/resources/net/shibboleth/idp/module/repo-entity.crt b/idp-admin-api/src/test/resources/net/shibboleth/idp/module/repo-entity.crt
new file mode 100644
index 000000000..b9834258f
--- /dev/null
+++ b/idp-admin-api/src/test/resources/net/shibboleth/idp/module/repo-entity.crt
@@ -0,0 +1,39 @@
+## This is the current *.shibboleth.net wildcard cert, expires Jan 2019.
+
+-----BEGIN CERTIFICATE-----
+MIIGazCCBFOgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwaTELMAkGA1UEBhMCVVMx
+DTALBgNVBAgMBE9oaW8xHjAcBgNVBAoMFVNoaWJib2xldGggQ29uc29ydGl1bTEr
+MCkGA1UEAwwiU2hpYmJvbGV0aCBQcm9qZWN0IEludGVybWVkaWF0ZSBDQTAeFw0x
+ODEyMTExNTE5NDlaFw0zODEyMDYxNTE5NDlaMFoxCzAJBgNVBAYTAlVTMQ0wCwYD
+VQQIDARPaGlvMR4wHAYDVQQKDBVTaGliYm9sZXRoIENvbnNvcnRpdW0xHDAaBgNV
+BAMME3Rlc3Quc2hpYmJvbGV0aC5uZXQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
+ggIKAoICAQDI39TBFEbOkf0Bb2h/qnG4bbJRF5Ga9OBgSAxPsx2PNgVmf1cvJYlq
+uRCzATu3O4PPclomow5VU7hB+umpk2s03FHejUtO8w85qQx7bkSeyfLpMYloX3SD
+AWDFSpw54Tg2Dfja6jYLnE0aYWUCTXjcFJEIrT0QP1Azdk8b9PeKLqGIagECUMzC
+UjmJxEcyqhbe6mB7tdSsBng+R4DRdVdouN4rtHknNuEyAc5eEppGxY33KXhElYol
+4IK6YxAqXI6iQIDdcVxrH061/iKh7qT1bCAEmzeeoS4st4v4oyIhxUk7yUxYOuFc
+NhYUd5U93Ws4P8xPFzcPhD2TIZDAS/bnm2EJ+JxLG6Gp1jhBN5qTpdTPWiG9+Tmm
+HFuYOrSefgZk0edkJhe0dycfV/FWFX2fNrmkpQhyPQzb3ZyZ5mACn020TXDaF5o3
+fX8ndLl4RghTORJs5n51TuLX85DEeZWkJe5f8Hsip1mpmxlMTl9QMqHrN70n5gBi
+uCYo9g/Jw5xoropCq7Jri9K9FWtbORncUIXutsTVo+fXeHZ6IDRoovR004gHHEJ7
+ks46fZQYNbd8bB/mPlCdYiFyJnfUiOu89O5aLqvhrJNgPUhMt/gmhSV7zw+/3/cd
+o7pwWH2h2ObuS8v8gVUZAE04tefqRJZEB0YsWA3DASDT7nVqndOp2QIDAQABo4IB
+KjCCASYwCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4QgEN
+BCYWJE9wZW5TU0wgR2VuZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNVHQ4E
+FgQUG3Vg4ubsJVaylBUCPtqVc9mHWfYwgYwGA1UdIwSBhDCBgYAUELzfpij2mkrs
+9B4CEsXYmoN6cKuhZaRjMGExCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARPaGlvMR4w
+HAYDVQQKDBVTaGliYm9sZXRoIENvbnNvcnRpdW0xIzAhBgNVBAMMGlNoaWJib2xl
+dGggUHJvamVjdCBUZXN0IENBggIQADAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAww
+CgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggIBAFZQF7KzKGSPieV2eQWbFt30
+kVZzVe/T5UAvrr8n7mRqMfye4QtHHOVM3MHvZv93AXVUQU4PH9KPGtv7poEtwNWk
+7hNbq74z5x5tSvE0EYYI9UMolDL6il+QR5AgLw7YqgMmPPhtm+crmLg8+uMoQDyU
+uSH8ej4rMrdhL2xKlgvL/rhWycpYu1cFLmeolljOZGqr7ITwWJ06BQsLtt4/cyYj
+WiVldHQRZMGAuHLHlX+ukaEg7Gc/N7o936bS5d7AqXwtmtkXiA8An5q5rhncEK1G
+kwUUQN2y5iyx/nD4B2k1IcgFlu/bM4iXZQtmMUtLptUqRssuxS45ukiweiM9UU8n
+WxyxJMzFTctJJ2f/y4Bg5ggsr4WQU/YhoDaQVYxyjXiBt3oT+7eqsoep9HK9xwbG
+xriLzrlao+K3EcKA3vjKGYh15gpEDUbn0Cr5V74TUSdkHjhG7ocaJ5u9/vCS4+AR
+iU5ge2zN6QcwoZKT8+8XGKeXqVc/3hXeXTn3FyvMitPDZsmg8wUhnb/pq5MyKqUA
+bNse4a7oGAeAUGkLf4Q+eLCLSZmL5udrGXdHIffFYqZVcZS+zVWQ1TRfodTDPkFb
+KTz1mcr4KjLNCtplu4CfFpHwC20uk3hPEslOUd+ugj0+HGNH93L7H0WL1GDQoCPh
+RcdRISVwORcD/dit15zD
+-----END CERTIFICATE-----
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list