SIDP-468
authorrdw <rdw@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Sat, 12 Mar 2011 12:08:00 +0000 (12:08 +0000)
committerrdw <rdw@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Sat, 12 Mar 2011 12:08:00 +0000 (12:08 +0000)
Add taglib support for <mdui:UIInfo/> statements - amongst other things

git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/branches/REL_2@2992 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

13 files changed:
pom.xml
src/installer/resources/build.xml
src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceContactTag.java [new file with mode: 0644]
src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceDescriptionTag.java [new file with mode: 0644]
src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceInformationURLTag.java [new file with mode: 0644]
src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceLogoTag.java [new file with mode: 0644]
src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceNameTag.java [new file with mode: 0644]
src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServicePrivacyURLTag.java [new file with mode: 0644]
src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceTagSupport.java [new file with mode: 0644]
src/main/java/edu/internet2/middleware/shibboleth/idp/ui/package-info.java [new file with mode: 0644]
src/main/webapp/WEB-INF/mduitaglib.tld [new file with mode: 0644]
src/main/webapp/WEB-INF/web.xml
src/main/webapp/login.jsp

diff --git a/pom.xml b/pom.xml
index 9b21358..0548626 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -46,7 +46,7 @@
         <dependency>
             <groupId>edu.internet2.middleware</groupId>
             <artifactId>shibboleth-common</artifactId>
-            <version>1.3.0</version>
+            <version>1.3.1</version>
         </dependency>
         
         <!-- Provided dependencies -->
             <artifactId>servlet-api</artifactId>
             <version>2.4</version>
         </dependency>
+        
+        <dependency>
+            <groupId>javax.servlet.jsp</groupId>
+            <artifactId>jsp-api</artifactId>
+            <version>2.0</version>
+        </dependency>
+
                 
         <!-- Runtime dependencies -->
         <dependency>
index ad1a7b6..6d8fd45 100755 (executable)
 
         <!-- build the war file -->
         <war warfile="${installer.dir}/${war.name}.war" webxml="${installer.dir}/web.xml">
-            <lib dir="${basedir}/lib" excludes="servlet-api*.jar"/>
+            <lib dir="${basedir}/lib" excludes="servlet-api*.jar,jsp-api*.jar"/>
             <webinf dir="${webapp.dir}/WEB-INF" excludes="web.xml" />
             <fileset dir="${webapp.dir}" excludes="WEB-INF/**" />
         </war>
