KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > security > jacc > WebUserDataPermission


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package javax.security.jacc;
25
26 import java.util.HashMap JavaDoc;
27
28 import java.io.IOException JavaDoc;
29 import java.io.ObjectStreamField JavaDoc;
30
31 import java.security.*;
32 import javax.security.jacc.URLPatternSpec JavaDoc;
33 import javax.security.jacc.HttpMethodSpec JavaDoc;
34
35 import javax.servlet.http.HttpServletRequest JavaDoc;
36
37 /**
38  * Class for Servlet Web user data permissions.
39  * A WebUserDataPermission is a named permission and has actions.
40  * <P>
41  * The name of a WebUserDataPermission (also referred to as the target name)
42  * identifies a Web resource by its context path relative URL pattern.
43  *
44  * @see java.security.Permission
45  *
46  * @author Ron Monzillo
47  * @author Gary Ellison
48  *
49  */

50
51 public final class WebUserDataPermission extends Permission
52 implements java.io.Serializable JavaDoc
53 {
54
55      private static String JavaDoc transportKeys[] = {
56      "NONE",
57      "INTEGRAL",
58      "CONFIDENTIAL",
59      };
60
61      private static HashMap JavaDoc transportHash = new HashMap JavaDoc();
62      static {
63      for (int i=0; i<transportKeys.length; i++)
64          transportHash.put(transportKeys[i], new Integer JavaDoc(i));
65      };
66
67      private static int TT_NONE =
68          ((Integer JavaDoc) transportHash.get("NONE")).intValue();
69      private static int TT_CONFIDENTIAL =
70          ((Integer JavaDoc) transportHash.get("CONFIDENTIAL")).intValue();
71   
72      private transient URLPatternSpec JavaDoc urlPatternSpec = null;
73
74      private transient HttpMethodSpec JavaDoc methodSpec;
75
76      private transient int transportType;
77
78      private transient int hashCodeValue = 0;
79
80      private transient static final String JavaDoc EMPTY_STRING = "";
81
82      private static final long serialVersionUID = 1L;
83
84     /**
85      * The serialized fields of this permission are defined below. Whether
86      * or not the serialized fields correspond to actual (private) fields
87      * is an implementation decision.
88      * @serialField actions String
89      * the canonicalized actions string (as returned by getActions).
90      */

91      private static final ObjectStreamField JavaDoc[] serialPersistentFields = {
92      new ObjectStreamField JavaDoc("actions", java.lang.String JavaDoc.class)
93      };
94
95     /**
96      * Creates a new WebUserDataPermission with the specified name and actions.
97      * <P>
98      * The name contains a URLPatternSpec that identifies the web
99      * resources to which the permissions applies. The syntax of a URLPatternSpec
100      * is as follows:
101      * <P><Pre>
102      *
103      * URLPatternList ::= URLPattern | URLPatternList colon URLPattern
104      *
105      * URLPatternSpec ::= null | URLPattern | URLPattern colon URLPatternList
106      *
107      * </Pre><P>
108      * A null URLPatternSpec is translated to the default URLPattern, "/", by
109      * the permission constructor. The empty string is an exact URLPattern, and
110      * may occur anywhere in a URLPatternSpec that an exact URLPattern may occur.
111      * The first URLPattern in a URLPatternSpec may be any of the pattern
112      * types, exact, path-prefix, extension, or default as defined in the
113      * <i>Java Servlet Specification)</i>. When a URLPatternSpec includes
114      * a URLPatternList, the patterns of the URLPatternList identify the
115      * resources to which the permission does NOT apply and depend on the
116      * pattern type and value of the first pattern as follows: <p>
117      * <ul>
118      * <li> No pattern may exist in the URLPatternList that matches the
119      * first pattern.
120      * <li> If the first pattern is a path-prefix
121      * pattern, only exact patterns matched by the first pattern
122      * and path-prefix patterns matched by, but different from,
123      * the first pattern may occur in the URLPatternList.
124      * <li> If the first pattern is an extension
125      * pattern, only exact patterns that are matched by the first
126      * pattern and path-prefix patterns may occur in the URLPatternList.
127      * <li> If the first pattern is the default pattern, "/", any pattern
128      * except the default pattern may occur in the URLPatternList.
129      * <li> If the first pattern is an exact pattern a URLPatternList must not
130      * be present in the URLPatternSpec.
131      * </ul>
132      * <P>
133      * The actions parameter contains a comma separated list of HTTP methods
134      * that may be followed by a transportType separated from the HTTP
135      * method by a colon.
136      * <P><Pre>
137      *
138      * ExtensionMethod ::= any token as defined by RFC 2616
139      * (that is, 1*[any CHAR except CTLs or separators])
140      *
141      * HTTPMethod ::= "Get" | "POST" | "PUT" | "DELETE" | "HEAD" |
142      * "OPTIONS" | "TRACE" | ExtensionMethod
143      *
144      * HTTPMethodList ::= HTTPMethod | HTTPMethodList comma HTTPMethod
145      *
146      * HTTPMethodExceptionList ::= exclaimationPoint HTTPMethodList
147      *
148      * HTTPMethodSpec ::= emptyString | HTTPMethodExceptionList |
149      * HTTPMethodList
150      *
151      * transportType ::= "INTEGRAL" | "CONFIDENTIAL" | "NONE"
152      *
153      * actions ::= null | HTTPMethodSpec |
154      * HTTPMethodSpec colon transportType
155      *
156      * </Pre><P>
157      * If duplicates occur in the HTTPMethodSpec
158      * they must be eliminated by the permission constructor.
159      * <P>
160      * An empty string HTTPMethodSpec is a shorthand for a List
161      * containing all the possible HTTP methods.
162      * <P>
163      * If the HTTPMethodSpec contains an HTTPMethodExceptionList (i.e.,
164      * it begins with an exclaimationPoint), the permission pertains
165      * to all methods except those occuring in the exception list.
166      * <P>
167      * An actions string without a transportType is a shorthand for a
168      * actions string with the value "NONE" as its TransportType.
169      * <P>
170      * A granted permission representing a transportType of "NONE",
171      * indicates that the associated resources may be accessed
172      * using any conection type.
173      * <P>
174      * @param name the URLPatternSpec that identifies the application
175      * specific web resources to which the permission pertains.
176      * All URLPatterns in the URLPatternSpec are relative to the context path
177      * of the deployed web application module, and the same URLPattern must not
178      * occur more than once in a URLPatternSpec. A null URLPatternSpec is
179      * translated to the default URLPattern, "/", by the permission constructor.
180      * <P>
181      * @param actions identifies the HTTP methods and transport type to which
182      * the permission pertains. If the value passed through this
183      * parameter is null or the empty string, then the permission
184      * is constructed with actions corresponding to all the possible
185      * HTTP methods and transportType "NONE".
186      */

187
188      public WebUserDataPermission(String JavaDoc name, String JavaDoc actions)
189      {
190         super(name);
191     this.urlPatternSpec = new URLPatternSpec JavaDoc(name);
192     parseActions(actions);
193      }
194
195     /**
196      * Creates a new WebUserDataPermission with name corresponding to the
197      * URLPatternSpec, and actions composed from the array of HTTP methods
198      * and the transport type.
199      * <P>
200      * @param urlPatternSpec the URLPatternSpec that identifies the
201      * application specific web resources to which the permission pertains.
202      * All URLPatterns in the URLPatternSpec are relative to the context path
203      * of the deployed web application module, and the same URLPattern must not
204      * occur more than once in a URLPatternSpec. A null URLPatternSpec is
205      * translated to the default URLPattern, "/", by the permission constructor.
206      * <P>
207      * @param HTTPMethods an array of strings each element of which contains
208      * the value of an HTTP method. If the value passed through this
209      * parameter is null or is an array with no elements, then the permission
210      * is constructed with actions corresponding to all the possible HTTP methods.
211      * <P>
212      * @param transportType a String whose value is a transportType.
213      * If the value passed through this parameter is null, then the permission
214      * is constructed with actions corresponding to transportType "NONE".
215      */

216
217      public WebUserDataPermission(String JavaDoc urlPatternSpec, String JavaDoc[] HTTPMethods,
218                   String JavaDoc transportType)
219      {
220     super(urlPatternSpec);
221     this.urlPatternSpec = new URLPatternSpec JavaDoc(urlPatternSpec);
222
223     this.transportType = TT_NONE;
224
225     if (transportType != null) {
226         Integer JavaDoc bit = (Integer JavaDoc) transportHash.get(transportType);
227         if (bit == null)
228         throw new IllegalArgumentException JavaDoc("illegal transport value");
229         this.transportType = bit.intValue();
230     }
231
232     this.methodSpec = HttpMethodSpec.getSpec(HTTPMethods);
233      }
234
235     /**
236      * Creates a new WebUserDataPermission from the HttpServletRequest
237      * object.
238      * <P>
239      * @param request the HttpServletRequest object corresponding
240      * to the Servlet operation to which the permission pertains.
241      * The permission name is the substring of the requestURI
242      * (HttpServletRequest.getRequestURI()) that begins after the contextPath
243      * (HttpServletRequest.getContextPath()). When the substring operation
244      * yields the string "/", the permission is constructed with the empty
245      * string as its name. The HTTP method component of the permission's
246      * actions is as obtained from HttpServletRequest.getMethod().
247      * The TransportType component of the permission's
248      * actions is determined by calling HttpServletRequest.isSecure().
249      */

250
251      public WebUserDataPermission(HttpServletRequest JavaDoc request)
252      {
253     super(getUriMinusContextPath(request));
254     this.urlPatternSpec = new URLPatternSpec JavaDoc(super.getName());
255     this.transportType = request.isSecure() ? TT_CONFIDENTIAL : TT_NONE;
256     this.methodSpec = HttpMethodSpec.getSpec(request.getMethod());
257      }
258
259     /**
260      * Checks two WebUserDataPermission objects for equality.
261      * WebUserDataPermission objects are equivalent if their
262      * URLPatternSpec and (canonicalized) actions values are equivalent.
263      * The URLPatternSpec of a reference permission is equivalent to that
264      * of an argument permission if their first patterns are
265      * equivalent, and the patterns of the URLPatternList of the reference
266      * permission collectively match exactly the same set of patterns
267      * as are matched by the patterns of the URLPatternList of the
268      * argument permission.
269      * <P>
270      * Two Permission objects, P1 and P2, are equivalent if and only if
271      * P1.implies(P2) && P2.implies(P1).
272      * <P>
273      * @param o the WebUserDataPermission object being tested for equality
274      * with this WebUserDataPermission.
275      * <P>
276      * @return true if the argument WebUserDataPermission object is equivalent
277      * to this WebUserDataPermission.
278      */

279
280     public boolean equals(Object JavaDoc o) {
281     if (o == null || ! (o instanceof WebUserDataPermission JavaDoc)) return false;
282
283     WebUserDataPermission JavaDoc that = (WebUserDataPermission JavaDoc) o;
284
285     if (this.transportType != that.transportType) return false;
286
287     if (!this.methodSpec.equals(that.methodSpec)) return false;
288
289     return this.urlPatternSpec.equals(that.urlPatternSpec);
290     }
291
292    /**
293     * Returns a canonical String representation of the actions of this
294     * WebUserDataPermission. The canonical form of the actions of a
295     * WebUserDataPermission is described by the following syntax description.
296     * <P><Pre>
297     *
298     * ExtensionMethod ::= any token as defined by RFC 2616
299     * (that is, 1*[any CHAR except CTLs or separators])
300     *
301     * HTTPMethod ::= "GET" | "POST" | "PUT" | "DELETE" | "HEAD" |
302     * "OPTIONS" | "TRACE" | ExtensionMethod
303     *
304     * HTTPMethodList ::= HTTPMethod | HTTPMethodList comma HTTPMethod
305     *
306     * HTTPMethodExceptionList ::= exclaimationPoint HTTPMethodList
307     *
308     * HTTPMethodSpec ::= emptyString | HTTPMethodExceptionList |
309     * HTTPMethodList
310     *
311     * transportType ::= "INTEGRAL" | "CONFIDENTIAL" | "NONE"
312     *
313     * actions ::= null | HTTPMethodList |
314     * HTTPMethodSpec colon transportType
315     *
316     * </Pre><P>
317     * If the permission's HTTP methods correspond to the entire HTTP method
318     * set and the permission's transport type is "INTEGRAL" or "CONFIDENTIAL",
319     * the HTTP methods shall be represented in the canonical form by an
320     * emptyString HTTPMethodSpec. If the permission's HTTP methods correspond
321     * to the entire HTTP method set, and the permission's transport type is not
322     * "INTEGRAL"or "CONFIDENTIAL", the canonical actions value shall be the
323     * null value.
324     *<P>
325     * If the permission's methods do not correspond to the entire HTTP
326     * method set, duplicates must be eliminated and the remaining elements
327     * must be ordered such that the predefined methods preceed the extension
328     * methods, and such that within each method classification the corresponding
329     * methods occur in ascending lexical order.
330     * The resulting (non-emptyString) HTTPMethodSpec
331     * must be included in the canonical form, and if the permission's
332     * transport type is not "INTEGRAL" or "CONFIDENTIAL", the canonical
333     * actions value must be exactly the resulting HTTPMethodSpec.
334     * <P>
335     * @return a String containing the canonicalized actions of this
336     * WebUserDataPermission (or the null value).
337     */

338
339     public String JavaDoc getActions()
340     {
341     String JavaDoc result;
342     String JavaDoc hActions = this.methodSpec.getActions();
343     if (this.transportType == TT_NONE && hActions == null) result = null;
344     else if (this.transportType == TT_NONE) result = hActions;
345     else if (hActions == null)
346         result = ":" + transportKeys[this.transportType];
347     else result = hActions + ":" + transportKeys[this.transportType];
348     return result;
349     }
350
351    /**
352     * Returns the hash code value for this WebUserDataPermission. The
353     * properties of the returned hash code must be as follows: <p>
354     * <ul>
355     * <li> During the lifetime of a Java application, the hashCode method
356     * shall return the same integer value every time it is called on a
357     * WebUserDataPermission object. The value returned by hashCode for a
358     * particular EJBMethod permission need not remain consistent from
359     * one execution of an application to another.
360     * <li> If two WebUserDataPermission objects are equal according to the
361     * equals method, then calling the hashCode method on each of the two
362     * Permission objects must produce the same integer result (within an
363     * application).
364     * </ul>
365     * <P>
366     * @return the integer hash code value for this object.
367     */

368
369     public int hashCode() {
370     if (this.hashCodeValue == 0) {
371         String JavaDoc hashInput = new String JavaDoc(this.urlPatternSpec.toString() +
372                       " " + this.methodSpec.hashCode() +
373                                           ":" + this.transportType);
374
375         this.hashCodeValue = hashInput.hashCode();
376     }
377     return this.hashCodeValue;
378     }
379
380     /**
381      * Determines if the argument Permission is "implied by" this
382      * WebUserDataPermission. For this to be the case all of the following
383      * must be true:<p>
384      * <ul>
385      * <li> The argument is an instanceof WebUserDataPermission.
386      * <li> The first URLPattern in the name of the argument permission
387      * is matched by the first URLPattern in the name of this permission.
388      * <li> The first URLPattern in the name of the argument permission
389      * is NOT matched by any URLPattern in the URLPatternList of the
390      * URLPatternSpec of this permission.
391      * <li> If the first URLPattern in the name of the argument permission
392      * matches the first URLPattern in the URLPatternSpec of this
393      * permission, then every URLPattern in the URLPatternList of the
394      * URLPatternSpec of this permission is matched by a URLPattern
395      * in the URLPatternList of the argument permission.
396      * <li> The HTTP methods represented by the actions of the argument
397      * permission are a subset of the HTTP methods represented by the
398      * actions of this permission.
399      * <li> The transportType in the actions of this permission
400      * either corresponds to the value "NONE", or equals the
401      * transportType in the actions of the argument permission.
402      * </ul>
403      * <P>
404      * URLPattern matching is performed using the <i>Servlet matching
405      * rules</i> where two URL patterns match if they are related as follows:
406      * <p><ul>
407      * <li> their pattern values are String equivalent, or
408      * <li> this pattern is the path-prefix pattern "/*", or
409      * <li> this pattern is a path-prefix pattern (that is, it starts with
410      * "/" and ends with "/*") and the argument pattern starts with the
411      * substring of this pattern, minus its last 2 characters, and the
412      * next character of the argument pattern, if there is one, is "/", or
413      * <li> this pattern is an extension pattern (that is, it starts with
414      * "*.") and the argument pattern ends with this pattern, or
415      * <li> the reference pattern is the special default pattern, "/",
416      * which matches all argument patterns.
417      * </ul>
418      * <P>
419      * All of the comparisons described above are case sensitive.
420      * <P>
421      * @param permission "this" WebUserDataPermission is checked to see if
422      * it implies the argument permission.
423      * <P>
424      * @return true if the specified permission is implied by this object,
425      * false if not.
426      */

427
428     public boolean implies(Permission permission) {
429     if (permission == null ||
430         ! (permission instanceof WebUserDataPermission JavaDoc)) return false;
431
432     WebUserDataPermission JavaDoc that = (WebUserDataPermission JavaDoc) permission;
433
434     if (this.transportType != TT_NONE &&
435         this.transportType != that.transportType) return false;
436
437     if (!this.methodSpec.implies(that.methodSpec)) return false;
438
439     return this.urlPatternSpec.implies(that.urlPatternSpec);
440     }
441
442     // ----------------- Private Methods ---------------------
443

444     /**
445      * Chops the ContextPath off the front of the requestURI to
446      * yield the servletPath + PathInfo. For the special case where
447      * the servletPath + PathInfo is the pattern, "/", this
448      * routine returns the empty string.
449      */

450     private static String JavaDoc getUriMinusContextPath(HttpServletRequest JavaDoc request) {
451     String JavaDoc uri = request.getRequestURI();
452     if (uri != null) {
453         String JavaDoc contextPath = request.getContextPath();
454         int contextLength = contextPath == null ? 0 : contextPath.length();
455         if (contextLength > 0) {
456         uri = uri.substring(contextLength);
457         }
458         if (uri.equals("/")) {
459         uri = EMPTY_STRING;
460         }
461     } else {
462         uri = EMPTY_STRING;
463     }
464     return uri;
465     }
466
467     private void parseActions(String JavaDoc actions)
468     {
469     this.transportType = TT_NONE;
470  
471     if (actions == null || actions.equals("")) {
472          this.methodSpec = HttpMethodSpec.getSpec((String JavaDoc) null);
473         } else {
474         int colon = actions.indexOf(':');
475         if (colon < 0) {
476         this.methodSpec = HttpMethodSpec.getSpec(actions);
477         } else {
478         if (colon == 0) {
479             this.methodSpec = HttpMethodSpec.getSpec((String JavaDoc) null);
480         } else {
481             this.methodSpec = HttpMethodSpec.getSpec
482                        (actions.substring(0,colon));
483         }
484         Integer JavaDoc bit = (Integer JavaDoc)
485             transportHash.get(actions.substring(colon+1));
486         if (bit == null)
487             throw new IllegalArgumentException JavaDoc
488             ("illegal transport value");
489       
490         this.transportType = bit.intValue();
491         }
492     }
493     }
494
495    /**
496      * readObject reads the serialized fields from the
497      * input stream and uses them to restore the permission.
498      * This method need not be implemented if establishing the
499      * values of the serialized fields (as is done by defaultReadObject)
500      * is sufficient to initialize the permission.
501      */

502     private synchronized void readObject(java.io.ObjectInputStream JavaDoc s)
503          throws IOException JavaDoc,ClassNotFoundException JavaDoc
504     {
505     parseActions((String JavaDoc) s.readFields().get("actions",null));
506     this.urlPatternSpec = new URLPatternSpec JavaDoc(super.getName());
507     }
508
509     /**
510      * writeObject is used to establish the values of the serialized fields
511      * before they are written to the output stream and need not be
512      * implemented if the values of the serialized fields are always
513      * available and up to date. The serialized fields are written to
514      * the output stream in the same form as they would be written
515      * by defaultWriteObject.
516      */

517     private synchronized void writeObject(java.io.ObjectOutputStream JavaDoc s)
518          throws IOException JavaDoc
519     {
520     s.putFields().put("actions",this.getActions());
521     s.writeFields();
522     }
523
524 }
525
526
527
528
529
530
531
532
Popular Tags