b3103fb15fa36f2ff6dda01e2e9216028d31b345
[utils] / security / src / main / java / org / wamblee / security / authorization / UrlAuthorizationRule.java
1 /*
2  * Copyright 2005 the original author or authors.
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 package org.wamblee.security.authorization;
17
18 import org.apache.log4j.Logger;
19
20 import org.wamblee.persistence.AbstractPersistent;
21 import static org.wamblee.security.authorization.AuthorizationResult.DENIED;
22 import static org.wamblee.security.authorization.AuthorizationResult.GRANTED;
23 import static org.wamblee.security.authorization.AuthorizationResult.UNDECIDED;
24 import static org.wamblee.security.authorization.AuthorizationResult.UNSUPPORTED_RESOURCE;
25
26 import org.wamblee.usermgt.User;
27
28
29 /**
30  * Utility base class for implementation of authentication rules based on
31  * the
32  *  <ul>
33  *      <li>The path of the resource. To obtain the path of a resource,
34  *      subclasses must implement {@link #getResourcePath(Object)}.  Whether a
35  *      path is appropriate is determined by a  {@link
36  *      org.wamblee.security.authorization.PathCondition}.</li>
37  *      <li>The user identity with which the resource is accessed.
38  *      Whether a user is appropriate is determined by a {@link
39  *      org.wamblee.security.authorization.UserCondition}.</li>
40  *      <li>The operation that is requested.  Whether the operation is
41  *      appropriate is determined by a  {@link
42  *      org.wamblee.security.authorization.OperationCondition}.</li>
43  *  </ul>
44  *  In case all three conditions match, the condition returns the
45  * configured result passed at construction (GRANTED or DENIED). If the
46  * resource is not of the specified type, the result is UNSUPPORTED_RESOURCE,
47  * otherwise, the result is UNDECIDED.
48  */
49 public abstract class UrlAuthorizationRule extends AbstractPersistent
50     implements AuthorizationRule {
51     /**
52      * DOCUMENT ME!
53      */
54     private static final Logger LOGGER = Logger.getLogger(UrlAuthorizationRule.class);
55
56     /**
57      * Result that the rule will return in case there is a match.
58      */
59     private AuthorizationResult result;
60
61     /**
62      * A condition which specifies which users the rule is for.
63      */
64     private UserCondition userCondition;
65
66     /**
67      * Path the rule applies for.
68      */
69     private PathCondition pathCondition;
70
71     /**
72      * Resource class that the rule applies for.
73      */
74     private Class resourceClass;
75
76     /**
77      * Operation that this rule is for.
78      */
79     private OperationCondition operationCondition;
80
81 /**
82      * Constructs an authorization rule. 
83      * IF the group and path match, then the provided result will be returned. 
84      * @param aResult Result of the authorization when the path and group match. 
85      * @param aUserCondition Condition to match users.  
86      * @param aPathCondition Condition to match paths with.  
87      * @param aResourceClass Supported resource class this is for.
88      * @param aOperationCondition Condition to match the operation with.  
89      */
90     protected UrlAuthorizationRule(AuthorizationResult aResult,
91         UserCondition aUserCondition, PathCondition aPathCondition,
92         Class aResourceClass, OperationCondition aOperationCondition) {
93         if (!aResult.equals(GRANTED) && !aResult.equals(DENIED)) {
94             throw new IllegalArgumentException(
95                 "Only GRANTED or DENIED may be used: " + aResult);
96         }
97
98         result                 = aResult;
99         userCondition          = aUserCondition;
100         pathCondition          = aPathCondition;
101         resourceClass          = aResourceClass;
102         operationCondition     = aOperationCondition;
103     }
104
105 /**
106      * For OR mapping. 
107      *
108      */
109     protected UrlAuthorizationRule(Class aResourceClass) {
110         result                 = null;
111         userCondition          = null;
112         pathCondition          = null;
113         resourceClass          = aResourceClass;
114         operationCondition     = null;
115     }
116
117 /**
118      * For OR mapping. 
119      *
120      */
121     protected UrlAuthorizationRule() {
122         result                 = null;
123         userCondition          = null;
124         pathCondition          = null;
125         resourceClass          = null;
126         operationCondition     = null;
127     }
128
129     /*
130      * (non-Javadoc)
131      *
132      * @see org.wamblee.security.authorization.AuthorizationRule#getSupportedTypes()
133      */
134     /**
135      * DOCUMENT ME!
136      *
137      * @return DOCUMENT ME!
138      */
139     public Class[] getSupportedTypes() {
140         return new Class[] { resourceClass };
141     }
142
143     /*
144      * (non-Javadoc)
145      *
146      * @see org.wamblee.security.authorization.AuthorizationRule#isAllowed(java.lang.Object,
147      *      org.wamblee.security.authorization.Operation)
148      */
149     /**
150      * DOCUMENT ME!
151      *
152      * @param aResource DOCUMENT ME!
153      * @param anOperation DOCUMENT ME!
154      * @param aUser DOCUMENT ME!
155      *
156      * @return DOCUMENT ME!
157      */
158     public AuthorizationResult isAllowed(Object aResource,
159         Operation anOperation, User aUser) {
160         if (!resourceClass.isInstance(aResource)) {
161             return UNSUPPORTED_RESOURCE;
162         }
163
164         String path = getResourcePath(aResource);
165
166         return isAllowed(path, anOperation, aUser);
167     }
168
169     /**
170      * Determines if the operation is allowed on the resource.
171      *
172      * @param aPath Path of the resource.
173      * @param aOperation Operation to be done.
174      * @param aUser Currently logged in user or null if no user is logged in.
175      *
176      * @return Authorization result,
177      */
178     protected AuthorizationResult isAllowed(String aPath, Operation aOperation,
179         User aUser) {
180         if (!pathCondition.matches(aPath)) {
181             return UNDECIDED;
182         }
183
184         if (!operationCondition.matches(aOperation)) {
185             return UNDECIDED;
186         }
187
188         if (!userCondition.matches(aUser)) {
189             return UNDECIDED;
190         }
191
192         return result;
193     }
194
195     /**
196      * Gets the path of the resource.
197      *
198      * @param aResource Resource, guaranteed to be an instance of  {@link
199      *        #resourceClass}.
200      *
201      * @return Path of the resource.
202      */
203     protected abstract String getResourcePath(Object aResource);
204
205     /* (non-Javadoc)
206      * @see java.lang.Object#toString()
207      */
208     /**
209      * DOCUMENT ME!
210      *
211      * @return DOCUMENT ME!
212      */
213     @Override
214     public String toString() {
215         return "UrlAUthorizationRule(result = " + result + ", pathCondition = "
216         + pathCondition + ", userCondition = " + userCondition
217         + ", resourceClass = " + resourceClass + ")";
218     }
219
220     /**
221      * Gets the authorization result for OR mapping.
222      *
223      * @return Result.
224      */
225     protected String getAuthorizationResultString() {
226         if (result == null) {
227             return null;
228         }
229
230         return result.toString();
231     }
232
233     /**
234      * Sets the authorization result, for OR mapping.
235      *
236      * @param aResult Result.
237      */
238     protected void setAuthorizationResultString(String aResult) {
239         result = AuthorizationResult.valueOf(aResult);
240     }
241
242     /**
243      * DOCUMENT ME!
244      *
245      * @return DOCUMENT ME!
246      */
247     protected String getResourceClassName() {
248         if (resourceClass == null) {
249             return "";
250         }
251
252         return resourceClass.getName();
253     }
254
255     /**
256      * DOCUMENT ME!
257      *
258      * @param aResourceClass DOCUMENT ME!
259      *
260      * @throws IllegalArgumentException DOCUMENT ME!
261      */
262     protected void setResourceClassName(String aResourceClass) {
263         try {
264             resourceClass = Class.forName(aResourceClass);
265         } catch (ClassNotFoundException e) {
266             LOGGER.error("Cannot find resource class '" + aResourceClass + "'",
267                 e);
268             throw new IllegalArgumentException(e.getMessage(), e);
269         }
270     }
271
272     /**
273      * DOCUMENT ME!
274      *
275      * @return Returns the operationCondition.
276      */
277     public OperationCondition getOperationCondition() {
278         return operationCondition;
279     }
280
281     /**
282      * DOCUMENT ME!
283      *
284      * @param aOperationCondition The operationCondition to set.
285      */
286     protected void setOperationCondition(OperationCondition aOperationCondition) {
287         operationCondition = aOperationCondition;
288     }
289
290     /**
291      * DOCUMENT ME!
292      *
293      * @return Returns the pathCondition.
294      */
295     public PathCondition getPathCondition() {
296         return pathCondition;
297     }
298
299     /**
300      * DOCUMENT ME!
301      *
302      * @param aPathCondition The pathCondition to set.
303      */
304     protected void setPathCondition(PathCondition aPathCondition) {
305         pathCondition = aPathCondition;
306     }
307
308     /**
309      * DOCUMENT ME!
310      *
311      * @return Returns the userCondition.
312      */
313     public UserCondition getUserCondition() {
314         return userCondition;
315     }
316
317     /**
318      * DOCUMENT ME!
319      *
320      * @param aUserCondition The userCondition to set.
321      */
322     protected void setUserCondition(UserCondition aUserCondition) {
323         userCondition = aUserCondition;
324     }
325 }