diff --git a/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceContactTag.java b/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceContactTag.java
new file mode 100644 (file)
index 0000000..45061e9
--- /dev/null
@@ -0,0 +1,200 @@
+/*\r
+ * Copyright 2011 University Corporation for Advanced Internet Development, Inc.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package edu.internet2.middleware.shibboleth.idp.ui;\r
+\r
+import java.io.IOException;\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.ContactPerson;\r
+import org.opensaml.saml2.metadata.ContactPersonTypeEnumeration;\r
+import org.opensaml.saml2.metadata.EmailAddress;\r
+import org.opensaml.saml2.metadata.GivenName;\r
+import org.opensaml.saml2.metadata.SurName;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/** return the contactInfo for the SP or null. */\r
+public class ServiceContactTag extends ServiceTagSupport {\r
+    \r
+    /** required by checkstyle. */\r
+    private static final long serialVersionUID = -4000690571141490553L;\r
+\r
+    /** Class logger. */\r
+    private static Logger log = LoggerFactory.getLogger(ServiceContactTag.class);\r
+\r
+    /** storage for the contactType bean. */\r
+    private ContactPersonTypeEnumeration contactType = ContactPersonTypeEnumeration.SUPPORT;\r
+    \r
+    /** bean storage for the name attribute. */\r
+    private String contactName;\r
+    \r
+    /** \r
+     * Setter for the contactType bean.\r
+     * @param type in value\r
+     */\r
+    public void setContactType(String type) {\r
+        if (null == type || 0 == type.length()) {\r
+            log.warn("no parameter provided to contactType");\r
+            return;\r
+        }\r
+        if (type.equals(ContactPersonTypeEnumeration.ADMINISTRATIVE)) {\r
+            contactType = ContactPersonTypeEnumeration.ADMINISTRATIVE;\r
+        } else if (type.equals(ContactPersonTypeEnumeration.BILLING)) {\r
+            contactType = ContactPersonTypeEnumeration.BILLING;\r
+        } else if (type.equals(ContactPersonTypeEnumeration.OTHER)) {\r
+            contactType = ContactPersonTypeEnumeration.OTHER;\r
+        } else if (type.equals(ContactPersonTypeEnumeration.SUPPORT)) {\r
+            contactType = ContactPersonTypeEnumeration.SUPPORT;\r
+        } else if (type.equals(ContactPersonTypeEnumeration.TECHNICAL)) {\r
+            contactType = ContactPersonTypeEnumeration.TECHNICAL;\r
+        } else {\r
+            log.warn("parameter provided to contactType:" + type + " is invalid");\r
+            return;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Set the bean.\r
+     * @param s new value\r
+     */\r
+    public void setName(String s) {\r
+        contactName = s;\r
+    }\r
+    \r
+    /**\r
+     * either return the name raw or garnshed in a hyperlink.\r
+     * @param email the email address (a url)\r
+     * @param name the name to return.\r
+     * @return either a hyperlink or a raw string\r
+     */\r
+    private String buildURL(String email, String name){\r
+        //\r
+        // We have emailAdress or null and a  non empty fullName.\r
+        //\r
+        if (null != email) {\r
+            //\r
+            // Nonempty email. Construct an href\r
+            //\r
+            if (log.isDebugEnabled()) {\r
+                log.debug("constructing hyperlink from name \"" + name+ "\" and email " + email);\r
+            }\r
+            return buildHyperLink(email, name);\r
+        } else {\r
+            //\r
+            // No mail, no href\r
+            //\r
+            if (log.isDebugEnabled()) {\r
+                log.debug("no email found, using name \"" + name + "\" with no hyperlink");\r
+            }\r
+            return name.toString();\r
+        }\r
+        \r
+    }\r
+    \r
+    /**\r
+     * build an appropriate string from the &ltContact&gt.\r
+     * @param contact who we are interested in.\r
+     * @return either an hyperlink or straight text or null\r
+     */\r
+     private String getStringFromContact(ContactPerson contact) {\r
+        StringBuilder fullName = new StringBuilder();\r
+        GivenName givenName = contact.getGivenName();\r
+        SurName surName = contact.getSurName();\r
+        List<EmailAddress> emails = contact.getEmailAddresses();\r
+        String emailAddress = null;\r
+\r
+        //\r
+        // grab email - of there is one\r
+        //\r
+        if (emails != null && !emails.isEmpty()) {\r
+            emailAddress = emails.get(0).getAddress();\r
+        }\r
+        \r
+        if (null != contactName) {\r
+            return buildURL(emailAddress, contactName);\r
+        }\r
+        //\r
+        // Otherwise we build it from whats in the metadata\r
+        //\r
+        if (null != givenName) {\r
+            fullName.append(givenName.getName()).append(" ");\r
+        }\r
+        if (null != surName) {\r
+            fullName.append(surName.getName()).append(" ");\r
+        }\r
+        if (0 == fullName.length()) {\r
+            if (null == emails) {\r
+                //\r
+                // No name, no email, nothing we can do\r
+                //\r
+                return null;\r
+            }\r
+            if (log.isDebugEnabled()) {\r
+                log.debug("no names found, using email address as text");\r
+            }\r
+            fullName.append(emailAddress);\r
+        }\r
+        return buildURL(emailAddress, fullName.toString());\r
+    }\r
+    \r
+    /** \r
+     * build an appropriate string from the &ltEntityDescriptor&gt.\r
+     * @return either an hyperlink or straight text or null.\r
+     */\r
+    protected String getContactFromEntity() {\r
+        List<ContactPerson> contacts = getSPEntityDescriptor().getContactPersons();\r
+        if (null == contacts) {\r
+            return null;\r
+        }\r
+        for (ContactPerson contact:contacts) {\r
+            if (contactType == contact.getType()) {\r
+                return getStringFromContact(contact);\r
+            }\r
+        } \r
+        return null;\r
+    }\r
+    \r
+    @Override\r
+    public int doEndTag() throws JspException {\r
+       \r
+        String result;\r
+        result = getContactFromEntity();\r
+        \r
+        try {\r
+            if (null == result) {\r
+                BodyContent bc = getBodyContent();\r
+                if (null != bc) {\r
+                    JspWriter ew= bc.getEnclosingWriter();\r
+                    if (ew != null) {\r
+                        bc.writeOut(ew);\r
+                    }\r
+                }\r
+            } else {\r
+                pageContext.getOut().print(result);\r
+            }\r
+        } catch (IOException e) {\r
+            log.warn("Error generating Description");\r
+            throw new JspException("EndTag", e);\r
+        }\r
+        return super.doEndTag();\r
+    }\r
+\r
+}\r
diff --git a/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceDescriptionTag.java b/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceDescriptionTag.java
new file mode 100644 (file)
index 0000000..8d17bbe
--- /dev/null
@@ -0,0 +1,144 @@
+/*\r
+ * Copyright 2011 University Corporation for Advanced Internet Development, Inc.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package edu.internet2.middleware.shibboleth.idp.ui;\r
+\r
+import java.io.IOException;\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.LocalizedString;\r
+import org.opensaml.saml2.metadata.RoleDescriptor;\r
+import org.opensaml.saml2.metadata.SPSSODescriptor;\r
+import org.opensaml.saml2.metadata.ServiceDescription;\r
+import org.opensaml.samlext.saml2mdui.Description;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ * Display the description from the &lt;mdui:UIInfo&gt;.\r
+ * \r
+ */\r
+public class ServiceDescriptionTag extends ServiceTagSupport {\r
+    \r
+    /** required by checkstyle. */\r
+    private static final long serialVersionUID = -2000941439055969537L;\r
+    /** Class logger. */\r
+    private static Logger log = LoggerFactory.getLogger(ServiceDescriptionTag.class);\r
+\r
+    /** \r
+     * look at &lt;Uiinfo&gt; if there and if so look for appropriate description.\r
+     * @return null or an appropriate description\r
+     */\r
+    private String getDescriptionFromUIInfo() {\r
+        String lang = getBrowserLanguage();\r
+\r
+        if (getSPUIInfo() != null && getSPUIInfo().getDescriptions() != null) {\r
+            for (Description desc:getSPUIInfo().getDescriptions()) {\r
+                if (log.isDebugEnabled()){\r
+                    log.debug("Found description in UIInfo, language=" + desc.getXMLLang());\r
+                }\r
+                if (desc.getXMLLang().equals(lang)) {\r
+                    //\r
+                    // Found it\r
+                    //\r
+                    if (log.isDebugEnabled()){\r
+                        log.debug("returning description from UIInfo " + desc.getName().getLocalString());\r
+                    }\r
+                    return desc.getName().getLocalString();\r
+                }\r
+            }\r
+            if (log.isDebugEnabled()){\r
+                log.debug("No valid description in UIInfo");\r
+            }            \r
+        }\r
+        return null;\r
+    }\r
+    \r
+    /**\r
+     * look for an &ltAttributeConsumeService&gt and if its there look for an appropriate description.\r
+     * @return null or an appropriate description\r
+     */\r
+    private String getDescriptionFromAttributeConsumingService() {\r
+        String lang = getBrowserLanguage();\r
+        List<RoleDescriptor> roles;\r
+        AttributeConsumingService acs = null;\r
+\r
+        roles = getSPEntityDescriptor().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 (ServiceDescription desc:acs.getDescriptions()) {\r
+                LocalizedString localDescription = desc.getDescription();\r
+                if (log.isDebugEnabled()){\r
+                    log.debug("Found name in AttributeConsumingService, language=" + localDescription.getLanguage());\r
+                }\r
+                if (localDescription.getLanguage().equals(lang)) {\r
+                    if (log.isDebugEnabled()){\r
+                        log.debug("returning name from AttributeConsumingService " + \r
+                                desc.getDescription().getLocalString());\r
+                    }\r
+                    return localDescription.getLocalString();\r
+                }\r
+            }\r
+            if (log.isDebugEnabled()){\r
+                log.debug("No description in AttributeConsumingService");\r
+            }            \r
+        }        \r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public int doEndTag() throws JspException {\r
+       \r
+        String result;\r
+        //\r
+        // UIInfoirst\r
+        //\r
+        result = getDescriptionFromUIInfo();\r
+        \r
+        if (result == null) {\r
+            //\r
+            // Then AttributeCOnsumingService\r
+            //\r
+            result = getDescriptionFromAttributeConsumingService();\r
+        }\r
+\r
+        try {\r
+            if (null == result) {\r
+                BodyContent bc = getBodyContent();\r
+                if (null != bc) {\r
+                    JspWriter ew= bc.getEnclosingWriter();\r
+                    if (ew != null) {\r
+                        bc.writeOut(ew);\r
+                    }\r
+                }\r
+            } else {\r
+                pageContext.getOut().print(result);\r
+            }\r
+        } catch (IOException e) {\r
+            log.warn("Error generating Description");\r
+            throw new JspException("EndTag", e);\r
+        }\r
+        return super.doEndTag();\r
+    }\r
+}\r
diff --git a/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceInformationURLTag.java b/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceInformationURLTag.java
new file mode 100644 (file)
index 0000000..31f4be0
--- /dev/null
@@ -0,0 +1,101 @@
+/*\r
+ * Copyright 2011 University Corporation for Advanced Internet Development, Inc.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package edu.internet2.middleware.shibboleth.idp.ui;\r
+\r
+import java.io.IOException;\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.samlext.saml2mdui.InformationURL;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**Service InformationURL - directly from the metadata if present.*/\r
+public class ServiceInformationURLTag extends ServiceTagSupport {\r
+    \r
+    /** check style requires the serialVersionUID.*/\r
+    private static final long serialVersionUID = 5601822745575892676L;\r
+    /** Class logger. */\r
+    private static Logger log = LoggerFactory.getLogger(ServiceInformationURLTag.class);\r
+\r
+    /** Bean storage for the link text attribute. */\r
+    private static String linkText;\r
+\r
+    /** Bean setter  for the link text attribute.\r
+     * @param text the link text to put in\r
+     */\r
+    public void setLinkText(String text) {\r
+        linkText = text;\r
+    }\r
+    \r
+    /**\r
+     * look for the &lt;InformationURL&gt; in the &lt;UIInfo&gt;.\r
+     * @return null or an appropriate string.\r
+     */\r
+    private String getInformationURLFromUIIinfo() {\r
+        String lang = getBrowserLanguage();\r
+\r
+        if (getSPUIInfo() != null && getSPUIInfo().getInformationURLs() != null) {\r
+            for (InformationURL infoURL:getSPUIInfo().getInformationURLs()) {\r
+                if (log.isDebugEnabled()){\r
+                    log.debug("Found InformationURL in UIInfo, language=" + infoURL.getXMLLang());\r
+                }\r
+                if (infoURL.getXMLLang().equals(lang)) {\r
+                    //\r
+                    // Found it\r
+                    //\r
+                    if (log.isDebugEnabled()){\r
+                        log.debug("returning URL from UIInfo " + infoURL.getURI().getLocalString());\r
+                    }\r
+                    return infoURL.getURI().getLocalString();\r
+                }\r
+            }\r
+            if (log.isDebugEnabled()){\r
+                log.debug("No relevant InformationURL in UIInfo");\r
+            }                       \r
+        }\r
+        return null;\r
+    }\r
+    @Override\r
+\r
+    public int doEndTag() throws JspException {\r
+       \r
+        String infoURL = getInformationURLFromUIIinfo();\r
+        \r
+        try {\r
+            if (null == infoURL) {\r
+                BodyContent bc = getBodyContent();\r
+                if (null != bc) {\r
+                    JspWriter ew= bc.getEnclosingWriter();\r
+                    if (ew != null) {\r
+                        bc.writeOut(ew);\r
+                    }\r
+                }\r
+            } else {\r
+                pageContext.getOut().print(buildHyperLink(infoURL, linkText));\r
+            }\r
+        } catch (IOException e) {\r
+            log.warn("Error generating Description");\r
+            throw new JspException("EndTag", e);\r
+        }\r
+        return super.doEndTag();\r
+    }\r
+\r
+\r
+}\r
diff --git a/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceLogoTag.java b/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceLogoTag.java
new file mode 100644 (file)
index 0000000..db09d30
--- /dev/null
@@ -0,0 +1,173 @@
+/*\r
+ * Copyright 2011 University Corporation for Advanced Internet Development, Inc.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package edu.internet2.middleware.shibboleth.idp.ui;\r
+\r
+import java.io.IOException;\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.samlext.saml2mdui.Logo;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**Logo for the SP.*/\r
+public class ServiceLogoTag extends ServiceTagSupport {\r
+\r
+    /**\r
+     * checkstype 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
+\r
+    /** Bean storage. Size constraint X */\r
+    private int minWidth;\r
+    /** Bean storage. Size constraint X */\r
+    private int maxWidth = Integer.MAX_VALUE;\r
+    /** Bean storage. Size constraint Y */\r
+    private int minHeight;\r
+    /** Bean storage.  Size constraint Y */\r
+    private int maxHeight = Integer.MAX_VALUE;\r
+\r
+    /** Bean setter.\r
+     * @param value what to set\r
+     */\r
+    public void setMaxWidth(Integer value) {\r
+        maxWidth = value.intValue();\r
+    }\r
+    /** Bean setter.\r
+     * @param value what to set\r
+     */\r
+    public void setMinWidth(Integer value) {\r
+        minWidth = value.intValue();\r
+    }\r
+    /** Bean setter.\r
+     * @param value what to set\r
+     */\r
+    public void setMinHeight(Integer value) {\r
+        minHeight = value.intValue();\r
+    }\r
+    /** Bean setter.\r
+     * @param value what to set\r
+     */\r
+    public void setMaxHeight(Integer value) {\r
+        maxHeight = value.intValue();\r
+    }\r
+\r
+    /**\r
+     * Whether the provided logo fits inside the constraints.\r
+     * @param logo the logo\r
+     * @return whether it fits the provided max and mins\r
+     */\r
+    private boolean logoFits(Logo logo) {\r
+        return logo.getHeight() <= maxHeight && logo.getHeight() >= minHeight &&\r
+               logo.getWidth() <= maxWidth && logo.getWidth() >= minWidth;\r
+    }\r
+    \r
+    /**\r
+     * get an appropriate Logo from UIInfo.\r
+     * @return the URL for a logo\r
+     */\r
+    private String getLogoFromUIInfo() {\r
+        String lang = getBrowserLanguage();\r
+\r
+        if (getSPUIInfo() != null && getSPUIInfo().getDescriptions() != null) {\r
+            for (Logo logo:getSPUIInfo().getLogos()) {\r
+                if (log.isDebugEnabled()){\r
+                    log.debug("Found logo in UIInfo, language=" + logo.getXMLLang() + \r
+                            " width=" + logo.getWidth() + " height=" +logo.getHeight());\r
+                }\r
+                if (null != logo.getXMLLang() && !logo.getXMLLang().equals(lang)) {\r
+                    //\r
+                    // there is a language and its now what we want\r
+                    continue;\r
+                }\r
+                if (!logoFits(logo)) {\r
+                    //\r
+                    // size out of range\r
+                    //\r
+                    continue;\r
+                }\r
+                //\r
+                // Found it\r
+                //\r
+                if (log.isDebugEnabled()) {\r
+                    log.debug("returning logo from UIInfo " + logo.getURL());\r
+                }\r
+                return logo.getURL();\r
+            }\r
+            if (log.isDebugEnabled()){\r
+                log.debug("No appropriate logo in UIInfo");\r
+            }            \r
+        }\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Given the url build an appropriate &lta href=...\r
+     * @return the contrcuted hyperlink or null\r
+     */\r
+    private String getHyperlink() {\r
+        String url = getLogoFromUIInfo();\r
+        StringBuilder sb;\r
+        \r
+        if (null == url) {\r
+            return null;\r
+        }\r
+        sb = new StringBuilder("<img src=\"");\r
+        sb.append(url).append('"');\r
+        addClassAndId(sb);\r
+        sb.append("/>");\r
+        return sb.toString();\r
+    }\r
+    \r
+    @Override\r
+    public int doEndTag() throws JspException {\r
+       \r
+        String result = getHyperlink();\r
+        \r
+        try {\r
+            if (null == result) {\r
+                BodyContent bc = getBodyContent();\r
+                boolean written = false;\r
+                if (null != bc) {\r
+                    JspWriter ew= bc.getEnclosingWriter();\r
+                    if (ew != null) {\r
+                        bc.writeOut(ew);\r
+                        written = true;\r
+                    }\r
+                }\r
+                if (!written) {\r
+                    //\r
+                    // No value provided put in our own hardwired default\r
+                    //\r
+                    pageContext.getOut().print(DEFAULT_VALUE);\r
+                }\r
+            } else {\r
+                pageContext.getOut().print(result);\r
+            }\r
+        } catch (IOException e) {\r
+            log.warn("Error generating Description");\r
+            throw new JspException("EndTag", e);\r
+        }\r
+        return super.doEndTag();\r
+    }\r
+}\r
diff --git a/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceNameTag.java b/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceNameTag.java
new file mode 100644 (file)
index 0000000..3feaee6
--- /dev/null
@@ -0,0 +1,186 @@
+/*\r
+ * Copyright 2011 University Corporation for Advanced Internet Development, Inc.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+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
+\r
+import org.opensaml.saml2.metadata.AttributeConsumingService;\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.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+\r
+/**\r
+ * Display the serviceName.\r
+ * \r
+ * This is taken in order\r
+ *  1) From the mdui\r
+ *  2) AttributeConsumeService\r
+ *  3) HostName from the EntityId\r
+ *  4) EntityId.\r
+ */\r
+public class ServiceNameTag extends ServiceTagSupport {\r
+\r
+    /** checkstyle requires one of these. */\r
+    private static final long serialVersionUID = 8883158293402992407L;\r
+    /** Class logger. */\r
+    private static Logger log = LoggerFactory.getLogger(ServiceNameTag.class);\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
+        try {\r
+            URI entityId = new URI(getSPEntityDescriptor().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 getSPEntityDescriptor().getEntityID();\r
+        }\r
+        //\r
+        // not a URL return full entityID\r
+        //\r
+        return getSPEntityDescriptor().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
+\r
+        roles = getSPEntityDescriptor().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.warn("No relying party, nothing to display");\r
+            return "";\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
+        log.debug("StartTag");\r
+        try {\r
+            pageContext.getOut().print(getServiceName());\r
+        } catch (IOException e) {\r
+            log.warn("Error generating name");\r
+            throw new JspException("StartTag", e);\r
+        }\r
+        return super.doStartTag();\r
+    }\r
+}\r
diff --git a/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServicePrivacyURLTag.java b/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServicePrivacyURLTag.java
new file mode 100644 (file)
index 0000000..7f8c5a3
--- /dev/null
@@ -0,0 +1,102 @@
+/*\r
+ * Copyright 2011 University Corporation for Advanced Internet Development, Inc.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package edu.internet2.middleware.shibboleth.idp.ui;\r
+\r
+import java.io.IOException;\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.samlext.saml2mdui.PrivacyStatementURL;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/** Service PrivacyURL - directly from the metadata if present.*/\r
+public class ServicePrivacyURLTag extends ServiceTagSupport {\r
+\r
+    /** checkstyle needs serial version UID. */\r
+    private static final long serialVersionUID = 1706444251504545781L;\r
+    \r
+    /** Class logger. */\r
+    private static Logger log = LoggerFactory.getLogger(ServicePrivacyURLTag.class);\r
+\r
+    /** Bean storage for the link text attribute. */\r
+    private static String linkText;\r
+    \r
+    /** Bean setter  for the link text attribute.\r
+     * @param text the link text to put in\r
+     */\r
+    public void setLinkText(String text) {\r
+        linkText = text;\r
+    }\r
+    \r
+    /**\r
+     * look for the &lt;PrivacyURL&gt; in the &lt;UIInfo&gt;.\r
+     * @return null or an appropriate string.\r
+     */\r
+    private String getPrivacyURLFromUIIinfo() {\r
+        String lang = getBrowserLanguage();\r
+\r
+        if (getSPUIInfo() != null && getSPUIInfo().getPrivacyStatementURLs() != null) {\r
+            for (PrivacyStatementURL privacyURL:getSPUIInfo().getPrivacyStatementURLs()) {\r
+                if (log.isDebugEnabled()){\r
+                    log.debug("Found PrivacyStatementURL in UIInfo, language=" + privacyURL.getXMLLang());\r
+                }\r
+                if (privacyURL.getXMLLang().equals(lang)) {\r
+                    //\r
+                    // Found it\r
+                    //\r
+                    if (log.isDebugEnabled()){\r
+                        log.debug("returning URL from UIInfo " + privacyURL.getURI().getLocalString());\r
+                    }\r
+                    return privacyURL.getURI().getLocalString();\r
+                }\r
+            }\r
+            if (log.isDebugEnabled()){\r
+                log.debug("No relevant PrivacyStatementURL in UIInfo");\r
+            }                       \r
+        }\r
+        return null;\r
+    }\r
+    \r
+    @Override\r
+\r
+    public int doEndTag() throws JspException {\r
+       \r
+        String privacyURL = getPrivacyURLFromUIIinfo();\r
+        \r
+        try {\r
+            if (null == privacyURL) {\r
+                BodyContent bc = getBodyContent();\r
+                if (null != bc) {\r
+                    JspWriter ew= bc.getEnclosingWriter();\r
+                    if (ew != null) {\r
+                        bc.writeOut(ew);\r
+                    }\r
+                }\r
+            } else {\r
+                pageContext.getOut().print(buildHyperLink(privacyURL, linkText));\r
+            }\r
+        } catch (IOException e) {\r
+            log.warn("Error generating Description");\r
+            throw new JspException("EndTag", e);\r
+        }\r
+        return super.doEndTag();\r
+    }\r
+\r
+}\r
diff --git a/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceTagSupport.java b/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/ServiceTagSupport.java
new file mode 100644 (file)
index 0000000..b7cc466
--- /dev/null
@@ -0,0 +1,189 @@
+/*\r
+ * Copyright 2011 University Corporation for Advanced Internet Development, Inc.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package edu.internet2.middleware.shibboleth.idp.ui;\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.EntityDescriptor;\r
+import org.opensaml.saml2.metadata.RoleDescriptor;\r
+import org.opensaml.saml2.metadata.SPSSODescriptor;\r
+import org.opensaml.samlext.saml2mdui.UIInfo;\r
+import org.opensaml.xml.XMLObject;\r
+\r
+import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfigurationManager;\r
+import edu.internet2.middleware.shibboleth.idp.authn.LoginContext;\r
+import edu.internet2.middleware.shibboleth.idp.util.HttpServletHelper;\r
+\r
+\r
+/**\r
+ * Display the serviceName.\r
+ * \r
+ * This is taken in order\r
+ *  1) From the mdui\r
+ *  2) AttributeConsumeService\r
+ *  3) HostName from the EntityId\r
+ *  4) EntityId.\r
+ */\r
+public class ServiceTagSupport extends BodyTagSupport{\r
+\r
+    /**\r
+     * checkstyle requires this serialization info.\r
+     */\r
+    private static final long serialVersionUID = 7988646597267865255L;\r
+    /** The actual entity for the SP. */ \r
+    private EntityDescriptor spEntity;\r
+\r
+    /** Bean storage. class reference*/\r
+    private String cssClass;\r
+    /** Bean storage. id reference*/\r
+    private String cssId;\r
+    /** Bean storage. style reference*/\r
+    private String cssStyle;\r
+\r
+    /** The uiInfo (if present) for the SP. */\r
+    private UIInfo spUIInfo;\r
+    /** Whether we have tried to populate the above two. */\r
+    private boolean populated;\r
+    \r
+    /** Bean setter.\r
+     * @param value what to set\r
+     */\r
+    public void setCssClass(String value) {\r
+        cssClass = value;\r
+    }\r
+    /** Bean setter.\r
+     * @param value what to set\r
+     */\r
+    public void setCssId(String value) {\r
+        cssId = value;\r
+    }\r
+\r
+    /** Bean setter.\r
+     * @param value what to set\r
+     */\r
+    public void setCssStyle(String value) {\r
+        cssStyle = value;\r
+    }\r
+\r
+    /**\r
+     * Add the class and Id if present.\r
+     * @param sb the stringbuilder to asdd to.\r
+     */\r
+    protected void addClassAndId(StringBuilder sb) {\r
+        if (cssClass != null) {\r
+            sb.append(" class=\"").append(cssClass).append('"');\r
+        }\r
+        if (cssId != null) {\r
+            sb.append(" id=\"").append(cssId).append('"');\r
+        }\r
+        if (cssStyle != null) {\r
+            sb.append(" style=\"").append(cssStyle).append('"');\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * build a hyperlink from the parameters.\r
+     * @param url the URL\r
+     * @param text what to embed\r
+     * @return the hyperlink.\r
+     */\r
+    protected String buildHyperLink(String url, String text) {\r
+        StringBuilder sb = new StringBuilder("<a href=\"");\r
+        sb.append(url).append('"');\r
+        addClassAndId(sb);\r
+        sb.append(">").append(text).append("</a>");\r
+        return sb.toString();\r
+    }\r
+    \r
+    /** Populate spEntity and spUIInfo.  */\r
+    private void initialize() {\r
+        LoginContext loginContext;\r
+        HttpServletRequest request;\r
+        ServletContext application;\r
+        RelyingPartyConfigurationManager rpConfigMngr;\r
+\r
+        if (populated) {\r
+            return;\r
+        }\r
+        //\r
+        // Populate up those things that jsp gives us.\r
+        //\r
+        request = (HttpServletRequest) pageContext.getRequest();\r
+        application = pageContext.getServletContext();\r
+        \r
+        //\r
+        // grab the login context and the RP config mgr.\r
+        //\r
+        loginContext = HttpServletHelper.getLoginContext(HttpServletHelper.getStorageService(application),\r
+                application, request);\r
+        rpConfigMngr = HttpServletHelper.getRelyingPartyConfigurationManager(application);       \r
+        spEntity = HttpServletHelper.getRelyingPartyMetadata(loginContext.getRelyingPartyId(), rpConfigMngr);\r
+\r
+        Extensions exts;\r
+\r
+        populated = true;\r
+        if (null == spEntity) {\r
+            //\r
+            // all done\r
+            //\r
+            return;\r
+        }\r
+        for (RoleDescriptor role:spEntity.getRoleDescriptors(SPSSODescriptor.DEFAULT_ELEMENT_NAME)) {\r
+            exts = role.getExtensions();\r
+            for (XMLObject object:exts.getOrderedChildren()) {\r
+                if (object instanceof UIInfo) {\r
+                    spUIInfo = (UIInfo) object;\r
+                    //\r
+                    // found it\r
+                    //\r
+                    return;\r
+                }\r
+            }\r
+        }\r
+    }\r
+    /**\r
+     * Get the EntityDescriptor for the relying party.\r
+     * @return the SPs EntityDescriptor\r
+     */\r
+    protected EntityDescriptor getSPEntityDescriptor() {\r
+        initialize();\r
+        return spEntity;\r
+    }\r
+    /**\r
+     * Traverse the SP's EntityDescriptor and pick out the UIInfo.\r
+     * @return the first UIInfo for the SP.\r
+     */\r
+    protected UIInfo getSPUIInfo() {\r
+        initialize();\r
+        return spUIInfo;\r
+    }\r
+            \r
+    /**\r
+     * Pluck the language from the browser.\r
+     * @return the two letter language\r
+     */\r
+    protected String getBrowserLanguage() {\r
+        HttpServletRequest request;\r
+        request = (HttpServletRequest) pageContext.getRequest();\r
+        \r
+        return request.getLocale().getLanguage();\r
+    }\r
+       \r
+}\r
diff --git a/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/package-info.java b/src/main/java/edu/internet2/middleware/shibboleth/idp/ui/package-info.java
new file mode 100644 (file)
index 0000000..6d8e388
--- /dev/null
@@ -0,0 +1,23 @@
+/*\r
+ * Copyright 2011 University Corporation for Advanced Internet Development, Inc.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * UI package for the Shibboleth IdP.\r
+ * \r
+ * This package contains the taglibs used in displaying the login page (and other stuff) to the user.\r
+ */\r
+package edu.internet2.middleware.shibboleth.idp.ui;\r
+\r
diff --git a/src/main/webapp/WEB-INF/mduitaglib.tld b/src/main/webapp/WEB-INF/mduitaglib.tld
new file mode 100644 (file)
index 0000000..fa69565
--- /dev/null
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>\r
+<!DOCTYPE taglib\r\r
+        PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"\r
+        "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">\r
+<taglib>\r
+  <tlibversion>1.0</tlibversion>\r
+  <jspversion>1.2</jspversion>\r
+  <tag>\r
+    <name>serviceName</name>\r
+    <tagclass>edu.internet2.middleware.shibboleth.idp.ui.ServiceNameTag</tagclass>\r
+    <bodycontent>empty</bodycontent>\r
+    <info>Service Name - some user friendly information about the relying party</info>\r
+  </tag>\r
+  <tag>\r
+    <name>serviceDescription</name>\r
+    <tagclass>edu.internet2.middleware.shibboleth.idp.ui.ServiceDescriptionTag</tagclass>\r
+    <bodycontent>scriptless</bodycontent>\r
+    <info>Service Description - taken from the mdui statement</info>\r
+  </tag>\r
+  <tag>\r
+    <name>serviceContact</name>\r
+    <tagclass>edu.internet2.middleware.shibboleth.idp.ui.ServiceContactTag</tagclass>\r
+    <bodycontent>scriptless</bodycontent>\r
+    <info>Service Contact - information about contact info on the SP</info>\r
+    <attribute>\r
+      <name>contactType</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>name</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>cssId</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>cssClass</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>cssStyle</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+  </tag>\r
+  <tag>\r
+    <name>servicePrivacyURL</name>\r
+    <tagclass>edu.internet2.middleware.shibboleth.idp.ui.ServicePrivacyURLTag</tagclass>\r
+    <bodycontent>scriptless</bodycontent>\r
+    <info>Service PrivacyURL - directly from the metadata if present</info>\r
+    <attribute>\r
+      <name>linkText</name>\r
+      <required>true</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>cssId</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>cssClass</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>cssStyle</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+  </tag>\r
+  <tag>\r
+    <name>serviceInformationURL</name>\r
+    <tagclass>edu.internet2.middleware.shibboleth.idp.ui.ServiceInformationURLTag</tagclass>\r
+    <bodycontent>scriptless</bodycontent>\r
+    <info>Service InformationURL - directly from the metadata if present</info>\r
+    <attribute>\r
+      <name>linkText</name>\r
+      <required>true</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>cssId</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>cssClass</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>cssStyle</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+  </tag>\r
+  <tag>\r
+    <name>serviceLogo</name>\r
+    <tagclass>edu.internet2.middleware.shibboleth.idp.ui.ServiceLogoTag</tagclass>\r
+    <bodycontent>scriptless</bodycontent>\r
+    <info>Logo for the SP</info>\r
+    <attribute>\r
+      <name>minHeight</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>maxHeight</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>minWidth</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>maxWidth</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>cssId</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>cssClass</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+    <attribute>\r
+      <name>cssStyle</name>\r
+      <required>false</required>\r
+      <rtexprvalue>true</rtexprvalue>\r
+    </attribute>\r
+  </tag>\r
+</taglib>\r
index aba5855..89e0ed4 100644 (file)
     <!-- <login-config> <auth-method>FORM</auth-method> <realm-name>IdP Password Authentication</realm-name> <form-login-config> 
         <form-login-page>/login.jsp</form-login-page> <form-error-page>/login-error.jsp</form-error-page> </form-login-config> </login-config> -->
 
-</web-app>
\ No newline at end of file
+    <taglib>
+      <taglib-uri>/mdui</taglib-uri>
+      <taglib-location>/WEB-INF/mduitaglib.tld</taglib-location>
+    </taglib>
+</web-app>
index 9a2ff8e..9450563 100644 (file)
@@ -4,6 +4,9 @@
 <%@ page import="edu.internet2.middleware.shibboleth.idp.util.HttpServletHelper" %>
 <%@ page import="org.opensaml.saml2.metadata.*" %>
 
+<%@ taglib uri="/mdui" prefix="mdui" %>
+
+
 <%
     LoginContext loginContext = HttpServletHelper.getLoginContext(HttpServletHelper.getStorageService(application),
                                                                   application, request);
     <head>
         <title>Shibboleth Identity Provider - Example Login Page</title>
     </head>
-
        <body>
-               <img src="<%= request.getContextPath() %>/images/logo.jpg" />
+
+        <img src="<%= request.getContextPath()%>/images/logo.jpg" />
                <h1>Example Login Page</h1>
                <p>This login page is an example and should be customized.  Refer to the 
                        <a href="https://spaces.internet2.edu/display/SHIB2/IdPAuthUserPassLoginPage" target="_new"> documentation</a>.
                </p>
+               
+               <div style="border: 2px solid;padding: 4px">
+                 The Following information is made available via the &lt;mdui:taglibs&gt; It is included purely as
+          an example.
+
+            <p>
+                Service Name = <mdui:serviceName/>
+            </p>
+
+            <p>
+                The service description: is <mdui:serviceDescription>not present</mdui:serviceDescription>
+            </p>
+                
+            <p>
+                Support text could read:  If you don't know why you got here please contact <mdui:serviceContact cssClass="claz1">your support desk</mdui:serviceContact>
+            </p>
+
+            <p>
+                <mdui:servicePrivacyURL cssId="id2" linkText="The PS Privacy Statement">No Privacy Statement</mdui:servicePrivacyURL>
+            </p>
+            
+            <p>
+                <mdui:serviceInformationURL cssStyle="font-style:Italic" linkText="More Information">No Information URL</mdui:serviceInformationURL>
+            </p>
+
+            <mdui:serviceLogo cssId="logoId" cssClass="class" minWidth="20" maxHeight="400">No logo available</mdui:serviceLogo>
+        </div>
+    
 
                <% if (loginContext == null) { %>
                <p><font color="red">Error:</font> Direct access to this page is not supported.</p>