View Javadoc

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