all session items are now serializable
authormaxcooper <maxcooper>
Wed, 14 Aug 2002 13:13:23 +0000 (13:13 +0000)
committermaxcooper <maxcooper>
Wed, 14 Aug 2002 13:13:23 +0000 (13:13 +0000)
implemented spec-compliant url-pattern ordering

src/share/org/securityfilter/filter/MatchableURLPattern.java
src/share/org/securityfilter/filter/SavedRequest.java
src/share/org/securityfilter/filter/SecurityFilter.java
src/share/org/securityfilter/realm/SimplePrincipal.java [new file with mode: 0644]
src/share/org/securityfilter/realm/SimpleSecurityRealmBase.java

index 0f01268..a577ad3 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/filter/Attic/MatchableURLPattern.java,v 1.3 2002/08/12 01:34:28 maxcooper Exp $
- * $Revision: 1.3 $
- * $Date: 2002/08/12 01:34:28 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/filter/Attic/MatchableURLPattern.java,v 1.4 2002/08/14 13:13:23 maxcooper Exp $
+ * $Revision: 1.4 $
+ * $Date: 2002/08/14 13:13:23 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -69,7 +69,7 @@ import java.util.Collection;
  * by the order field).
  *
  * @author Max Cooper (max@maxcooper.com)
- * @version $Revision: 1.3 $ $Date: 2002/08/12 01:34:28 $
+ * @version $Revision: 1.4 $ $Date: 2002/08/14 13:13:23 $
  */
 public class MatchableURLPattern implements Comparable {
    private String pattern;
@@ -77,6 +77,8 @@ public class MatchableURLPattern implements Comparable {
    private SecurityConstraint constraint;
    private WebResourceCollection resourceCollection;
    private int order;
+   private int patternType;
+   private int pathLength;
 
    /**
     * Construct a new MatchableURLPattern object.
@@ -100,7 +102,7 @@ public class MatchableURLPattern implements Comparable {
       this.constraint = constraint;
       this.resourceCollection = resourceCollection;
       this.order = order;
-      this.patternRE = new RE(compiler.compile(getConvertedPattern()));
+      init(compiler);
    }
 
    /**
@@ -121,6 +123,28 @@ public class MatchableURLPattern implements Comparable {
    }
 
    /**
+    * Pattern type for patterns that do not meet the PATH or EXTENSION pattern type specifications.
+    */
+   public static final int EXACT = 1;
+   /**
+    * Pattern type for PATH mappings. Starts with '/' and ends with '/*'.
+    */
+   public static final int PATH = 2;
+   /**
+    * Pattern type for PATH mappings
+    */
+   public static final int EXTENSION = 3;
+
+   /**
+    * Get the pattern type. The pattern type will be determined on the first call to this method.
+    *
+    * @return EXACT, PATH, or EXTENSION
+    */
+   public int getPatternType() {
+      return patternType;
+   }
+
+   /**
     * Get the url pattern to match.
     */
    public String getPattern() {
@@ -169,24 +193,93 @@ public class MatchableURLPattern implements Comparable {
    }
 
    /**
-    * Compares this MatchableURLPattern to another to support sorting.
-    * Ordering is currently implemented according to the order field value, which can exhibit behavior inconsistent
-    * with equals() if non-equivalent instances have the same order value.
+    * Compares this MatchableURLPattern to another to support sorting.<p>
     *
-    * TO-DO: Update to support servlet spec compliant ordering.
+    * The sort order is dictated by the servlet spec. EXACT patterns are first, followed by PATH patterns,
+    * followed by EXTENTION patterns. Ordering among PATH patterns is determined by path length, with the
+    * longer path coming first. If the path lengths are the same, or both are EXACT or EXTENSION patterns,
+    * ordering is determined by the order in which the pattern appeared in the config file.
     *
-    * @param o object to compare to
+    * @param another another MatchableURLPattern to compare to
+    *
+    * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater
+    * than the specified object.
     *
     * @exception ClassCastException thrown if o is not a MatchableURLPattern instance
     */
-   public int compareTo(Object o) throws ClassCastException {
-      MatchableURLPattern otherPattern = (MatchableURLPattern) o;
+   public int compareTo(Object another) throws ClassCastException {
+      MatchableURLPattern otherPattern = (MatchableURLPattern) another;
+      // if the patterns are equivalent, ordering priority is equal
       if (this.equals(otherPattern)) {
          return 0;
       } else {
-         // TO-DO: update to reflect servlet spec pattern order
-         return (getOrder() - otherPattern.getOrder());
+         int otherPatternType = otherPattern.getPatternType();
+         // if the pattern types are the same
+         if (patternType == otherPatternType) {
+            // if the type is PATH
+            if (patternType == MatchableURLPattern.PATH) {
+               int otherPathLength = otherPattern.getPathLength();
+               // if path lengths are different, the pattern with longer path length should be first
+               if (pathLength != otherPathLength) {
+                  return (otherPathLength - pathLength);
+               // path length are the same, the pattern with the smaller order should be first
+               } else {
+                  return (order - otherPattern.getOrder());
+               }
+            // for EXACT or EXTENSION, the pattern with the smaller order should be first
+            } else {
+               return (order - otherPattern.getOrder());
+            }
+         } else {
+            // pattern types are not the same, order should be EXACT, PATH, EXTENSION
+            return (patternType - otherPatternType);
+         }
+      }
+   }
+
+   /**
+    * Get the path length of the pattern. This is only valid when getPatternType() = PATH.<p>
+    * Examples:
+    * <ul>
+    *    <li>/* = 0</li>
+    *    <li>/path/* = 1</li>
+    *    <li>/really/long/path/* = 3</li>
+    * </ul>
+    *
+    * @return path length of this pattern
+    */
+   public int getPathLength() {
+      return pathLength;
+   }
+
+   /**
+    * Initialize pattern-related internal variables.
+    *
+    * @param compiler an RECompiler
+    *
+    * @exception RESyntaxException
+    */
+   private void init(RECompiler compiler) throws RESyntaxException {
+      // calculate the path length
+      pathLength = -1;
+      int pos = pattern.indexOf('/');
+      while (pos != -1) {
+         pathLength++;
+         pos = pattern.indexOf('/', pos + 1);
+      }
+      // determine the pattern type
+      if (pattern.startsWith("*.")) {
+         patternType = MatchableURLPattern.EXTENSION;
+      } else if (pattern.startsWith("/") && pattern.endsWith("/*")) {
+         patternType = MatchableURLPattern.PATH;
+      } else {
+         patternType = MatchableURLPattern.EXACT;
+      }
+      // initilize the patternRE
+      if (compiler == null) {
+         compiler = new RECompiler();
       }
+      patternRE = new RE(compiler.compile(getConvertedPattern()));
    }
 
    /**
index f88089f..07acc7f 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/filter/SavedRequest.java,v 1.1 2002/08/12 01:34:28 maxcooper Exp $
- * $Revision: 1.1 $
- * $Date: 2002/08/12 01:34:28 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/filter/SavedRequest.java,v 1.2 2002/08/14 13:13:23 maxcooper Exp $
+ * $Revision: 1.2 $
+ * $Date: 2002/08/14 13:13:23 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
 package org.securityfilter.filter;
 
 import javax.servlet.http.HttpServletRequest;
+import java.io.Serializable;
 import java.util.Map;
 
 /**
- * SavedRequest
+ * SavedRequest represents a request that initiated an authorization sequence.
+ * It saves the parameterMap and (HTTP) Method of the original request to be used after the user is authenticated
+ * and the original request information is needed for processing.
  *
  * @author Max Cooper (max@maxcooper.com)
  */
-public class SavedRequest {
+public class SavedRequest implements Serializable {
    private Map parameterMap;
    private String method;
 
index e7369b0..2817f6f 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/filter/SecurityFilter.java,v 1.4 2002/08/12 02:08:54 maxcooper Exp $
- * $Revision: 1.4 $
- * $Date: 2002/08/12 02:08:54 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/filter/SecurityFilter.java,v 1.5 2002/08/14 13:13:23 maxcooper Exp $
+ * $Revision: 1.5 $
+ * $Date: 2002/08/14 13:13:23 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -78,7 +78,7 @@ import java.util.*;
  *
  * @author Max Cooper (max@maxcooper.com)
  * @author Torgeir Veimo (torgeir@pobox.com)
- * @version $Revision: 1.4 $ $Date: 2002/08/12 02:08:54 $
+ * @version $Revision: 1.5 $ $Date: 2002/08/14 13:13:23 $
  */
 public class SecurityFilter implements Filter {
    public static final String SAVED_REQUEST_URL = SecurityFilter.class.getName() + ".SAVED_REQUEST_URL";
@@ -231,6 +231,11 @@ public class SecurityFilter implements Filter {
             }
          }
          Collections.sort(patternList);
+         //System.out.println("Sorted pattern list:");
+         //for (Iterator i = patternList.iterator(); i.hasNext(); ) {
+         //   MatchableURLPattern pattern = (MatchableURLPattern) i.next();
+         //   System.out.println(pattern.getPattern());
+         //}
 
       } catch (RESyntaxException rese) {
          System.err.println("invalid regular expression pattern: " + rese);
diff --git a/src/share/org/securityfilter/realm/SimplePrincipal.java b/src/share/org/securityfilter/realm/SimplePrincipal.java
new file mode 100644 (file)
index 0000000..c781b81
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/realm/SimplePrincipal.java,v 1.1 2002/08/14 13:13:56 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/14 13:13:56 $
+ *
+ * ====================================================================
+ * The SecurityFilter Software License, Version 1.1
+ *
+ * (this license is derived and fully compatible with the Apache Software
+ * License - see http://www.apache.org/LICENSE.txt)
+ *
+ * Copyright (c) 2002 SecurityFilter.org. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by
+ *        SecurityFilter.org (http://www.securityfilter.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "SecurityFilter" must not be used to endorse or promote
+ *    products derived from this software without prior written permission.
+ *    For written permission, please contact license@securityfilter.org .
+ *
+ * 5. Products derived from this software may not be called "SecurityFilter",
+ *    nor may "SecurityFilter" appear in their name, without prior written
+ *    permission of SecurityFilter.org.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ */
+
+package org.securityfilter.realm;
+
+import java.io.Serializable;
+import java.security.Principal;
+
+/**
+ * SimplePrincipal - a simple, serializable Principal.
+ *
+ * @author Max Cooper (max@maxcooper.com)
+ */
+public class SimplePrincipal implements Principal, Serializable {
+
+   private String name;
+
+   /**
+    * Default constructor is private. Use SimplePrincipal(String name) constructor.
+    */
+   private SimplePrincipal() {
+   }
+
+   /**
+    * Constructor
+    */
+   public SimplePrincipal(String name) {
+      this.name = name;
+   }
+
+   /**
+    * Returns the name of this principal.
+    *
+    * @return the name of this principal.
+    */
+   public String getName() {
+      return name;
+   }
+
+   /**
+    * Compares this principal to the specified object.
+    *
+    * @param obj object to compare with.
+    *
+    * @return true if the object passed in is a SimplePrincipal with the same name.
+    */
+   public boolean equals(Object obj) {
+      if (obj instanceof SimplePrincipal) {
+         return name.equals(((SimplePrincipal)obj).getName());
+      }
+      return false;
+   }
+
+   /**
+    * Returns a string representation of this principal.
+    *
+    * @return a string representation of this principal.
+    */
+   public String toString() {
+      return "SimplePrincipal[name = \'" + name + "\']";
+   }
+
+   /**
+    * Returns a hashcode for this principal.
+    *
+    * @return a hashcode for this principal.
+    */
+   public int hashCode() {
+      return name.hashCode();
+   }
+}
+
+// ----------------------------------------------------------------------------
+// EOF
\ No newline at end of file
index 9032951..3d14929 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/realm/SimpleSecurityRealmBase.java,v 1.1 2002/08/14 11:26:31 maxcooper Exp $
- * $Revision: 1.1 $
- * $Date: 2002/08/14 11:26:31 $
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/realm/SimpleSecurityRealmBase.java,v 1.2 2002/08/14 13:13:56 maxcooper Exp $
+ * $Revision: 1.2 $
+ * $Date: 2002/08/14 13:13:56 $
  *
  * ====================================================================
  * The SecurityFilter Software License, Version 1.1
@@ -56,6 +56,7 @@
 package org.securityfilter.realm;
 
 import java.security.Principal;
+import java.io.Serializable;
 
 /**
  * Security realm base class. This class insulates you from having to create or process Principal
@@ -102,13 +103,9 @@ public class SimpleSecurityRealmBase implements SecurityRealmInterface {
     *
     * @return a Principal object representing the user if successful, false otherwise
     */
-   public Principal authenticate(final String username, String password) {
+   public Principal authenticate(String username, String password) {
       if (booleanAuthenticate(username, password)) {
-         return new Principal() {
-            public String getName() {
-               return username;
-            }
-         };
+         return new SimplePrincipal(username);
       } else {
          return null;
       }