001package org.gbif.utils.html;
002
003import java.lang.reflect.InvocationTargetException;
004import java.util.Map;
005import java.util.Set;
006
007import com.google.common.base.Preconditions;
008import org.apache.commons.beanutils.PropertyUtils;
009import org.owasp.html.PolicyFactory;
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013/**
014 * Simple wrapper around OWASP Html Sanitizer to apply it to all String properties of a bean.
015 */
016public class BeanHtmlSanitizer {
017
018  private static final Logger LOG = LoggerFactory.getLogger(BeanHtmlSanitizer.class);
019
020  /**
021   * Apply the {@link PolicyFactory} to all String properties of the provided bean.
022   * This function will only apply sanitization to properties that are String and will only
023   * be applied to the variable of the provided bean. In other words, it won't be applied to inner-beans.
024   *
025   * @param obj
026   * @param policy
027   * @param exclusion set of property that should not be sanitized
028   * @param <T>
029   * @return same instance of the provided bean with all String properties sanitized by the {@link PolicyFactory}.
030   */
031  public static <T> T sanitize(T obj, PolicyFactory policy, Set<String> exclusion) {
032    Preconditions.checkNotNull(obj, "The provided object can not be null");
033    Preconditions.checkNotNull(policy, "The provided policy can not be null");
034
035    try {
036      Map<String, Object> properties = PropertyUtils.describe(obj);
037      for (String property : properties.keySet()) {
038        if ((exclusion == null || !exclusion.contains(property)) &&
039                String.class.equals(PropertyUtils.getPropertyType(obj, property))) {
040          PropertyUtils.setProperty(obj, property, policy.sanitize((String) properties.get(property)));
041        }
042      }
043      //TODO change for Java 7 multicatch when possible
044    } catch (IllegalAccessException e) {
045      LOG.error("Issue while applying HTML sanitization", e);
046    } catch (InvocationTargetException e) {
047      LOG.error("Issue while applying HTML sanitization", e);
048    } catch (NoSuchMethodException e) {
049      LOG.error("Issue while applying HTML sanitization", e);
050    }
051    return obj;
052  }
053
054  /**
055   * Apply the {@link PolicyFactory} to all String properties of the provided bean.
056   * This function will only apply sanitization to properties that are String and will only
057   * be applied to the variable of the provided bean. In other words, it won't be applied to inner-beans.
058   *
059   * @return same instance of the provided bean with all String properties sanitized by the {@link PolicyFactory}.
060   */
061  public static <T> T sanitize(T obj, PolicyFactory policy) {
062    return sanitize(obj, policy, null);
063  }
064
065}