2 * Copyright 2005-2010 the original author or authors.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.wamblee.security.authorization;
18 import static org.wamblee.security.authorization.AuthorizationResult.*;
20 import javax.persistence.Access;
21 import javax.persistence.AccessType;
22 import javax.persistence.CascadeType;
23 import javax.persistence.Column;
24 import javax.persistence.Entity;
25 import javax.persistence.JoinColumn;
26 import javax.persistence.ManyToOne;
27 import javax.persistence.Transient;
29 import org.apache.log4j.Logger;
30 import org.wamblee.usermgt.User;
33 * Utility base class for implementation of authentication rules based on the
35 * <li>The path of the resource. To obtain the path of a resource, subclasses
36 * must implement {@link #getResourcePath(Object)}. Whether a path is
37 * appropriate is determined by a
38 * {@link org.wamblee.security.authorization.PathCondition}.</li>
39 * <li>The user identity with which the resource is accessed. Whether a user is
40 * appropriate is determined by a
41 * {@link org.wamblee.security.authorization.UserCondition}.</li>
42 * <li>The operation that is requested. Whether the operation is appropriate is
43 * determined by a {@link org.wamblee.security.authorization.OperationCondition}
46 * In case all three conditions match, the condition returns the configured
47 * result passed at construction (GRANTED or DENIED). If the resource is not of
48 * the specified type, the result is UNSUPPORTED_RESOURCE, otherwise, the result
52 @Access(AccessType.PROPERTY)
53 public abstract class UrlAuthorizationRule extends AuthorizationRule {
54 private static final Logger LOGGER = Logger
55 .getLogger(UrlAuthorizationRule.class);
58 * Result that the rule will return in case there is a match.
60 private AuthorizationResult result;
63 * A condition which specifies which users the rule is for.
65 private UserCondition userCondition;
68 * Path the rule applies for.
70 private PathCondition pathCondition;
73 * Resource class that the rule applies for.
75 private Class resourceClass;
78 * Operation that this rule is for.
80 private OperationCondition operationCondition;
83 * Constructs an authorization rule. IF the group and path match, then the
84 * provided result will be returned.
87 * Result of the authorization when the path and group match.
88 * @param aUserCondition
89 * Condition to match users.
90 * @param aPathCondition
91 * Condition to match paths with.
92 * @param aResourceClass
93 * Supported resource class this is for.
94 * @param aOperationCondition
95 * Condition to match the operation with.
97 protected UrlAuthorizationRule(AuthorizationResult aResult,
98 UserCondition aUserCondition, PathCondition aPathCondition,
99 Class aResourceClass, OperationCondition aOperationCondition) {
100 if (!aResult.equals(GRANTED) && !aResult.equals(DENIED)) {
101 throw new IllegalArgumentException(
102 "Only GRANTED or DENIED may be used: " + aResult);
106 userCondition = aUserCondition;
107 pathCondition = aPathCondition;
108 resourceClass = aResourceClass;
109 operationCondition = aOperationCondition;
116 protected UrlAuthorizationRule(Class aResourceClass) {
118 userCondition = null;
119 pathCondition = null;
120 resourceClass = aResourceClass;
121 operationCondition = null;
128 protected UrlAuthorizationRule() {
130 userCondition = null;
131 pathCondition = null;
132 resourceClass = null;
133 operationCondition = null;
140 * org.wamblee.security.authorization.AuthorizationRule#getSupportedTypes()
143 public Class[] getSupportedTypes() {
144 return new Class[] { resourceClass };
151 * org.wamblee.security.authorization.AuthorizationRule#isAllowed(java.lang
152 * .Object, org.wamblee.security.authorization.Operation)
154 public AuthorizationResult isAllowed(Object aResource,
155 Operation aOperation, User aUser) {
156 if (!resourceClass.isInstance(aResource)) {
157 return UNSUPPORTED_RESOURCE;
160 String path = getResourcePath(aResource);
162 return isAllowed(path, aOperation, aUser);
166 * Determines if the operation is allowed on the resource.
169 * Path of the resource.
171 * Operation to be done.
173 * Currently logged in user or null if no user is logged in.
175 * @return Authorization result,
177 protected AuthorizationResult isAllowed(String aPath, Operation aOperation,
179 if (!pathCondition.matches(aPath)) {
183 if (!operationCondition.matches(aOperation)) {
187 if (!userCondition.matches(aUser)) {
195 * Gets the path of the resource.
198 * Resource, guaranteed to be an instance of
199 * {@link #resourceClass}.
201 * @return Path of the resource.
203 protected abstract String getResourcePath(Object aResource);
208 * @see java.lang.Object#toString()
211 public String toString() {
212 return "UrlAUthorizationRule(result = " + result +
213 ", pathCondition = " + pathCondition + ", userCondition = " +
214 userCondition + ", resourceClass = " + resourceClass + ")";
218 * Gets the authorization result for OR mapping.
222 @Column(name = "AUTH_RESULT", nullable = false)
223 protected String getAuthorizationResultString() {
224 if (result == null) {
228 return result.toString();
232 * Sets the authorization result, for OR mapping.
237 protected void setAuthorizationResultString(String aResult) {
238 result = AuthorizationResult.valueOf(aResult);
241 @Column(name = "RES_CLASSNAME", nullable = false)
242 protected String getResourceClassName() {
243 if (resourceClass == null) {
247 return resourceClass.getName();
250 protected void setResourceClassName(String aResourceClass) {
252 resourceClass = Class.forName(aResourceClass);
253 } catch (ClassNotFoundException e) {
254 LOGGER.error("Cannot find resource class '" + aResourceClass + "'",
256 throw new IllegalArgumentException(e.getMessage(), e);
262 * @return Returns the operationCondition.
264 @ManyToOne(cascade = CascadeType.ALL)
265 @JoinColumn(name = "OPER_COND_PK")
266 public OperationCondition getOperationCondition() {
267 return operationCondition;
272 * @param aOperationCondition
273 * The operationCondition to set.
275 protected void setOperationCondition(OperationCondition aOperationCondition) {
276 operationCondition = aOperationCondition;
281 * @return Returns the pathCondition.
283 @ManyToOne(cascade = CascadeType.ALL)
284 @JoinColumn(name = "PATH_COND_PK")
285 public PathCondition getPathCondition() {
286 return pathCondition;
291 * @param aPathCondition
292 * The pathCondition to set.
294 protected void setPathCondition(PathCondition aPathCondition) {
295 pathCondition = aPathCondition;
300 * @return Returns the userCondition.
302 @ManyToOne(cascade = CascadeType.ALL)
303 @JoinColumn(name = "USER_COND_PK")
304 public UserCondition getUserCondition() {
305 return userCondition;
310 * @param aUserCondition
311 * The userCondition to set.
313 protected void setUserCondition(UserCondition aUserCondition) {
314 userCondition = aUserCondition;