View Javadoc

    1   /*
    2    * Copyright 2008 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.wayf.plugins.provider;
    18
    19  import java.util.HashSet;
    20  import java.util.Iterator;
    21  import java.util.List;
    22  import java.util.Set;
    23
    24  import org.opensaml.saml2.metadata.EntitiesDescriptor;
    25  import org.opensaml.saml2.metadata.EntityDescriptor;
    26  import org.opensaml.saml2.metadata.provider.FilterException;
    27  import org.opensaml.saml2.metadata.provider.MetadataFilter;
    28  import org.opensaml.xml.XMLObject;
    29  import org.slf4j.Logger;
    30  import org.slf4j.LoggerFactory;
    31  import org.w3c.dom.Element;
    32  import org.w3c.dom.NodeList;
    33
    34  import edu.internet2.middleware.shibboleth.wayf.XMLConstants;
    35
    36  /**
    37   * See SDSJ-57.  Explicit
    38   *
    39   * @author Rod Widdowson
    40   *
    41   */
    42  public class ListFilter implements MetadataFilter {
    43
    44      /**
    45       * Log for any messages.
    46       */
    47      private static final Logger LOG = LoggerFactory.getLogger(ListFilter.class.getName());
    48
    49      /**
    50       * Set if this is a blacklist.
    51       */
    52      private boolean excludeEntries;
    53
    54      /**
    55       * The list of entities.
    56       */
    57      private final Set<String> filterEntities;
    58
    59      /**
    60       * The name of the filter (needed for debug).
    61       */
    62      private final String filterName;
    63
    64      /**
    65       * Only the protected constructor should be visible.
    66       */
    67      private ListFilter() {
    68          this.excludeEntries = false;
    69          this.filterEntities = new HashSet<String>(0);
    70          this.filterName = "anonymous";
    71      }
    72
    73      /**
    74       * Initialize the filter.
    75       * @param config the configuration
    76       *
    77       * The configuration looks liken this
    78       * <code> <Filter identifier="WhiteList"
    79       *                type ="edu.internet2.middleware.shibboleth.wayf.plugins.provider.ListFilter"
    80       *                excludeEntries = "true" >
    81       *        <EntityId>foo</EntityId>
    82       *        [...]
    83       *        </Filter>
    84       *  </code>
    85       */
    86      public ListFilter(Element config) {
    87          String excludeEntriesValue;
    88          this.filterEntities = new HashSet<String>(10);
    89          this.filterName = config.getAttribute("identifier");
    90          excludeEntriesValue = config.getAttribute("excludeEntries");
    91
    92          if (null == excludeEntriesValue || 0 == excludeEntriesValue.length()) {
    93              this.excludeEntries = true;
    94          } else {
    95              this.excludeEntries = Boolean.getBoolean(excludeEntriesValue);
    96          }
    97
    98          NodeList itemElements = config.getElementsByTagNameNS(XMLConstants.CONFIG_NS, "EntityId");
    99
    100         if (excludeEntries) {
    101             LOG.debug("Populating blacklist " + filterName);
    102         } else {
    103             LOG.debug("Populating whitelist " + filterName);
    104         }
    105
    106         for (int i = 0; i < itemElements.getLength(); i++) {
    107             Element element = (Element) itemElements.item(i);
    108             String entityId = element.getTextContent();
    109
    110             LOG.debug("\t" + entityId);
    111             this.filterEntities.add(entityId);
    112         }
    113     }
    114
    115     /**
    116      * Apply the filter.
    117      * @see org.opensaml.saml2.metadata.provider.MetadataFilter#doFilter(org.opensaml.xml.XMLObject)
    118      * @param metadata what to filter.
    119      * @throws FilterException if it sees any missed or bad bindings.
    120      */
    121     public void doFilter(XMLObject metadata) throws FilterException {
    122
    123         if (metadata instanceof EntitiesDescriptor) {
    124             filterEntities((EntitiesDescriptor)metadata);
    125         } else if (metadata instanceof EntityDescriptor) {
    126             EntityDescriptor entity = (EntityDescriptor) metadata;
    127             String entityName = entity.getEntityID();
    128
    129             if (excludeEntries) {
    130                 if (filterEntities.contains(entityName)) {
    131                     LOG.error("Metadata provider contains a single <EntityDescriptor> (" + entityName +
    132                               ") which is in exclude list");
    133                 }
    134             } else if (!filterEntities.contains(entity.getEntityID())) {
    135                 LOG.error("Metadata provider contains a single <EntityDescriptor>  (" + entityName +
    136                           ") which is not on include list");
    137             }
    138         }
    139     }
    140
    141     /**
    142      * Filter an EntitiesDescriptor .  We do this explictly for the Entities and call ourselves
    143      *  recursively for the EntitesDescriptors.
    144      *
    145      * @param entities what to check.
    146      */
    147     private void filterEntities(EntitiesDescriptor entities) {
    148         String entitiesName = entities.getName();
    149         List<EntitiesDescriptor> childEntities = entities.getEntitiesDescriptors();
    150         List<EntityDescriptor> children = entities.getEntityDescriptors();
    151
    152         //
    153         // Go through and apply the filter
    154         //
    155
    156         if (children != null) {
    157             Iterator<EntityDescriptor> itr;
    158             EntityDescriptor entity;
    159             itr = children.iterator();
    160
    161             while (itr.hasNext()) {
    162                 entity = itr.next();
    163                 String entityName = entity.getEntityID();
    164                 if (excludeEntries) {
    165
    166                     if (filterEntities.contains(entityName)) {
    167                         LOG.debug("Filter " + filterName + ": Removing blacklisted "  + entityName + " from " + entitiesName);
    168                         itr.remove();
    169                     }
    170                 } else if (!filterEntities.contains(entityName)) {
    171                     LOG.debug("Filter " + filterName + ": Removing non-whitelisted "  + entityName + " from " + entitiesName);
    172                     itr.remove();
    173                 }
    174             }
    175         }
    176
    177         if (childEntities != null) {
    178             for (EntitiesDescriptor descriptor : childEntities) {
    179                 filterEntities(descriptor);
    180             }
    181         }
    182     }
    183 }