SIDP-485 add alt attribute to the <idpui:serviceLogo/> tag. Also add to to the image...
authorrdw <rdw@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 5 May 2011 13:09:08 +0000 (13:09 +0000)
committerrdw <rdw@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 5 May 2011 13:09:08 +0000 (13:09 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/branches/REL_2@3023 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

doc/RELEASE-NOTES.txt
src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceLogoTag.java
src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceNameTag.java
src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceTagSupport.java
src/main/webapp/WEB-INF/idpui.tld
src/main/webapp/login.jsp

index 87852f9..9ed5932 100644 (file)
@@ -19,6 +19,7 @@ Changes in Release 2.3.0
 [SIDP-482] - JSP pages should HTML-encode any strings they handle
 [SIDP-483] - Log Completed, Unencrypted SAML Assertion
 [SIDP-486] - login.jsp page contains old wiki link
+[SIDP-485] - <img> inside HTML pages must have alt attribute.
 
 Changes in Release 2.2.1
 =============================================
index 8000aa8..dfee29c 100644 (file)
@@ -27,7 +27,6 @@ import javax.servlet.jsp.tagext.BodyContent;
 import org.opensaml.samlext.saml2mdui.Logo;\r
 import org.owasp.esapi.ESAPI;\r
 import org.owasp.esapi.Encoder;\r
-import org.owasp.esapi.errors.EncodingException;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
@@ -35,13 +34,15 @@ import org.slf4j.LoggerFactory;
 public class ServiceLogoTag extends ServiceTagSupport {\r
 \r
     /**\r
-     * checkstype control.\r
+     * checkstyle control.\r
      */\r
     private static final long serialVersionUID = 6451849117572923712L;\r
     /** Class logger. */\r
     private static Logger log = LoggerFactory.getLogger(ServiceLogoTag.class);\r
     /** what to emit if the jsp has nothing. */\r
     private static final String DEFAULT_VALUE = "";\r
+    /** what to emit as alt txt if all else fails. */\r
+    private static final String DEFAULT_ALT_TXT = "SP Logo";\r
 \r
     /** Bean storage. Size constraint X */\r
     private int minWidth;\r
@@ -51,6 +52,8 @@ public class ServiceLogoTag extends ServiceTagSupport {
     private int minHeight;\r
     /** Bean storage.  Size constraint Y */\r
     private int maxHeight = Integer.MAX_VALUE;\r
+    /** Bean storage.  alt text */\r
+    private String altTxt;\r
 \r
     /** Bean setter.\r
      * @param value what to set\r
@@ -77,6 +80,13 @@ public class ServiceLogoTag extends ServiceTagSupport {
         maxHeight = value.intValue();\r
     }\r
 \r
+    /** Bean setter.\r
+     * @param value what to set\r
+     */\r
+    public void setAlt(String value) {\r
+        altTxt = value;\r
+    }\r
+\r
     /**\r
      * Whether the provided logo fits inside the constraints.\r
      * @param logo the logo\r
@@ -125,6 +135,30 @@ public class ServiceLogoTag extends ServiceTagSupport {
         }\r
         return null;\r
     }\r
+    \r
+    /** Find what the user specified for alt txt.\r
+     * @return the text required\r
+     */\r
+    private String getAltText() {\r
+        \r
+        //\r
+        // First see what the user tried\r
+        //\r
+        String value = altTxt;\r
+        if (null != value && 0 != value.length()) {\r
+            return value;\r
+        }\r
+        \r
+        //\r
+        // Try the request\r
+        //\r
+        value = getServiceName();\r
+        if (null != value && 0 != value.length()) {\r
+            return value;\r
+        }\r
+        \r
+        return DEFAULT_ALT_TXT;\r
+    }\r
 \r
     /**\r
      * Given the url build an appropriate &lta href=...\r
@@ -161,6 +195,7 @@ public class ServiceLogoTag extends ServiceTagSupport {
 \r
         sb = new StringBuilder("<img src=\"");\r
         sb.append(encodedURL).append('"');\r
+        sb.append("alt=").append(getAltText()).append('"');\r
         addClassAndId(sb);\r
         sb.append("/>");\r
         return sb.toString();\r
index dfb606f..1c9104f 100644 (file)
 package edu.internet2.middleware.shibboleth.idp.ui;\r
 \r
 import java.io.IOException;\r
-import java.net.URI;\r
-import java.net.URISyntaxException;\r
-import java.util.List;\r
 \r
 import javax.servlet.jsp.JspException;\r
 import javax.servlet.jsp.JspWriter;\r
 import javax.servlet.jsp.tagext.BodyContent;\r
 \r
-import org.opensaml.saml2.metadata.AttributeConsumingService;\r
-import org.opensaml.saml2.metadata.EntityDescriptor;\r
-import org.opensaml.saml2.metadata.LocalizedString;\r
-import org.opensaml.saml2.metadata.RoleDescriptor;\r
-import org.opensaml.saml2.metadata.SPSSODescriptor;\r
-import org.opensaml.saml2.metadata.ServiceName;\r
-import org.opensaml.samlext.saml2mdui.DisplayName;\r
 import org.owasp.esapi.ESAPI;\r
 import org.owasp.esapi.Encoder;\r
 import org.slf4j.Logger;\r
@@ -57,141 +47,6 @@ public class ServiceNameTag extends ServiceTagSupport {
     /** what to emit if the jsp has nothing. */\r
     private static final String DEFAULT_VALUE = "Unspecified Service Provider";\r
 \r
-    /**\r
-     * If the entityId can look like a host return that otherwise the string.\r
-     * @return either the host or the entityId.\r
-     */\r
-    private String getNameFromEntityId() {\r
-        EntityDescriptor sp = getSPEntityDescriptor();\r
-        \r
-        if (null == sp) {\r
-            log.debug("No relying party, nothing to display");\r
-            return null;\r
-        }\r
-\r
-        try {\r
-            URI entityId = new URI(sp.getEntityID());\r
-            String scheme = entityId.getScheme();\r
-\r
-            if ("http".equals(scheme) || "https".equals(scheme)) {\r
-                return entityId.getHost(); \r
-            }\r
-        } catch (URISyntaxException e) {\r
-            // \r
-            // It wasn't an URI.  return full entityId.\r
-            //\r
-            return sp.getEntityID();\r
-        }\r
-        //\r
-        // not a URL return full entityID\r
-        //\r
-        return sp.getEntityID();\r
-    }\r
-    \r
-    /** \r
-     * look at &lt;Uiinfo&gt; if there and if so look for appropriate name.\r
-     * @return null or an appropriate name\r
-     */\r
-    private String getNameFromUIInfo() {\r
-        String lang = getBrowserLanguage();\r
-\r
-        if (getSPUIInfo() != null) {\r
-            for (DisplayName name:getSPUIInfo().getDisplayNames()) {\r
-                if (log.isDebugEnabled()){\r
-                    log.debug("Found name in UIInfo, language=" + name.getXMLLang());\r
-                }\r
-                if (name.getXMLLang().equals(lang)) {\r
-                    //\r
-                    // Found it\r
-                    //\r
-                    if (log.isDebugEnabled()){\r
-                        log.debug("returning name from UIInfo " + name.getName().getLocalString());\r
-                    }\r
-                    return name.getName().getLocalString();\r
-                }\r
-            }\r
-            if (log.isDebugEnabled()){\r
-                log.debug("No name in UIInfo");\r
-            }            \r
-        }\r
-        return null;\r
-    }\r
-\r
-    /**\r
-     * look for an &ltAttributeConsumeService&gt and if its there look for an appropriate name.\r
-     * @return null or an appropriate name\r
-     */\r
-    private String getNameFromAttributeConsumingService(){\r
-        String lang = getBrowserLanguage();\r
-        List<RoleDescriptor> roles;\r
-        AttributeConsumingService acs = null;\r
-        EntityDescriptor sp = getSPEntityDescriptor();\r
-        \r
-        if (null == sp) {\r
-            log.warn("No relying party, nothing to display");\r
-            return null;\r
-        }\r
-\r
-        roles = sp.getRoleDescriptors(SPSSODescriptor.DEFAULT_ELEMENT_NAME);\r
-        if (!roles.isEmpty()) {\r
-            SPSSODescriptor spssod = (SPSSODescriptor) roles.get(0);\r
-            acs = spssod.getDefaultAttributeConsumingService();\r
-        }\r
-        if (acs != null) {\r
-            for (ServiceName name:acs.getNames()) {\r
-                LocalizedString localName = name.getName();\r
-                if (log.isDebugEnabled()){\r
-                    log.debug("Found name in AttributeConsumingService, language=" + localName.getLanguage());\r
-                }\r
-                if (localName.getLanguage().equals(lang)) {\r
-                    if (log.isDebugEnabled()){\r
-                        log.debug("returning name from AttributeConsumingService " + name.getName().getLocalString());\r
-                    }\r
-                    return localName.getLocalString();\r
-                }\r
-            }\r
-            if (log.isDebugEnabled()){\r
-                log.debug("No name in AttributeConsumingService");\r
-            }            \r
-        }        \r
-        return null;\r
-    }\r
-    \r
-    /**\r
-     * Get the identifier for the service name as per the rules above.\r
-     * @return something sensible for display.\r
-     */\r
-    private String getServiceName() {\r
-        String result;\r
-        //\r
-        // First look for MDUI\r
-        //\r
-        if (getSPEntityDescriptor() == null) {\r
-            log.debug("No relying party, nothing to display");\r
-            return null;\r
-        }\r
-        //\r
-        // Look at <UIInfo>\r
-        //\r
-        result = getNameFromUIInfo();\r
-        if (result != null) {\r
-            return result;\r
-        }\r
-        \r
-        //\r
-        // Otherwise <AttributeConsumingService>\r
-        //\r
-        result = getNameFromAttributeConsumingService();\r
-        if (result != null) {\r
-            return result;\r
-        }\r
-        \r
-        //\r
-        // Or look at the entityName\r
-        //\r
-        return getNameFromEntityId();\r
-    }\r
-    \r
     @Override\r
     public int doStartTag() throws JspException {\r
        \r
index 0ecb581..4ca5204 100644 (file)
@@ -18,20 +18,24 @@ package edu.internet2.middleware.shibboleth.idp.ui;
 \r
 import java.net.URI;\r
 import java.net.URISyntaxException;\r
+import java.util.List;\r
 \r
 import javax.servlet.ServletContext;\r
 import javax.servlet.http.HttpServletRequest;\r
 import javax.servlet.jsp.tagext.BodyTagSupport;\r
 \r
 import org.opensaml.saml2.common.Extensions;\r
+import org.opensaml.saml2.metadata.AttributeConsumingService;\r
 import org.opensaml.saml2.metadata.EntityDescriptor;\r
+import org.opensaml.saml2.metadata.LocalizedString;\r
 import org.opensaml.saml2.metadata.RoleDescriptor;\r
 import org.opensaml.saml2.metadata.SPSSODescriptor;\r
+import org.opensaml.saml2.metadata.ServiceName;\r
+import org.opensaml.samlext.saml2mdui.DisplayName;\r
 import org.opensaml.samlext.saml2mdui.UIInfo;\r
 import org.opensaml.xml.XMLObject;\r
 import org.owasp.esapi.ESAPI;\r
 import org.owasp.esapi.Encoder;\r
-import org.owasp.esapi.errors.EncodingException;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
@@ -207,5 +211,140 @@ public class ServiceTagSupport extends BodyTagSupport{
         \r
         return request.getLocale().getLanguage();\r
     }\r
-       \r
+    /**\r
+     * If the entityId can look like a host return that otherwise the string.\r
+     * @return either the host or the entityId.\r
+     */\r
+    private String getNameFromEntityId() {\r
+        EntityDescriptor sp = getSPEntityDescriptor();\r
+        \r
+        if (null == sp) {\r
+            log.debug("No relying party, nothing to display");\r
+            return null;\r
+        }\r
+\r
+        try {\r
+            URI entityId = new URI(sp.getEntityID());\r
+            String scheme = entityId.getScheme();\r
+\r
+            if ("http".equals(scheme) || "https".equals(scheme)) {\r
+                return entityId.getHost(); \r
+            }\r
+        } catch (URISyntaxException e) {\r
+            // \r
+            // It wasn't an URI.  return full entityId.\r
+            //\r
+            return sp.getEntityID();\r
+        }\r
+        //\r
+        // not a URL return full entityID\r
+        //\r
+        return sp.getEntityID();\r
+    }\r
+    \r
+    /** \r
+     * look at &lt;Uiinfo&gt; if there and if so look for appropriate name.\r
+     * @return null or an appropriate name\r
+     */\r
+    private String getNameFromUIInfo() {\r
+        String lang = getBrowserLanguage();\r
+\r
+        if (getSPUIInfo() != null) {\r
+            for (DisplayName name:getSPUIInfo().getDisplayNames()) {\r
+                if (log.isDebugEnabled()){\r
+                    log.debug("Found name in UIInfo, language=" + name.getXMLLang());\r
+                }\r
+                if (name.getXMLLang().equals(lang)) {\r
+                    //\r
+                    // Found it\r
+                    //\r
+                    if (log.isDebugEnabled()){\r
+                        log.debug("returning name from UIInfo " + name.getName().getLocalString());\r
+                    }\r
+                    return name.getName().getLocalString();\r
+                }\r
+            }\r
+            if (log.isDebugEnabled()){\r
+                log.debug("No name in UIInfo");\r
+            }            \r
+        }\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * look for an &ltAttributeConsumeService&gt and if its there look for an appropriate name.\r
+     * @return null or an appropriate name\r
+     */\r
+    private String getNameFromAttributeConsumingService(){\r
+        String lang = getBrowserLanguage();\r
+        List<RoleDescriptor> roles;\r
+        AttributeConsumingService acs = null;\r
+        EntityDescriptor sp = getSPEntityDescriptor();\r
+        \r
+        if (null == sp) {\r
+            log.warn("No relying party, nothing to display");\r
+            return null;\r
+        }\r
+\r
+        roles = sp.getRoleDescriptors(SPSSODescriptor.DEFAULT_ELEMENT_NAME);\r
+        if (!roles.isEmpty()) {\r
+            SPSSODescriptor spssod = (SPSSODescriptor) roles.get(0);\r
+            acs = spssod.getDefaultAttributeConsumingService();\r
+        }\r
+        if (acs != null) {\r
+            for (ServiceName name:acs.getNames()) {\r
+                LocalizedString localName = name.getName();\r
+                if (log.isDebugEnabled()){\r
+                    log.debug("Found name in AttributeConsumingService, language=" + localName.getLanguage());\r
+                }\r
+                if (localName.getLanguage().equals(lang)) {\r
+                    if (log.isDebugEnabled()){\r
+                        log.debug("returning name from AttributeConsumingService " + name.getName().getLocalString());\r
+                    }\r
+                    return localName.getLocalString();\r
+                }\r
+            }\r
+            if (log.isDebugEnabled()){\r
+                log.debug("No name in AttributeConsumingService");\r
+            }            \r
+        }        \r
+        return null;\r
+    }\r
+    \r
+    /**\r
+     * Get the identifier for the service name as per the rules above.\r
+     * @return something sensible for display.\r
+     */\r
+    protected String getServiceName() {\r
+        String result;\r
+        //\r
+        // First look for MDUI\r
+        //\r
+        if (getSPEntityDescriptor() == null) {\r
+            log.debug("No relying party, nothing to display");\r
+            return null;\r
+        }\r
+        //\r
+        // Look at <UIInfo>\r
+        //\r
+        result = getNameFromUIInfo();\r
+        if (result != null) {\r
+            return result;\r
+        }\r
+        \r
+        //\r
+        // Otherwise <AttributeConsumingService>\r
+        //\r
+        result = getNameFromAttributeConsumingService();\r
+        if (result != null) {\r
+            return result;\r
+        }\r
+        \r
+        //\r
+        // Or look at the entityName\r
+        //\r
+        return getNameFromEntityId();\r
+    }\r
+    \r
+\r
 }\r
index 6f5a318..ebcc7eb 100644 (file)
@@ -82,9 +82,9 @@
   </tag>\r
   \r
   <tag>\r
-    <description>Service descriptionrmationURL - directly from the metadata if present</description>\r
-    <name>servicedescriptionrmationURL</name>\r
-    <tag-class>edu.internet2.middleware.shibboleth.idp.ui.ServicedescriptionrmationURLTag</tag-class>\r
+    <description>Service Information URL - directly from the metadata if present</description>\r
+    <name>serviceInformationURL</name>\r
+    <tag-class>edu.internet2.middleware.shibboleth.idp.ui.ServiceInformationURLTag</tag-class>\r
     <body-content>scriptless</body-content>\r
     <attribute>\r
       <name>linkText</name>\r
     <tag-class>edu.internet2.middleware.shibboleth.idp.ui.ServiceLogoTag</tag-class>\r
     <body-content>scriptless</body-content>\r
     <attribute>\r
+      <name>alt</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
       <name>minHeight</name>\r
       <required>false</required>\r
       <rtexprvalue>true</rtexprvalue>\r
index eb494b0..edf5e8b 100644 (file)
@@ -6,7 +6,7 @@
   </head>\r
 \r
   <body id="homepage">\r
-    <img src="<%= request.getContextPath()%>/images/logo.jpg" />\r
+    <img src="<%= request.getContextPath()%>/images/logo.jpg" alt="Shibboleth Logo"/>\r
     <h1>Example Login Page</h1>\r
     <p>This login page is an example and should be customized.  Refer to the \r
        <a href="https://wiki.shibboleth.net/confluence/display/SHIB2/IdPAuthUserPassLoginPage" target="_blank"> documentation</a>.\r