[java-identity-provider] 09/11: IDP-1464 RelyingPartyUIContext now uses Locales
Rod Widdowson
rdw at steadingsoftware.com
Tue Jun 11 09:38:27 EDT 2019
This is an automated email from the git hooks/post-receive script.
rdw pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=83738f3e489f5f24d7b87d7f86e4904f4cfc3105
commit 83738f3e489f5f24d7b87d7f86e4904f4cfc3105
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Tue Jun 11 10:50:35 2019 +0100
IDP-1464 RelyingPartyUIContext now uses Locales
https://issues.shibboleth.net/jira/browse/IDP-1464
We change protected and private methods, and deprecate one
public method (setBrowserlanguages, which should only be used
by our code)
---
.../idp/ui/context/RelyingPartyUIContext.java | 571 +++++++++++----------
.../idp/ui/context/RelyingPartyUIContextTest.java | 8 +-
2 files changed, 292 insertions(+), 287 deletions(-)
diff --git a/idp-ui/src/main/java/net/shibboleth/idp/ui/context/RelyingPartyUIContext.java b/idp-ui/src/main/java/net/shibboleth/idp/ui/context/RelyingPartyUIContext.java
index e1a8fed..a5f6b6b 100644
--- a/idp-ui/src/main/java/net/shibboleth/idp/ui/context/RelyingPartyUIContext.java
+++ b/idp-ui/src/main/java/net/shibboleth/idp/ui/context/RelyingPartyUIContext.java
@@ -22,36 +22,31 @@ import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
+import java.util.Locale.LanguageRange;
+import java.util.Map;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opensaml.messaging.context.BaseContext;
-import org.opensaml.saml.ext.saml2mdui.Description;
-import org.opensaml.saml.ext.saml2mdui.DisplayName;
-import org.opensaml.saml.ext.saml2mdui.InformationURL;
import org.opensaml.saml.ext.saml2mdui.Logo;
-import org.opensaml.saml.ext.saml2mdui.PrivacyStatementURL;
import org.opensaml.saml.ext.saml2mdui.UIInfo;
import org.opensaml.saml.saml2.metadata.AttributeConsumingService;
import org.opensaml.saml.saml2.metadata.ContactPerson;
import org.opensaml.saml.saml2.metadata.ContactPersonTypeEnumeration;
import org.opensaml.saml.saml2.metadata.EntityDescriptor;
import org.opensaml.saml.saml2.metadata.Organization;
-import org.opensaml.saml.saml2.metadata.OrganizationDisplayName;
-import org.opensaml.saml.saml2.metadata.OrganizationName;
-import org.opensaml.saml.saml2.metadata.OrganizationURL;
import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
-import org.opensaml.saml.saml2.metadata.ServiceDescription;
-import org.opensaml.saml.saml2.metadata.ServiceName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.ImmutableList;
-
+import net.shibboleth.idp.saml.metadata.ACSUIInfo;
+import net.shibboleth.idp.saml.metadata.IdPUIInfo;
+import net.shibboleth.idp.saml.metadata.OrganizationUIInfo;
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.Unmodifiable;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.primitive.StringSupport;
@@ -69,25 +64,22 @@ public final class RelyingPartyUIContext extends BaseContext {
/** The appropriate {@link SPSSODescriptor}. */
@Nullable private SPSSODescriptor rpSPSSODescriptor;
- /** The appropriate {@link AttributeConsumingService}. */
- @Nullable private AttributeConsumingService rpAttributeConsumingService;
+ /** The appropriate {@link ACSUIInfo}. */
+ @Nullable private ACSUIInfo rpACSUIinfo;
- /** The appropriate {@link UIInfo}. */
- @Nullable private UIInfo rpUIInfo;
+ /** The appropriate {@link IdPUIInfo}. */
+ @Nullable private IdPUIInfo rpUIInfo;
/** The languages that this browser wants to know about. */
- @Nonnull @NonnullElements private List<String> browserLanguages;
+ @Nonnull @NonnullElements private List<LanguageRange> browserLanguages;
/** The languages that this the Operator want to fall back to. */
- @Nullable private List<String> fallbackLanguages;
-
- /** The languages that this the bean needs to look at. */
- @Nonnull @NonnullElements @Unmodifiable private List<String> usableLanguages;
+ @Nonnull private List<LanguageRange> fallbackLanguages;
/** Constructor. */
public RelyingPartyUIContext() {
browserLanguages = Collections.emptyList();
- usableLanguages = Collections.emptyList();
+ fallbackLanguages = Collections.emptyList();
}
/**
@@ -133,12 +125,12 @@ public final class RelyingPartyUIContext extends BaseContext {
}
/**
- * Get the {@link AttributeConsumingService} for the request.
+ * Get the {@link ACSUIInfo} for the request.
*
- * @return Returns the SPSSODescriptor.
+ * @return Returns the RP's {@link ACSUIInfo}.
*/
- @Nullable protected AttributeConsumingService getRPAttributeConsumingService() {
- return rpAttributeConsumingService;
+ @Nullable protected ACSUIInfo getRPACSUInfo() {
+ return rpACSUIinfo;
}
/**
@@ -146,54 +138,87 @@ public final class RelyingPartyUIContext extends BaseContext {
*
* @return the value or null if there is none.
*/
- @Nullable protected UIInfo getRPUInfo() {
+ @Nullable protected IdPUIInfo getRPUInfo() {
return rpUIInfo;
}
/**
- * Set the RP {@link UIInfo} associated with the request.
- *
+ * Set the RP {@link IdPUIInfo} associated with the request.
+ * We normally expect to get this from the object metadata.
* @param what the value to set
*
* @return this context
*/
@Nonnull public RelyingPartyUIContext setRPUInfo(@Nullable final UIInfo what) {
- rpUIInfo = what;
+ if (what == null) {
+ return this;
+ }
+ final List<IdPUIInfo> list = what.getObjectMetadata().get(IdPUIInfo.class);
+ if (list.isEmpty()) {
+ rpUIInfo = new IdPUIInfo(what);
+ } else {
+ rpUIInfo = list.get(0);
+ }
return this;
}
/**
- * Set the {@link AttributeConsumingService} for the request.
- *
+ * Set the {@link ACSUIInfo} for the request.
+ * We normally expect to get this from the object metadata.
* @param what what to set
*
* @return this context
*/
@Nonnull public RelyingPartyUIContext setRPAttributeConsumingService(
@Nullable final AttributeConsumingService what) {
- rpAttributeConsumingService = what;
+ if (what == null) {
+ return this;
+ }
+ final List<ACSUIInfo> list = what.getObjectMetadata().get(ACSUIInfo.class);
+ if (list.isEmpty()) {
+ rpACSUIinfo = new ACSUIInfo(what);
+ } else {
+ rpACSUIinfo = list.get(0);
+ }
return this;
}
/**
* Set the browser languages.
- *
+ *
* @param languages the languages to set
- *
+ * @deprecated use {@link #setBrowserLanguageRanges(List)}
* @return this context
*/
@Nonnull public RelyingPartyUIContext setBrowserLanguages(@Nonnull @NonnullElements final List<String> languages) {
- browserLanguages = Constraint.isNotNull(languages, "Language List cannot be null");
- makeNewusableList();
+ Constraint.isNotNull(languages, "Language List cannot be null");
+ browserLanguages = languages.
+ stream().
+ filter(e -> e != null).
+ map(s -> new LanguageRange(s)).
+ collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
+ return this;
+ }
+
+ /**
+ * Set the browser languages.
+ *
+ * @param ranges the languages to set
+ * @return this context
+ */
+ @Nonnull public RelyingPartyUIContext setBrowserLanguageRanges(
+ @Nonnull @NonnullElements final List<LanguageRange> ranges) {
+ browserLanguages = Constraint.isNotNull(ranges, "Language Range cannot be null");
return this;
}
+
/**
* Get the browser languages.
*
* @return the languages.
*/
- @Nonnull @NonnullElements protected List<String> getBrowserLanguages() {
+ @Nonnull @NonnullElements protected List<LanguageRange> getBrowserLanguages() {
return browserLanguages;
}
@@ -205,8 +230,14 @@ public final class RelyingPartyUIContext extends BaseContext {
* @return this context
*/
@Nonnull public RelyingPartyUIContext setFallbackLanguages(@Nullable final List<String> languages) {
- fallbackLanguages = languages;
- makeNewusableList();
+ if (languages == null || languages.isEmpty()) {
+ fallbackLanguages = Collections.EMPTY_LIST;
+ }
+ fallbackLanguages = languages.
+ stream().
+ filter(s -> s != null).
+ map(s -> new LanguageRange(s)).
+ collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
return this;
}
@@ -215,34 +246,11 @@ public final class RelyingPartyUIContext extends BaseContext {
*
* @return the languages.
*/
- @Nonnull @NonnullElements protected List<String> getFallbackLanguages() {
+ @Nonnull @NonnullElements protected List<LanguageRange> getFallbackLanguages() {
return fallbackLanguages;
}
/**
- * Construct the usableLanguages from the {@link #browserLanguages} and the {@link #fallbackLanguages}.
- */
- protected void makeNewusableList() {
- final ImmutableList.Builder<String> builder = ImmutableList.builder();
- if (null != browserLanguages) {
- builder.addAll(browserLanguages);
- }
- if (null != fallbackLanguages) {
- builder.addAll(fallbackLanguages);
- }
- usableLanguages = builder.build();
- }
-
- /**
- * Get the all the languages.
- *
- * @return the languages.
- */
- @Nonnull @NonnullElements @Unmodifiable protected List<String> getUsableLanguages() {
- return usableLanguages;
- }
-
- /**
* Check to see whether a supplied URL is acceptable, returning the default if it isn't.
*
* @param url the url to look at
@@ -281,7 +289,7 @@ public final class RelyingPartyUIContext extends BaseContext {
* @param url the url to look at
* @return the input or the default as appropriate
*/
- protected String policeURLLogo(@Nullable final String url) {
+ @Nullable protected String policeURLLogo(@Nullable final String url) {
return policeURL(url, Arrays.asList("http", "https", "data"));
}
@@ -291,51 +299,35 @@ public final class RelyingPartyUIContext extends BaseContext {
* @param url the url to look at
* @return the input or the default as appropriate
*/
- protected String policeURLNonLogo(@Nullable final String url) {
+ @Nullable protected String policeURLNonLogo(@Nullable final String url) {
return policeURL(url, Arrays.asList("http", "https", "mailto"));
}
/**
- * look at <UIinfo>; if there and if so look for appropriate name.
+ * Look for an <AttributeConsumeService> and if its there look for an appropriate name.
*
- * @param lang - which language to look up
* @return null or an appropriate name
*/
- @Nullable protected String getNameFromUIInfo(final String lang) {
+ @Nullable protected String getNameFromAttributeConsumingService() {
- if (getRPUInfo() != null) {
- for (final DisplayName name : getRPUInfo().getDisplayNames()) {
- log.trace("Found name in UIInfo, language '{}'", name.getXMLLang());
- if (name.getXMLLang() != null && name.getXMLLang().equals(lang)) {
- log.debug("Returning name from UIInfo '{}'", name.getValue());
- return name.getValue();
- }
- }
+ final ACSUIInfo acsInfo = getRPACSUInfo();
+ if (null == acsInfo) {
+ log.debug("No ACS so no ServiceName");
+ return null;
}
- log.trace("No name in UIINFO for '{}'", lang);
- return null;
- }
- /**
- * Look for an <AttributeConsumeService> and if its there look for an appropriate name.
- *
- * @param lang - which language to look up
- * @return null or an appropriate name
- */
- @Nullable protected String getNameFromAttributeConsumingService(final String lang) {
+ final Map<Locale, String> serviceNames = acsInfo.getServiceNames();
+ Locale l = Locale.lookup(getBrowserLanguages(), serviceNames.keySet());
- if (null == getRPAttributeConsumingService()) {
- return null;
+ if (l == null) {
+ l = Locale.lookup(getFallbackLanguages(), serviceNames.keySet());
}
- for (final ServiceName name : getRPAttributeConsumingService().getNames()) {
- log.trace("Found name in AttributeConsumingService, language '{}'", name.getXMLLang());
- if (name.getXMLLang() != null && name.getXMLLang().equals(lang)) {
- log.debug("Returning name from AttributeConsumingService '{}'", name.getValue());
- return name.getValue();
- }
+ if (l != null) {
+ log.debug("Found ServiceName '{}' in ACS, locale '{}'", serviceNames.get(l), l);
+ return serviceNames.get(l);
}
- log.trace("No name found in AttributeConsumingService for '{}'", lang);
+ log.debug("No ServiceName in ACS for '{}' or '{}'", getBrowserLanguages(), getFallbackLanguages());
return null;
}
@@ -372,22 +364,28 @@ public final class RelyingPartyUIContext extends BaseContext {
/**
* look at <UIInfo> if there and if so look for appropriate description.
*
- * @param lang - which language to look up
* @return null or an appropriate description
*/
- @Nullable protected String getDescriptionFromUIInfo(final String lang) {
- if (getRPUInfo() == null || getRPUInfo().getDescriptions() == null) {
- log.trace("No UIInfo");
+ @Nullable protected String getDescriptionFromUIInfo() {
+
+ final IdPUIInfo info = getRPUInfo();
+ if (info == null) {
+ log.warn("GetDescription: No UIInfo");
return null;
}
- for (final Description desc : getRPUInfo().getDescriptions()) {
- log.trace("Found description in UIInfo, language '{}'", desc.getXMLLang());
- if (desc.getXMLLang() != null && desc.getXMLLang().equals(lang)) {
- log.trace("Returning description from UIInfo '{}'", desc.getValue());
- return desc.getValue();
- }
+
+ final Map<Locale, String> descriptions = getRPUInfo().getDescriptions();
+ Locale l = Locale.lookup(getBrowserLanguages(), descriptions.keySet());
+
+ if (l == null) {
+ l = Locale.lookup(getFallbackLanguages(), descriptions.keySet());
+ }
+
+ if (l != null) {
+ log.debug("Found Description '{}' in UIInfo, locale '{}'", descriptions.get(l), l);
+ return descriptions.get(l);
}
- log.debug("No matching description in UIInfo");
+ log.debug("No Description in UIINFO for '{}' or '{}'", getBrowserLanguages(), getFallbackLanguages());
return null;
}
@@ -398,19 +396,24 @@ public final class RelyingPartyUIContext extends BaseContext {
* @return null or an appropriate description
*/
@Nullable protected String getDescriptionFromAttributeConsumingService(final String lang) {
- if (getRPAttributeConsumingService() == null) {
- log.trace("No ACS found");
+ final ACSUIInfo acsInfo = getRPACSUInfo();
+ if (null == acsInfo) {
+ log.debug("No ACS so no ServiceDescription");
return null;
}
- for (final ServiceDescription desc : getRPAttributeConsumingService().getDescriptions()) {
- log.trace("Found name in AttributeConsumingService, language=" + desc.getXMLLang());
- if (desc.getXMLLang() != null && desc.getXMLLang().equals(lang)) {
- log.debug("Returning name from AttributeConsumingService " + desc.getValue());
- return desc.getValue();
- }
+
+ final Map<Locale, String> serviceDescriptions = acsInfo.getServiceDescriptions();
+ Locale l = Locale.lookup(getBrowserLanguages(), serviceDescriptions.keySet());
+
+ if (l == null) {
+ l = Locale.lookup(getFallbackLanguages(), serviceDescriptions.keySet());
}
- log.trace("No description in AttributeConsumingService");
+ if (l != null) {
+ log.debug("Found ServiceDescription '{}' in ACS, locale '{}'", serviceDescriptions.get(l), l);
+ return serviceDescriptions.get(l);
+ }
+ log.debug("No ServiceDescription in ACS for '{}' or '{}'", getBrowserLanguages(), getFallbackLanguages());
return null;
}
@@ -419,14 +422,24 @@ public final class RelyingPartyUIContext extends BaseContext {
*
* @return the {@link Organization} for the relying party.
*/
- @Nullable protected Organization getOrganization() {
- if (null != getRPSPSSODescriptor() && null != getRPSPSSODescriptor().getOrganization()) {
- return getRPSPSSODescriptor().getOrganization();
+ @Nullable protected OrganizationUIInfo getOrganization() {
+
+ Organization organization = null;
+ if (null != getRPSPSSODescriptor()) {
+ organization = getRPSPSSODescriptor().getOrganization();
}
- if (null != getRPEntityDescriptor() && null != getRPEntityDescriptor().getOrganization()) {
- return getRPEntityDescriptor().getOrganization();
+ if (organization == null && getRPEntityDescriptor() != null) {
+ organization = getRPEntityDescriptor().getOrganization();
}
- return null;
+ if (organization == null) {
+ return null;
+ }
+
+ final List<OrganizationUIInfo> infoList = organization.getObjectMetadata().get(OrganizationUIInfo.class);
+ if (infoList.isEmpty()) {
+ return new OrganizationUIInfo(organization);
+ }
+ return infoList.get(0);
}
/**
@@ -487,20 +500,38 @@ public final class RelyingPartyUIContext extends BaseContext {
* @return the name or null if there wasn't one
*/
@Nullable public String getServiceName() {
-
- for (final String lang : getUsableLanguages()) {
- String result;
- result = getNameFromUIInfo(lang);
- if (result != null) {
- return result;
- }
-
- result = getNameFromAttributeConsumingService(lang);
- if (result != null) {
- return result;
- }
- }
- // failing that just look at the entity name
+ final IdPUIInfo uiinfo = getRPUInfo();
+ final ACSUIInfo acsinfo = getRPACSUInfo();
+ Locale l = null;
+ Map<Locale, String> names = null;
+ log.trace("GetServiceName - looking browser Locales '{}', Falllback locales '{}'");
+ if (uiinfo != null) {
+ log.trace("Looking in UI info for Browser Locales");
+ names = uiinfo.getDisplayNames();
+ l = Locale.lookup(getBrowserLanguages(), names.keySet());
+ }
+ if (l == null && acsinfo != null) {
+ log.trace("Looking in ACS for Browser Locales");
+ names = acsinfo.getServiceNames();
+ l = Locale.lookup(getBrowserLanguages(), names.keySet());
+ }
+ if (l == null && uiinfo != null) {
+ log.trace("Looking in UI info for Fallback Locales");
+ names = uiinfo.getDisplayNames();
+ l = Locale.lookup(getFallbackLanguages(), names.keySet());
+ }
+ if (l == null && acsinfo != null) {
+ log.trace("Looking in ACS for Fallback Locales");
+ names = acsinfo.getServiceNames();
+ l = Locale.lookup(getFallbackLanguages(), names.keySet());
+ }
+ if (l != null) {
+ final String result = names.get(l);
+ log.debug("Found Name '{}' for Locale '{}'", result, l);
+ return result;
+ }
+
+ log.debug("Nothing found returning name from entity");
return getNameFromEntityId();
}
@@ -510,18 +541,38 @@ public final class RelyingPartyUIContext extends BaseContext {
* @return the description or null if there wasn't one
*/
@Nullable public String getServiceDescription() {
-
- for (final String lang : getUsableLanguages()) {
- String value = getDescriptionFromUIInfo(lang);
- if (null != value) {
- return value;
- }
- value = getDescriptionFromAttributeConsumingService(lang);
- if (null != value) {
- return value;
- }
- }
- log.debug("No description matching the languages found, returning null");
+ final IdPUIInfo uiinfo = getRPUInfo();
+ final ACSUIInfo acsinfo = getRPACSUInfo();
+ Locale l = null;
+ Map<Locale, String> names = null;
+ log.trace("GetServiceDescription - looking browser Locales '{}', Falllback locales '{}'");
+ if (uiinfo != null) {
+ log.trace("Looking in UI info for Browser Locales");
+ names = uiinfo.getDescriptions();
+ l = Locale.lookup(getBrowserLanguages(), names.keySet());
+ }
+ if (l == null && acsinfo != null) {
+ log.trace("Looking in ACS for Browser Locales");
+ names = acsinfo.getServiceDescriptions();
+ l = Locale.lookup(getBrowserLanguages(), names.keySet());
+ }
+ if (l == null && uiinfo != null) {
+ log.trace("Looking in UI info for Fallback Locales");
+ names = uiinfo.getDescriptions();
+ l = Locale.lookup(getFallbackLanguages(), names.keySet());
+ }
+ if (l == null && acsinfo != null) {
+ log.trace("Looking in ACS for Fallback Locales");
+ names = acsinfo.getServiceDescriptions();
+ l = Locale.lookup(getFallbackLanguages(), names.keySet());
+ }
+ if (l != null) {
+ final String result = names.get(l);
+ log.debug("Found Name '{}' for Locale '{}'", result, l);
+ return result;
+ }
+
+ log.debug("Nothing found");
return null;
}
@@ -531,23 +582,12 @@ public final class RelyingPartyUIContext extends BaseContext {
* @return An appropriate string or null
*/
@Nullable public String getOrganizationDisplayName() {
- final Organization org = getOrganization();
- if (null == org || null == org.getDisplayNames() || org.getDisplayNames().isEmpty()) {
- log.debug("No Organization, OrganizationDisplayName or names, returning null");
+ final OrganizationUIInfo org = getOrganization();
+ if (null == org) {
+ log.debug("No Organization, returning null");
return null;
}
- for (final String lang : getUsableLanguages()) {
- for (final OrganizationDisplayName name : org.getDisplayNames()) {
- log.trace("Found OrganizationDisplayName in Organization, language={}", name.getXMLLang());
-
- if (name.getXMLLang() != null && name.getXMLLang().equals(lang)) {
- log.debug("Returning OrganizationDisplayName from Organization, {}", name.getValue());
- return name.getValue();
- }
- }
- }
- log.debug("No relevant OrganizationDisplayName in Organization, returning null");
- return null;
+ return getLocalizeString(org.getOrganizationDisplayNames(), "OrganizationDisplayName");
}
/**
@@ -556,23 +596,12 @@ public final class RelyingPartyUIContext extends BaseContext {
* @return An appropriate string or null
*/
@Nullable public String getOrganizationName() {
- final Organization org = getOrganization();
- if (null == org || null == org.getOrganizationNames() || org.getOrganizationNames().isEmpty()) {
- log.debug("No Organization, OrganizationName or names, returning null");
+ final OrganizationUIInfo org = getOrganization();
+ if (null == org) {
+ log.debug("No Organization, returning null");
return null;
}
- for (final String lang : getUsableLanguages()) {
- for (final OrganizationName name : org.getOrganizationNames()) {
- log.trace("Found OrganizationName in Organization, language={}", name.getXMLLang());
-
- if (name.getXMLLang() != null && name.getXMLLang().equals(lang)) {
- log.debug("Returning OrganizationName from Organization, {}", name.getValue());
- return name.getValue();
- }
- }
- }
- log.debug("No relevant OrganizationName in Organization, returning null");
- return null;
+ return getLocalizeString(org.getOrganizationNames(), "OrganizationName");
}
/**
@@ -581,23 +610,12 @@ public final class RelyingPartyUIContext extends BaseContext {
* @return An appropriate string or the null
*/
public String getOrganizationURL() {
- final Organization org = getOrganization();
- if (null == org || null == org.getURLs() || org.getURLs().isEmpty()) {
- log.debug("No Organization, OrganizationURL or urls, returning null");
+ final OrganizationUIInfo org = getOrganization();
+ if (null == org) {
+ log.debug("No Organization, returning null");
return null;
}
- for (final String lang : getUsableLanguages()) {
- for (final OrganizationURL url : org.getURLs()) {
- log.trace("Found OrganizationURL in Organization, language={}", url.getXMLLang());
-
- if (url.getXMLLang() != null && url.getXMLLang().equals(lang)) {
- log.debug("Returning OrganizationURL from Organization, {}", url.getValue());
- return policeURLNonLogo(url.getValue());
- }
- }
- }
- log.debug("No relevant OrganizationURL in Organization, returning null");
- return null;
+ return policeURLNonLogo(getLocalizeString(org.getOrganizationUrls(), "OrganizationURLs"));
}
/**
@@ -645,6 +663,31 @@ public final class RelyingPartyUIContext extends BaseContext {
return policeURLNonLogo(contact.getEmailAddresses().get(0).getAddress());
}
+ /** Helper function for methods which need localized strings.
+ * @param map the map to lookup
+ * @param type the name we are looking up (for logging)
+ * @return the suitable value, or null
+ */
+ @Nullable private String getLocalizeString(@Nonnull final Map<Locale, String> map, @Nonnull final String type) {
+ if (null == map || map.isEmpty()) {
+ log.debug("No {}s returning null", type);
+ return null;
+ }
+ Locale l = Locale.lookup(getBrowserLanguages(), map.keySet());
+ if (l == null) {
+ log.trace("No {} found from Brower langages '{}' in '{}'",
+ type, getBrowserLanguages(), map.keySet());
+ l = Locale.lookup(getFallbackLanguages(), map.keySet());
+ }
+ if (l == null) {
+ log.debug("No relevant {} with language match, returning null", type);
+ return null;
+ }
+ final String result = map.get(l);
+ log.debug("Found {} '{}' for '{}'", type, result, l);
+ return result;
+ }
+
/**
* Get the <mdui:InformationURL>.
*
@@ -652,22 +695,11 @@ public final class RelyingPartyUIContext extends BaseContext {
*/
@Nullable public String getInformationURL() {
- if (null == getRPUInfo() || null == rpUIInfo.getInformationURLs() || rpUIInfo.getInformationURLs().isEmpty()) {
- log.debug("No UIInfo or InformationURLs returning null");
+ if (null == getRPUInfo()) {
+ log.debug("No UIInfo returning null");
return null;
}
- for (final String lang : getUsableLanguages()) {
- for (final InformationURL url : rpUIInfo.getInformationURLs()) {
- log.trace("Found InformationURL, language={}", url.getXMLLang());
-
- if (url.getXMLLang() != null && url.getXMLLang().equals(lang)) {
- log.debug("Returning InformationURL, {}", url.getValue());
- return policeURLNonLogo(url.getValue());
- }
- }
- }
- log.debug("No relevant InformationURL with language match, returning null");
- return null;
+ return policeURLNonLogo(getLocalizeString(getRPUInfo().getInformationURLs(), "InformationURL"));
}
/**
@@ -676,23 +708,11 @@ public final class RelyingPartyUIContext extends BaseContext {
* @return the value or null
*/
@Nullable public String getPrivacyStatementURL() {
- if (null == getRPUInfo() || null == rpUIInfo.getPrivacyStatementURLs()
- || rpUIInfo.getPrivacyStatementURLs().isEmpty()) {
- log.debug("No UIInfo or PrivacyStatementURLs returning null");
+ if (null == getRPUInfo()) {
+ log.debug("No UIInfo returning null");
return null;
}
- for (final String lang : getUsableLanguages()) {
- for (final PrivacyStatementURL url : rpUIInfo.getPrivacyStatementURLs()) {
- log.trace("Found PrivacyStatementURL, language={}", url.getXMLLang());
-
- if (url.getXMLLang() != null && url.getXMLLang().equals(lang)) {
- log.debug("Returning PrivacyStatementURL, {}", url.getValue());
- return policeURLNonLogo(url.getValue());
- }
- }
- }
- log.debug("No relevant PrivacyStatementURLs with language match, returning null");
- return null;
+ return policeURLNonLogo(getLocalizeString(getRPUInfo().getPrivacyStatementURLs(), "PrivacyStatementURL"));
}
/**
@@ -724,60 +744,6 @@ public final class RelyingPartyUIContext extends BaseContext {
return height <= maxHeight && height >= minHeight && width <= maxWidth && width >= minWidth;
}
- /**
- * Get the Logo of the given language which fits the size.
- *
- * @param lang the language
- * @param minWidth the minimum width to allow.
- * @param minHeight the minimum height to allow.
- * @param maxWidth the maximum width to allow.
- * @param maxHeight the maximum height to allow.
- * @return an appropriate logo URL or null.
- */
- @Nullable private String getLogoByLanguage(@Nonnull final String lang, final int minWidth, final int minHeight,
- final int maxWidth, final int maxHeight) {
- for (final Logo logo : rpUIInfo.getLogos()) {
- log.trace("Found logo in UIInfo, '{}' ({} x {})", logo.getXMLLang(), logo.getWidth(), logo.getHeight());
- if (logo.getXMLLang() == null || !logo.getXMLLang().equals(lang)) {
- log.trace("Language mismatch against '{}'");
- continue;
- }
- if (!logoFits(logo, minWidth, minHeight, maxWidth, maxHeight)) {
- log.trace("Size mismatch");
- continue;
- }
- log.debug("Returning logo from UIInfo, '{}' ({} x {}) : {}", logo.getXMLLang(), logo.getWidth(),
- logo.getHeight(), logo.getURL());
- return logo.getURL();
- }
- return null;
- }
-
- /**
- * Get a Logo without a language which fits the size.
- *
- * @param minWidth the minimum width to allow.
- * @param minHeight the minimum height to allow.
- * @param maxWidth the maximum width to allow.
- * @param maxHeight the maximum height to allow.
- * @return an appropriate logo URL or null.
- */
- @Nullable private String getLogoNoLanguage(final int minWidth, final int minHeight, final int maxWidth,
- final int maxHeight) {
- for (final Logo logo : rpUIInfo.getLogos()) {
- if (null != logo.getXMLLang()) {
- continue;
- }
- log.trace("Found logo in UIInfo, ({} x {})", logo.getWidth(), logo.getHeight());
- if (!logoFits(logo, minWidth, minHeight, maxWidth, maxHeight)) {
- log.trace("Size Mismatch");
- continue;
- }
- log.debug("Returning logo from UIInfo, ({} x {}) : {}", logo.getWidth(), logo.getHeight(), logo.getURL());
- return logo.getURL();
- }
- return null;
- }
/**
* Get the Logo (or null). We apply the languages and the supplied lengths.
@@ -788,24 +754,61 @@ public final class RelyingPartyUIContext extends BaseContext {
* @param maxHeight the maximum height to allow.
* @return an appropriate logo URL or null.
*/
+ // CheckStyle: CyclomaticComplexity OFF
@Nullable public String getLogo(final int minWidth, final int minHeight, final int maxWidth, final int maxHeight) {
- if (null == getRPUInfo() || null == rpUIInfo.getLogos() || rpUIInfo.getLogos().isEmpty()) {
+
+ if (null == getRPUInfo()) {
log.debug("No UIInfo or logos returning null");
return null;
}
- for (final String lang : getUsableLanguages()) {
- final String result = getLogoByLanguage(lang, minWidth, minHeight, maxWidth, maxHeight);
- if (null != result) {
- return policeURLLogo(result);
+ final Map<Locale, List<Logo>> logos = getRPUInfo().getLocaleLogos();
+
+ if (logos != null && !logos.isEmpty()) {
+ for (final Locale l: Locale.filter(getBrowserLanguages(), logos.keySet())) {
+ for (final Logo logo : logos.get(l)) {
+ log.trace("Found logo in UIInfo, ({} x {}) - {}", logo.getWidth(), logo.getHeight(), l);
+ if (logoFits(logo, minWidth, minHeight, maxWidth, maxHeight)) {
+ final String result = policeURLLogo(logo.getURL());
+ if (result != null) {
+ log.debug("Found locale logo from UIInfo, ({} x {}) : {}",
+ logo.getWidth(), logo.getHeight(), result);
+ return result;
+ }
+ }
+ }
+ }
+ for (final Locale l: Locale.filter(getFallbackLanguages(), logos.keySet())) {
+ for (final Logo logo : logos.get(l)) {
+ log.trace("Found logo in UIInfo, ({} x {}) - {}", logo.getWidth(), logo.getHeight(), l);
+ if (logoFits(logo, minWidth, minHeight, maxWidth, maxHeight)) {
+ final String result = policeURLLogo(logo.getURL());
+ if (result != null) {
+ log.debug("Found locale logo from UIInfo, ({} x {}) : {}",
+ logo.getWidth(), logo.getHeight(), result);
+ return result;
+ }
+ }
+ }
}
}
- final String result = getLogoNoLanguage(minWidth, minHeight, maxWidth, maxHeight);
- if (null != result) {
- return policeURLLogo(result);
+ for (final Logo logo : rpUIInfo.getNonLocaleLogos()) {
+ log.trace("Found logo in UIInfo, ({} x {})", logo.getWidth(), logo.getHeight());
+ if (!logoFits(logo, minWidth, minHeight, maxWidth, maxHeight)) {
+ log.trace("Size Mismatch");
+ continue;
+ }
+ final String result = policeURLLogo(logo.getURL());
+ if (result != null) {
+ log.debug("Found nonlocale logo from UIInfo, ({} x {}) : {}",
+ logo.getWidth(), logo.getHeight(), logo.getURL());
+ return result;
+ }
}
+ log.debug("No valid logos which fit found");
return null;
}
+ // CheckStyle: CyclomaticComplexity ON
/**
* Get the Logo (or null). We apply the languages and the supplied lengths.
diff --git a/idp-ui/src/test/java/net/shibboleth/idp/ui/context/RelyingPartyUIContextTest.java b/idp-ui/src/test/java/net/shibboleth/idp/ui/context/RelyingPartyUIContextTest.java
index ce83d0d..6522296 100644
--- a/idp-ui/src/test/java/net/shibboleth/idp/ui/context/RelyingPartyUIContextTest.java
+++ b/idp-ui/src/test/java/net/shibboleth/idp/ui/context/RelyingPartyUIContextTest.java
@@ -17,8 +17,8 @@
package net.shibboleth.idp.ui.context;
-import java.util.Arrays;
import java.util.Collections;
+import java.util.Locale.LanguageRange;
import org.opensaml.core.xml.XMLObject;
import org.opensaml.core.xml.XMLObjectBaseTestCase;
@@ -60,7 +60,7 @@ public class RelyingPartyUIContextTest extends XMLObjectBaseTestCase {
if (null != theUiInfos[which]) {
result.setRPUInfo(theUiInfos[which]);
}
- result.setBrowserLanguages(Arrays.asList("en", "fr"));
+ result.setBrowserLanguageRanges(LanguageRange.parse("en,fr"));
return result;
}
@@ -160,6 +160,7 @@ public class RelyingPartyUIContextTest extends XMLObjectBaseTestCase {
Assert.assertEquals(ctx.getPrivacyStatementURL(), null);
}
+ @SuppressWarnings("deprecation")
@Test public void logo() {
RelyingPartyUIContext ctx = getContext();
@@ -171,10 +172,11 @@ public class RelyingPartyUIContextTest extends XMLObjectBaseTestCase {
}
+ @SuppressWarnings("deprecation")
@Test public void fallbackLanguage() {
RelyingPartyUIContext ctx = getContext();
- ctx.setBrowserLanguages(Collections.singletonList("improbable"));
+ ctx.setBrowserLanguages(Collections.singletonList("zh"));
Assert.assertEquals(ctx.getLogo(), "https://shibboleth.net/images/shibboleth.png");
ctx.setFallbackLanguages(Collections.singletonList("de"));
Assert.assertEquals(ctx.getLogo(), "https://shibboleth.net/images/shibboleth.pngde");
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list