[java-identity-provider] branch main updated: IDP-1664 - Support Module service API
Scott Cantor
cantor.2 at osu.edu
Tue Sep 22 15:55:10 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=3c00e3644bc93b5ba80d7a82e31f55672f98137f
The following commit(s) were added to refs/heads/main by this push:
new 3c00e3644 IDP-1664 - Support Module service API
3c00e3644 is described below
commit 3c00e3644bc93b5ba80d7a82e31f55672f98137f
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Sep 22 11:55:07 2020 -0400
IDP-1664 - Support Module service API
https://issues.shibboleth.net/jira/browse/IDP-1664
Add i18n support to various fields and CLI.
---
.../java/net/shibboleth/idp/module/IdPModule.java | 8 ++-
.../net/shibboleth/idp/module/ModuleContext.java | 31 +++++++++++
.../idp/module/PropertyDrivenIdPModule.java | 64 ++++++++++++++++++++--
.../net/shibboleth/idp/module/IdPModuleTest.java | 15 ++++-
.../net/shibboleth/idp/module/module.properties | 3 +
.../idp/module/impl/ModuleManagerCLI.java | 5 +-
idp-war/src/main/webapp/WEB-INF/jsp/status.jsp | 2 +-
7 files changed, 118 insertions(+), 10 deletions(-)
diff --git a/idp-admin-api/src/main/java/net/shibboleth/idp/module/IdPModule.java b/idp-admin-api/src/main/java/net/shibboleth/idp/module/IdPModule.java
index 0a78b1501..b2b7c331f 100644
--- a/idp-admin-api/src/main/java/net/shibboleth/idp/module/IdPModule.java
+++ b/idp-admin-api/src/main/java/net/shibboleth/idp/module/IdPModule.java
@@ -43,16 +43,20 @@ public interface IdPModule extends IdentifiedComponent {
/**
* Gets module name.
*
+ * @param moduleContext optional context for supplying i18n input
+ *
* @return a human-readable name for the module
*/
- @Nonnull @NotEmpty String getName();
+ @Nonnull @NotEmpty String getName(@Nullable final ModuleContext moduleContext);
/**
* Gets module description.
*
+ * @param moduleContext optional context for supplying i18n input
+ *
* @return a human-readable description for the module
*/
- @Nullable @NotEmpty String getDescription();
+ @Nullable @NotEmpty String getDescription(@Nullable final ModuleContext moduleContext);
/**
* Gets module URL.
diff --git a/idp-admin-api/src/main/java/net/shibboleth/idp/module/ModuleContext.java b/idp-admin-api/src/main/java/net/shibboleth/idp/module/ModuleContext.java
index 8997395ed..9883fd15d 100644
--- a/idp-admin-api/src/main/java/net/shibboleth/idp/module/ModuleContext.java
+++ b/idp-admin-api/src/main/java/net/shibboleth/idp/module/ModuleContext.java
@@ -19,6 +19,9 @@ package net.shibboleth.idp.module;
import java.io.PrintStream;
import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale.LanguageRange;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -26,7 +29,10 @@ import javax.annotation.Nullable;
import org.apache.http.client.HttpClient;
import org.opensaml.security.httpclient.HttpClientSecurityParameters;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotLive;
+import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
import net.shibboleth.utilities.java.support.logic.Constraint;
/**
@@ -45,6 +51,9 @@ public final class ModuleContext {
/** HTTP security parameters. */
@Nullable private HttpClientSecurityParameters httpClientSecurityParams;
+ /** Language expressions to use for i18n. */
+ @Nonnull @NonnullElements private List<LanguageRange> languageRanges;
+
/** Output stream for sending output to the module consumer. */
@Nullable private PrintStream messageStream;
@@ -110,6 +119,28 @@ public final class ModuleContext {
public void setHttpClientSecurityParameters(@Nullable final HttpClientSecurityParameters params) {
httpClientSecurityParams = params;
}
+
+ /**
+ * Gets the language ranges to use for i18n.
+ *
+ * @return language ranges
+ */
+ @Nonnull @NonnullElements @NotLive @Unmodifiable public List<LanguageRange> getLanguageRanges() {
+ return languageRanges;
+ }
+
+ /**
+ * Sets the language ranges to use for i18n.
+ *
+ * @param ranges language ranges
+ */
+ public void setLanguageRanges(@Nullable @NonnullElements final List<LanguageRange> ranges) {
+ if (ranges != null) {
+ languageRanges = List.copyOf(ranges);
+ } else {
+ languageRanges = Collections.emptyList();
+ }
+ }
/**
* Gets the output stream to receive any instructioons or additional information after
diff --git a/idp-admin-api/src/main/java/net/shibboleth/idp/module/PropertyDrivenIdPModule.java b/idp-admin-api/src/main/java/net/shibboleth/idp/module/PropertyDrivenIdPModule.java
index 054f18429..9c8bc91f5 100644
--- a/idp-admin-api/src/main/java/net/shibboleth/idp/module/PropertyDrivenIdPModule.java
+++ b/idp-admin-api/src/main/java/net/shibboleth/idp/module/PropertyDrivenIdPModule.java
@@ -24,6 +24,9 @@ import java.net.URL;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Properties;
@@ -33,6 +36,8 @@ import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Strings;
+
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.logic.Constraint;
@@ -73,6 +78,9 @@ public class PropertyDrivenIdPModule extends AbstractIdPModule {
/** Suffix of property for module post-disable message. */
@Nonnull @NotEmpty public static final String MODULE_POSTDISABLE_PROPERTY = ".postdisable";
+ /** Suffix of property for module languages. */
+ @Nonnull @NotEmpty public static final String MODULE_LANGS_PROPERTY = ".langs";
+
/** Class logger. */
@Nonnull private Logger log = LoggerFactory.getLogger(PropertyDrivenIdPModule.class);
@@ -88,6 +96,9 @@ public class PropertyDrivenIdPModule extends AbstractIdPModule {
/** Module URL. */
@Nullable private URL moduleURL;
+ /** Available message locales. */
+ @Nonnull @NonnullElements private List<String> locales;
+
/** Whether to require an HTTP client. */
private boolean requireHttpClient;
@@ -113,6 +124,7 @@ public class PropertyDrivenIdPModule extends AbstractIdPModule {
*/
public PropertyDrivenIdPModule(@Nonnull final InputStream inputStream)
throws IOException, ModuleException {
+ locales = Collections.emptyList();
moduleProperties = new Properties();
moduleProperties.load(inputStream);
load();
@@ -126,6 +138,7 @@ public class PropertyDrivenIdPModule extends AbstractIdPModule {
* @throws ModuleException if the module is not in a valid state
*/
public PropertyDrivenIdPModule(@Nonnull final Properties properties) throws ModuleException {
+ locales = Collections.emptyList();
moduleProperties = Constraint.isNotNull(properties, "Properties cannot be null");
load();
}
@@ -145,6 +158,9 @@ public class PropertyDrivenIdPModule extends AbstractIdPModule {
moduleURL = new URL(url);
}
+ locales = StringSupport.stringToList(
+ moduleProperties.getProperty(getId() + MODULE_LANGS_PROPERTY, ""), ", ");
+
final Collection<BasicModuleResource> resources = new ArrayList<>();
for (Integer rnum = 1; ; ++rnum) {
@@ -190,12 +206,30 @@ public class PropertyDrivenIdPModule extends AbstractIdPModule {
}
/** {@inheritDoc} */
- @Nonnull @NotEmpty public String getName() {
+ @Nonnull @NotEmpty public String getName(@Nullable final ModuleContext moduleContext) {
+
+ if (moduleContext != null) {
+ final String best = Locale.lookupTag(moduleContext.getLanguageRanges(), locales);
+ if (best != null && !best.equals(locales.get(0))) {
+ return moduleProperties.getProperty(getId() + MODULE_NAME_PROPERTY + "." + best, moduleName);
+ }
+ }
return moduleName;
}
/** {@inheritDoc} */
- @Nullable @NotEmpty public String getDescription() {
+ @Nullable @NotEmpty public String getDescription(@Nullable final ModuleContext moduleContext) {
+
+ if (moduleContext != null) {
+ final String best = Locale.lookupTag(moduleContext.getLanguageRanges(), locales);
+ if (best != null && !best.equals(locales.get(0))) {
+ final String desc = moduleProperties.getProperty(getId() + MODULE_DESC_PROPERTY + "." + best);
+ if (!Strings.isNullOrEmpty(desc)) {
+ return desc;
+ }
+ }
+ }
+
return StringSupport.trimOrNull(moduleProperties.getProperty(getId() + MODULE_DESC_PROPERTY));
}
@@ -216,7 +250,18 @@ public class PropertyDrivenIdPModule extends AbstractIdPModule {
final Map<ModuleResource,ResourceResult> results = super.enable(moduleContext);
if (moduleContext.getMessageStream() != null) {
- final String msg = moduleProperties.getProperty(getId() + MODULE_POSTENABLE_PROPERTY);
+
+ String msg = null;
+
+ final String best = Locale.lookupTag(moduleContext.getLanguageRanges(), locales);
+ if (best != null && !best.equals(locales.get(0))) {
+ msg = moduleProperties.getProperty(getId() + MODULE_POSTENABLE_PROPERTY + "." + best);
+ }
+
+ if (msg == null) {
+ msg = moduleProperties.getProperty(getId() + MODULE_POSTENABLE_PROPERTY);
+ }
+
if (msg != null) {
moduleContext.getMessageStream().println(msg);
}
@@ -232,7 +277,18 @@ public class PropertyDrivenIdPModule extends AbstractIdPModule {
final Map<ModuleResource,ResourceResult> results = super.disable(moduleContext, clean);
if (moduleContext.getMessageStream() != null) {
- final String msg = moduleProperties.getProperty(getId() + MODULE_POSTDISABLE_PROPERTY);
+
+ String msg = null;
+
+ final String best = Locale.lookupTag(moduleContext.getLanguageRanges(), locales);
+ if (best != null && !best.equals(locales.get(0))) {
+ msg = moduleProperties.getProperty(getId() + MODULE_POSTDISABLE_PROPERTY + "." + best);
+ }
+
+ if (msg == null) {
+ msg = moduleProperties.getProperty(getId() + MODULE_POSTDISABLE_PROPERTY);
+ }
+
if (msg != null) {
moduleContext.getMessageStream().println(msg);
}
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 219fc691e..99f8aa21c 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
@@ -28,6 +28,7 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
+import java.util.Locale.LanguageRange;
import java.util.Optional;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
@@ -141,7 +142,7 @@ public class IdPModuleTest {
@Test
public void testModule() {
Assert.assertEquals(testModule.getId(), "idp.test");
- Assert.assertEquals(testModule.getName(), "Test module");
+ Assert.assertEquals(testModule.getName(null), "Test module");
Assert.assertEquals(testModule.getURL().toString(), "https://wiki.shibboleth.net/confluence/display/IDP4/Home");
final Iterator<ModuleResource> resources = testModule.getResources().iterator();
@@ -155,6 +156,18 @@ public class IdPModuleTest {
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"));
+
+ context.setLanguageRanges(LanguageRange.parse("fr, de"));
+ Assert.assertEquals(testModule.getName(context), "Test module (French)");
+
+ context.setLanguageRanges(LanguageRange.parse("de, en"));
+ Assert.assertEquals(testModule.getName(context), "Test module (German)");
+
+ context.setLanguageRanges(LanguageRange.parse("en, de"));
+ Assert.assertEquals(testModule.getName(context), "Test module");
+
+ context.setLanguageRanges(LanguageRange.parse("en, en-GB"));
+ Assert.assertEquals(testModule.getName(context), "Test module");
}
@Test
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 a4012fef4..eb7096037 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
@@ -3,7 +3,10 @@
# Main test module
net.shibboleth.idp.module.TestModule = idp.test
+idp.test.langs = en,fr,de
idp.test.name = Test module
+idp.test.name.fr = Test module (French)
+idp.test.name.de = Test module (German)
idp.test.desc = Module for unit tests
idp.test.url = https://wiki.shibboleth.net/confluence/display/IDP4/Home
diff --git a/idp-admin-impl/src/main/java/net/shibboleth/idp/module/impl/ModuleManagerCLI.java b/idp-admin-impl/src/main/java/net/shibboleth/idp/module/impl/ModuleManagerCLI.java
index 98fc6f912..d56d169c8 100644
--- a/idp-admin-impl/src/main/java/net/shibboleth/idp/module/impl/ModuleManagerCLI.java
+++ b/idp-admin-impl/src/main/java/net/shibboleth/idp/module/impl/ModuleManagerCLI.java
@@ -97,6 +97,7 @@ public final class ModuleManagerCLI extends AbstractIdPHomeAwareCommandLine<Modu
new ModuleContext(getApplicationContext().getEnvironment().getProperty("idp.home"));
moduleContext.setHttpClient(getHttpClient());
moduleContext.setHttpClientSecurityParameters(getHttpClientSecurityParameters());
+ moduleContext.setLanguageRanges(args.getLanguageRanges());
if (args.getList() || !args.getInfoModuleIds().isEmpty()) {
doList(moduleContext, args);
@@ -128,8 +129,8 @@ public final class ModuleManagerCLI extends AbstractIdPHomeAwareCommandLine<Modu
if (args.getInfoModuleIds().contains(module.getId())) {
System.out.println();
System.out.println("Module: " + module.getId());
- System.out.println("\tName: " + module.getName());
- System.out.println("\tDesc: " + module.getDescription());
+ System.out.println("\tName: " + module.getName(moduleContext));
+ System.out.println("\tDesc: " + module.getDescription(moduleContext));
System.out.println("\tHelp: " + module.getURL());
if (module.isEnabled(moduleContext)) {
System.out.println("\tStatus: " + ANSIColors.ANSI_GREEN + "ENABLED" + ANSIColors.ANSI_RESET);
diff --git a/idp-war/src/main/webapp/WEB-INF/jsp/status.jsp b/idp-war/src/main/webapp/WEB-INF/jsp/status.jsp
index d33fa9cfa..b09b29268 100644
--- a/idp-war/src/main/webapp/WEB-INF/jsp/status.jsp
+++ b/idp-war/src/main/webapp/WEB-INF/jsp/status.jsp
@@ -52,7 +52,7 @@ final ModuleContext moduleContext =
new ModuleContext(((Environment) request.getAttribute("environment")).getProperty("idp.home"));
for (final IdPModule module : ServiceLoader.load(IdPModule.class)) {
if (module.isEnabled(moduleContext)) {
- out.println("\t" + module.getId() + " (" + module.getName() + ")");
+ out.println("\t" + module.getId() + " (" + module.getName(moduleContext) + ")");
}
}
out.println();
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list