View Javadoc

    1   /*
    2    * Copyright 2011 University Corporation for Advanced Internet Development, Inc.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    * http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16
    17  package edu.internet2.middleware.shibboleth.idp.ui;
    18
    19  import java.io.IOException;
    20  import java.net.URI;
    21  import java.net.URISyntaxException;
    22
    23  import javax.servlet.jsp.JspException;
    24  import javax.servlet.jsp.JspWriter;
    25  import javax.servlet.jsp.tagext.BodyContent;
    26
    27  import org.opensaml.samlext.saml2mdui.Logo;
    28  import org.owasp.esapi.ESAPI;
    29  import org.owasp.esapi.Encoder;
    30  import org.slf4j.Logger;
    31  import org.slf4j.LoggerFactory;
    32
    33  /**Logo for the SP.*/
    34  public class ServiceLogoTag extends ServiceTagSupport {
    35
    36      /**
    37       * checkstyle control.
    38       */
    39      private static final long serialVersionUID = 6451849117572923712L;
    40      /** Class logger. */
    41      private static Logger log = LoggerFactory.getLogger(ServiceLogoTag.class);
    42      /** what to emit if the jsp has nothing. */
    43      private static final String DEFAULT_VALUE = "";
    44      /** what to emit as alt txt if all else fails. */
    45      private static final String DEFAULT_ALT_TXT = "SP Logo";
    46
    47      /** Bean storage. Size constraint X */
    48      private int minWidth;
    49      /** Bean storage. Size constraint X */
    50      private int maxWidth = Integer.MAX_VALUE;
    51      /** Bean storage. Size constraint Y */
    52      private int minHeight;
    53      /** Bean storage.  Size constraint Y */
    54      private int maxHeight = Integer.MAX_VALUE;
    55      /** Bean storage.  alt text */
    56      private String altTxt;
    57
    58      /** Bean setter.
    59       * @param value what to set
    60       */
    61      public void setMaxWidth(Integer value) {
    62          maxWidth = value.intValue();
    63      }
    64      /** Bean setter.
    65       * @param value what to set
    66       */
    67      public void setMinWidth(Integer value) {
    68          minWidth = value.intValue();
    69      }
    70      /** Bean setter.
    71       * @param value what to set
    72       */
    73      public void setMinHeight(Integer value) {
    74          minHeight = value.intValue();
    75      }
    76      /** Bean setter.
    77       * @param value what to set
    78       */
    79      public void setMaxHeight(Integer value) {
    80          maxHeight = value.intValue();
    81      }
    82
    83      /** Bean setter.
    84       * @param value what to set
    85       */
    86      public void setAlt(String value) {
    87          altTxt = value;
    88      }
    89
    90      /**
    91       * Whether the provided logo fits inside the constraints.
    92       * @param logo the logo
    93       * @return whether it fits the provided max and mins
    94       */
    95      private boolean logoFits(Logo logo) {
    96          return logo.getHeight() <= maxHeight && logo.getHeight() >= minHeight &&
    97                 logo.getWidth() <= maxWidth && logo.getWidth() >= minWidth;
    98      }
    99
    100     /**
    101      * get an appropriate Logo from UIInfo.
    102      * @return the URL for a logo
    103      */
    104     private String getLogoFromUIInfo() {
    105         String lang = getBrowserLanguage();
    106
    107         if (getSPUIInfo() != null && getSPUIInfo().getDescriptions() != null) {
    108             for (Logo logo:getSPUIInfo().getLogos()) {
    109                 if (log.isDebugEnabled()){
    110                     log.debug("Found logo in UIInfo, language=" + logo.getXMLLang() +
    111                             " width=" + logo.getWidth() + " height=" +logo.getHeight());
    112                 }
    113                 if (null != logo.getXMLLang() && !logo.getXMLLang().equals(lang)) {
    114                     //
    115                     // there is a language and its now what we want
    116                     continue;
    117                 }
    118                 if (!logoFits(logo)) {
    119                     //
    120                     // size out of range
    121                     //
    122                     continue;
    123                 }
    124                 //
    125                 // Found it
    126                 //
    127                 if (log.isDebugEnabled()) {
    128                     log.debug("returning logo from UIInfo " + logo.getURL());
    129                 }
    130                 return logo.getURL();
    131             }
    132             if (log.isDebugEnabled()){
    133                 log.debug("No appropriate logo in UIInfo");
    134             }
    135         }
    136         return null;
    137     }
    138
    139     /** Find what the user specified for alt txt.
    140      * @return the text required
    141      */
    142     private String getAltText() {
    143
    144         //
    145         // First see what the user tried
    146         //
    147         String value = altTxt;
    148         if (null != value && 0 != value.length()) {
    149             return value;
    150         }
    151
    152         //
    153         // Try the request
    154         //
    155         value = getServiceName();
    156         if (null != value && 0 != value.length()) {
    157             return value;
    158         }
    159
    160         return DEFAULT_ALT_TXT;
    161     }
    162
    163     /**
    164      * Given the url build an appropriate &lta href=...
    165      * @return the contrcuted hyperlink or null
    166      */
    167     private String getHyperlink() {
    168         String url = getLogoFromUIInfo();
    169         String encodedURL;
    170         StringBuilder sb;
    171         Encoder esapiEncoder = ESAPI.encoder();
    172
    173         if (null == url) {
    174             return null;
    175         }
    176
    177         try {
    178             URI theUrl = new URI(url);
    179             String scheme = theUrl.getScheme();
    180
    181             if (!"http".equals(scheme) && !"https".equals(scheme) && !"mailto".equals(scheme)) {
    182                 log.warn("The logo URL " + url + " contained an invalid scheme");
    183                 return null;
    184             }
    185         } catch (URISyntaxException e) {
    186             //
    187             // Could not encode
    188             //
    189             log.warn("The logo URL " + url + " was not a URL " + e.toString());
    190             return null;
    191         }
    192
    193
    194         encodedURL = esapiEncoder.encodeForHTMLAttribute(url);
    195
    196         sb = new StringBuilder("<img src=\"");
    197         sb.append(encodedURL).append('"');
    198         sb.append("alt=").append(getAltText()).append('"');
    199         addClassAndId(sb);
    200         sb.append("/>");
    201         return sb.toString();
    202     }
    203
    204     @Override
    205     public int doEndTag() throws JspException {
    206
    207         String result = getHyperlink();
    208
    209         try {
    210             if (null == result) {
    211                 BodyContent bc = getBodyContent();
    212                 boolean written = false;
    213                 if (null != bc) {
    214                     JspWriter ew= bc.getEnclosingWriter();
    215                     if (ew != null) {
    216                         bc.writeOut(ew);
    217                         written = true;
    218                     }
    219                 }
    220                 if (!written) {
    221                     //
    222                     // No value provided put in our own hardwired default
    223                     //
    224                     pageContext.getOut().print(DEFAULT_VALUE);
    225                 }
    226             } else {
    227                 pageContext.getOut().print(result);
    228             }
    229         } catch (IOException e) {
    230             log.warn("Error generating Description");
    231             throw new JspException("EndTag", e);
    232         }
    233         return super.doEndTag();
    234     }
    235 }