/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/providers/trunk/jldap/src/java/edu/amc/sakai/user/RegexpBlacklistEidValidator.java $ * $Id: RegexpBlacklistEidValidator.java 105079 2012-02-24 23:08:11Z ottenhoff@longsight.com $ *********************************************************************************** * * Copyright (c) 2003, 2004, 2005, 2006, 2008 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package edu.amc.sakai.user; import java.util.Collection; import java.util.HashSet; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; /** * Implements <code>User</code> EID "validation" by checking * for matches in a configurable blacklist, entries in which * are treated as regular expressions. * * @author dmccallum * */ public class RegexpBlacklistEidValidator implements EidValidator { private Collection<Pattern> eidBlacklist; private int regexpFlags; /** * Requires minimally valid and non-blacklisted EIDs. This * is tested by calling {@link #isMinimallyValidEid(String)} * and {@link #isBlackListedEid(String)}. Theoretically, then, * a subclass could override {@link #isMinimallyValidEid(String)} * to, for example, allow any non-null EID but allow any * EID not described by the current blacklist. */ public boolean isSearchableEid(String eid) { return isMinimallyValidEid(eid) && !(isBlackListedEid(eid)); } /** * As implemented requires that the given ID be non-null * and non-whitespace. * * @param eid and EID to test * @return <code>true<code> unless the given String is * null or entirely whitespace */ protected boolean isMinimallyValidEid(String eid) { return StringUtils.isNotBlank(eid); } /** * Encapsulates the logic for actually checking a user EID * against the configured blacklist. If no blacklist is * configured, will return <code>false</code> * * @return <code>true</code> if the eid matches a configured * blacklist pattern. <code>false</code> otherwise (e.g. * if no configured blacklist). */ protected boolean isBlackListedEid(String eid) { if ( eidBlacklist == null || eidBlacklist.isEmpty() ) { return false; } for ( Pattern pattern : eidBlacklist ) { if ( pattern.matcher(eid).matches() ) { return true; } } return false; } /** * Access the String representation of blacklisted User EID * regexps configured on this object. The returned collection * may or may not be equivalent to the collection passed to * {@link #setEidBlacklist(Collection)} * * @return */ public Collection<String> getEidBlacklist() { return eidBlacklistAsStrings(); } private Collection<String> eidBlacklistAsStrings() { if ( eidBlacklist == null || eidBlacklist.isEmpty() ) { return new HashSet<String>(0); } HashSet<String> patternStrings = new HashSet<String>(eidBlacklist.size()); for ( Pattern pattern : eidBlacklist ) { patternStrings.add(pattern.pattern()); } return patternStrings; } /** * Converts the given collection of Strings into a collection * of {@Link Pattern}s and caches the latter for evaluation * by {@link #isSearchableEid(String)}. Configure {link Pattern} * evaluation flags with {@link #setRegexpFlags(int)}. * * @param eidBlacklist a collection of Strings to be compiled * into {@link Patterns}. May be <code>null</code>, which * will have the same semantics as an empty collection. */ public void setEidBlacklist(Collection<String> eidBlacklist) { this.eidBlacklist = eidBlacklistAsPatterns(eidBlacklist); } private Collection<Pattern> eidBlacklistAsPatterns( Collection<String> eidBlacklistStrings) { if ( eidBlacklistStrings == null || eidBlacklistStrings.isEmpty() ) { return new HashSet<Pattern>(0); } HashSet<Pattern> patterns = new HashSet<Pattern>(eidBlacklistStrings.size()); for ( String patternString : eidBlacklistStrings ) { Pattern pattern = Pattern.compile(patternString, regexpFlags); patterns.add(pattern); } return patterns; } /** * Access the configured set of {@link Pattern} matching * flags. Defaults to zero. * * @see Pattern#compile(String, int) * @return a bitmask of {@link Pattern} matching flags */ public int getRegexpFlags() { return regexpFlags; } /** * Assign a bitmask for {@link Pattern} matching behaviors. * Be sure to set this property prior to invoking * {@link #setEidBlacklist(Collection)}. The cached {@link Patterns} * will <code>not</code> be recompiled as a side-effect of * invoking this method. * * @param regexpFlags */ public void setRegexpFlags(int regexpFlags) { this.regexpFlags = regexpFlags; } }