[java-identity-provider] branch main updated: IDP-2073 Consider enabling the installer to download new versions
Rod Widdowson
rdw at steadingsoftware.com
Mon Jun 12 13:04:55 UTC 2023
This is an automated email from the git hooks/post-receive script.
rdw 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=483d73013e6ba40e7d766fbf8e53aeb9ce86884b
The following commit(s) were added to refs/heads/main by this push:
new 483d73013 IDP-2073 Consider enabling the installer to download new versions
483d73013 is described below
commit 483d73013e6ba40e7d766fbf8e53aeb9ce86884b
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Mon Jun 12 13:51:40 2023 +0100
IDP-2073 Consider enabling the installer to download new versions
https://shibboleth.atlassian.net/browse/IDP-2073
Introduce a bean and associated wiring to reach out and check the update status
at idp startup.
---
.../net/shibboleth/idp/admin/impl/IdPInfo.java | 57 +++++++
.../idp/admin/impl/ReportUpdateStatus.java | 165 +++++++++++++++++++++
.../net/shibboleth/idp/conf/admin-system.xml | 16 +-
.../net/shibboleth/idp/module/conf/idp.properties | 3 +
idp-installer/pom.xml | 7 +
.../idp/installer/impl/UpdateIdPCLI.java | 36 +----
6 files changed, 250 insertions(+), 34 deletions(-)
diff --git a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/IdPInfo.java b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/IdPInfo.java
new file mode 100644
index 000000000..f2ba9fb01
--- /dev/null
+++ b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/IdPInfo.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.admin.impl;
+
+import java.util.Properties;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.profile.installablecomponent.InstallableComponentInfo;
+import net.shibboleth.profile.installablecomponent.InstallableComponentVersion;
+
+/** Implementation of {@link InstallableComponentInfo} for an IdP Version. This is keyed in
+ * to the format of the idp-versions.properties file (which doesn't specify max and min "supported IdP versions". */
+public final class IdPInfo extends InstallableComponentInfo {
+
+ /** The "plugin Id" to look up idp versions with. */
+ @Nonnull public static String IDP_PLUGIN_ID = "net.shibboleth.idp";
+
+ /**
+ * Constructor.
+ * @param props The property file to populate from
+ */
+ public IdPInfo(@Nonnull Properties props) {
+ super(IDP_PLUGIN_ID, props);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected InstallableComponentVersion getMaxVersion(@Nonnull Properties props, @Nonnull String version) {
+ // The maximum version that version "us" can be installed in is "us" (a re-intall).
+ return new InstallableComponentVersion(version);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable
+ protected InstallableComponentVersion getMinVersion(@Nonnull Properties props, @Nonnull String version) {
+ // We can always be on anything from V4.0.0
+ return new InstallableComponentVersion(4,0,0);
+ }
+}
diff --git a/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/ReportUpdateStatus.java b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/ReportUpdateStatus.java
new file mode 100644
index 000000000..5615b5cc5
--- /dev/null
+++ b/idp-admin-impl/src/main/java/net/shibboleth/idp/admin/impl/ReportUpdateStatus.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.admin.impl;
+
+import java.net.URL;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.hc.client5.http.classic.HttpClient;
+import org.opensaml.security.httpclient.HttpClientSecurityParameters;
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.Version;
+import net.shibboleth.profile.installablecomponent.InstallableComponentInfo;
+import net.shibboleth.profile.installablecomponent.InstallableComponentInfo.VersionInfo;
+import net.shibboleth.profile.installablecomponent.InstallableComponentSupport;
+import net.shibboleth.profile.installablecomponent.InstallableComponentSupport.SupportLevel;
+import net.shibboleth.profile.installablecomponent.InstallableComponentVersion;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * A class to reach out and find out whether we are up to date.
+ */
+public class ReportUpdateStatus extends AbstractIdentifiableInitializableComponent implements Runnable {
+
+ /** Logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(ReportUpdateStatus.class);
+
+ /** Where to look for update information. */
+ @Nonnull private List<URL> updateUrls = CollectionSupport.emptyList();
+
+ /** Are we to run? */
+ private boolean enabled;
+
+ /** How to reach out. */
+ @NonnullAfterInit private HttpClient httpClient;
+
+ /** any security parameters needed. */
+ @Nullable private HttpClientSecurityParameters securityParams;
+
+ /** Set where to look.
+ * @param urls what to set.
+ */
+ public void setUpdateUrls(@Nullable final List<URL> urls) {
+ if (urls == null || urls.isEmpty()) {
+ log.error("Emopty URL update listr specified");
+ } else {
+ updateUrls = urls;
+ }
+ }
+
+ /** Set any {@link HttpClientSecurityParameters}.
+ * @param params what to set.
+ */
+ public void setSecurityParams(@Nullable final HttpClientSecurityParameters params) {
+ securityParams = params;
+ }
+
+ /** Set the {@link HttpClient} to use.
+ * @param client what to set.
+ */
+ public void setHttpClient(@Nonnull final HttpClient client) {
+ httpClient = Constraint.isNotNull(client, "HttpClient cannot be null");
+ }
+
+ /** Are we going to do anything?
+ * @param on are we enabled
+ */
+ public void setEnabled(final boolean on) {
+ enabled = on;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ if (!enabled) {
+ return;
+ }
+ if (httpClient == null) {
+ log.error("Http Client was not set");
+ throw new ComponentInitializationException("Http Client was not set");
+ }
+ if (updateUrls.isEmpty()) {
+ log.error("No Update Urls set");
+ throw new ComponentInitializationException("No Update Urls set");
+ }
+
+ final ExecutorService svc = Executors.newSingleThreadExecutor();
+ svc.execute(this);
+ svc.shutdown();
+ }
+
+ /** {@inheritDoc}
+ * Do the lookup, but in a different thread so as to not slow down startup.
+ */
+ @Override
+ public void run() {
+ try {
+ String versionStr = Version.getVersion();
+ if (versionStr == null) {
+ log.error("Could not find Current IdP Version");
+ return;
+ }
+ @Nonnull final InstallableComponentVersion version = new InstallableComponentVersion(versionStr);
+ assert httpClient!=null;
+ final Properties properties = InstallableComponentSupport.loadInfo(updateUrls, httpClient, securityParams);
+ if (properties == null) {
+ log.error("Could not located Idp update information");
+ return;
+ }
+ final InstallableComponentInfo info = new IdPInfo(properties);
+
+ final InstallableComponentVersion newIdPVersion = InstallableComponentSupport.getBestVersion(version, version, info);
+ if (newIdPVersion == null) {
+ log.info("No Upgrade available from {}", version);
+ } else {
+ log.warn("Version {} can be upgraded to {}", version, newIdPVersion);
+ }
+ final VersionInfo verInfo = info.getAvailableVersions().get(version);
+ if (verInfo == null) {
+ log.warn("Could not locate version info for version {}", version);
+ } else {
+ final SupportLevel sl = verInfo.getSupportLevel();
+ switch (sl) {
+ case Current:
+ log.debug("Version {} is current");
+ break;
+ case Secadv:
+ log.error("Version {} has secuorty alerts again it.", version);
+ break;
+ default:
+ log.warn("Support level for {} is {}", version, sl);
+ break;
+ }
+ }
+ } catch (final Throwable t) {
+ log.error("Check for update status failed unexpectedly", t);
+ }
+ }
+}
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/admin-system.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/admin-system.xml
index 501a2b6e6..e6342106b 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/admin-system.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/admin-system.xml
@@ -320,5 +320,19 @@
class="net.shibboleth.shared.service.ReloadableServiceGaugeSet" lazy-init="true"
c:metricName="net.shibboleth.idp.managedbean"
p:service-ref="shibboleth.ManagedBeanService" />
-
+
+ <util:list id="shibboleth.IdPUpdateCheckUrls">
+ <value>https://shibboleth.net/downloads/identity-provider/plugins/idp-versions.properties</value>
+ <value>http://plugins.shibboleth.net/idp-versions.properties</value>
+ </util:list>
+
+ <bean id="shibboleth.UpdateStatus"
+ class="net.shibboleth.idp.admin.impl.ReportUpdateStatus"
+ lazy-init="false"
+ depends-on="shibboleth.LoggingService"
+ p:updateUrls-ref="%{idp.updateCheck.urls:shibboleth.IdPUpdateCheckUrls}"
+ p:enabled="%{idp.updateCheck.enabled:true}"
+ p:httpClient-ref="%{idp.updateCheck.httpClient:shibboleth.InternalHttpClient}"
+ p:securityParams="#{ environment.containsProperty('idp.updateCheck.httpSecurityParameters') ? getObject('idp.updateCheck.httpSecurityParameters') :null}"/>
+
</beans>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/idp.properties b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/idp.properties
index 1e37c9b71..3e2af2ba3 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/idp.properties
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/idp.properties
@@ -253,3 +253,6 @@ idp.ui.fallbackLanguages=en,fr,de
# Set false if you want SAML bindings "spelled out" in audit log
idp.audit.shortenBindings = true
+
+# Set false if you do not want the IdP to check (asynchronously) whether it can be updated when the container starts
+#idp.updateCheck.enable=true
diff --git a/idp-installer/pom.xml b/idp-installer/pom.xml
index 602985e87..c5f63eb21 100644
--- a/idp-installer/pom.xml
+++ b/idp-installer/pom.xml
@@ -51,6 +51,13 @@
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>idp-admin-impl</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
<dependency>
<groupId>net.shibboleth</groupId>
<artifactId>shib-metadata-api</artifactId>
diff --git a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/UpdateIdPCLI.java b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/UpdateIdPCLI.java
index 517a615f4..32066d28b 100644
--- a/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/UpdateIdPCLI.java
+++ b/idp-installer/src/main/java/net/shibboleth/idp/installer/impl/UpdateIdPCLI.java
@@ -43,6 +43,7 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import net.shibboleth.idp.Version;
+import net.shibboleth.idp.admin.impl.IdPInfo;
import net.shibboleth.idp.cli.AbstractIdPHomeAwareCommandLine;
import net.shibboleth.idp.installer.InstallerSupport;
import net.shibboleth.idp.installer.impl.UpdateIdPArguments.OperationType;
@@ -62,9 +63,6 @@ import net.shibboleth.shared.spring.httpclient.resource.HTTPResource;
*/
public class UpdateIdPCLI extends AbstractIdPHomeAwareCommandLine<UpdateIdPArguments> {
- /** The "plugin Id" to look up idp versions with. */
- @Nonnull public static String IDP_PLUGIN_ID = "net.shibboleth.idp";
-
/** The place we publish our keys. */
@Nonnull public static String SHIBBOLETH_SIGNING_KEYS = "http://shibboleth.net/downloads/PGP_KEYS";
@@ -273,7 +271,7 @@ public class UpdateIdPCLI extends AbstractIdPHomeAwareCommandLine<UpdateIdPArgum
assert idpHome != null;
trust.setIdpHome(idpHome);
trust.setTrustStore(args.getTruststore());
- trust.setPluginId(IDP_PLUGIN_ID);
+ trust.setPluginId(IdPInfo.IDP_PLUGIN_ID);
trust.initialize();
final Signature sig = TrustStore.signatureOf(sigStream);
if (!trust.contains(sig)) {
@@ -306,7 +304,7 @@ public class UpdateIdPCLI extends AbstractIdPHomeAwareCommandLine<UpdateIdPArgum
}
} catch (final ComponentInitializationException | IOException e) {
- getLogger().error("Could not manage truststore for [{}, {}] ", args.getIdPHome(), IDP_PLUGIN_ID, e);
+ getLogger().error("Could not manage truststore for [{}, {}] ", args.getIdPHome(), IdPInfo.IDP_PLUGIN_ID, e);
return RC_IO;
}
return RC_OK;
@@ -335,32 +333,4 @@ public class UpdateIdPCLI extends AbstractIdPHomeAwareCommandLine<UpdateIdPArgum
System.exit(runMain(args));
}
- /** Local implementaion of {@link InstallableComponentInfo} for an IdP Version. */
- private static class IdPInfo extends InstallableComponentInfo {
-
- /**
- * Constructor.
- * @param props The property file to populate from
- */
- public IdPInfo(@Nonnull Properties props) {
- super(IDP_PLUGIN_ID, props);
- }
-
- /** {@inheritDoc} */
- @Override
- @Nullable
- protected InstallableComponentVersion getMaxVersion(@Nonnull Properties props, @Nonnull String version) {
- // The maximum version that version "us" can be installed in is "us" (a re-intall).
- return new InstallableComponentVersion(version);
- }
-
- /** {@inheritDoc} */
- @Override
- @Nullable
- protected InstallableComponentVersion getMinVersion(@Nonnull Properties props, @Nonnull String version) {
- // We can always be on anything from V4.0.0
- return new InstallableComponentVersion(4,0,0);
- }
-
- }
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list