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 javax.persistence.Access;
19 import javax.persistence.AccessType;
20 import javax.persistence.CascadeType;
21 import javax.persistence.Column;
22 import javax.persistence.DiscriminatorValue;
23 import javax.persistence.Entity;
24 import javax.persistence.JoinColumn;
25 import javax.persistence.ManyToOne;
26 import javax.persistence.Transient;
28 import org.apache.log4j.Logger;
30 import static org.wamblee.security.authorization.AuthorizationResult.DENIED;
31 import static org.wamblee.security.authorization.AuthorizationResult.GRANTED;
32 import static org.wamblee.security.authorization.AuthorizationResult.UNDECIDED;
33 import static org.wamblee.security.authorization.AuthorizationResult.UNSUPPORTED_RESOURCE;
35 import org.wamblee.security.AbstractPersistent;
36 import org.wamblee.usermgt.User;
39 * Utility base class for implementation of authentication rules based on the
41 * <li>The path of the resource. To obtain the path of a resource, subclasses
42 * must implement {@link #getResourcePath(Object)}. Whether a path is
43 * appropriate is determined by a
44 * {@link org.wamblee.security.authorization.PathCondition}.</li>
45 * <li>The user identity with which the resource is accessed. Whether a user is
46 * appropriate is determined by a
47 * {@link org.wamblee.security.authorization.UserCondition}.</li>
48 * <li>The operation that is requested. Whether the operation is appropriate is
49 * determined by a {@link org.wamblee.security.authorization.OperationCondition}
52 * In case all three conditions match, the condition returns the configured
53 * result passed at construction (GRANTED or DENIED). If the resource is not of
54 * the specified type, the result is UNSUPPORTED_RESOURCE, otherwise, the result
58 @Access(AccessType.PROPERTY)
59 public abstract class UrlAuthorizationRule extends AuthorizationRule {
60 private static final Logger LOGGER = Logger
61 .getLogger(UrlAuthorizationRule.class);
64 * Result that the rule will return in case there is a match.
66 private AuthorizationResult result;
69 * A condition which specifies which users the rule is for.
71 private UserCondition userCondition;
74 * Path the rule applies for.
76 private PathCondition pathCondition;
79 * Resource class that the rule applies for.
81 private Class resourceClass;
84 * Operation that this rule is for.
86 private OperationCondition operationCondition;
89 * Constructs an authorization rule. IF the group and path match, then the
90 * provided result will be returned.
93 * Result of the authorization when the path and group match.
94 * @param aUserCondition
95 * Condition to match users.
96 * @param aPathCondition
97 * Condition to match paths with.
98 * @param aResourceClass
99 * Supported resource class this is for.
100 * @param aOperationCondition
101 * Condition to match the operation with.
103 protected UrlAuthorizationRule(AuthorizationResult aResult,
104 UserCondition aUserCondition, PathCondition aPathCondition,
105 Class aResourceClass, OperationCondition aOperationCondition) {
106 if (!aResult.equals(GRANTED) && !aResult.equals(DENIED)) {
107 throw new IllegalArgumentException(
108 "Only GRANTED or DENIED may be used: " + aResult);
112 userCondition = aUserCondition;
113 pathCondition = aPathCondition;
114 resourceClass = aResourceClass;
115 operationCondition = aOperationCondition;
122 protected UrlAuthorizationRule(Class aResourceClass) {
124 userCondition = null;
125 pathCondition = null;
126 resourceClass = aResourceClass;
127 operationCondition = null;
134 protected UrlAuthorizationRule() {
136 userCondition = null;
137 pathCondition = null;
138 resourceClass = null;
139 operationCondition = null;
146 * org.wamblee.security.authorization.AuthorizationRule#getSupportedTypes()
149 public Class[] getSupportedTypes() {
150 return new Class[] { resourceClass };
157 * org.wamblee.security.authorization.AuthorizationRule#isAllowed(java.lang
158 * .Object, org.wamblee.security.authorization.Operation)
160 public AuthorizationResult isAllowed(Object aResource,
161 Operation aOperation, User aUser) {
162 if (!resourceClass.isInstance(aResource)) {
163 return UNSUPPORTED_RESOURCE;
166 String path = getResourcePath(aResource);
168 return isAllowed(path, aOperation, aUser);
172 * Determines if the operation is allowed on the resource.
175 * Path of the resource.
177 * Operation to be done.
179 * Currently logged in user or null if no user is logged in.
181 * @return Authorization result,
183 protected AuthorizationResult isAllowed(String aPath, Operation aOperation,
185 if (!pathCondition.matches(aPath)) {
189 if (!operationCondition.matches(aOperation)) {
193 if (!userCondition.matches(aUser)) {
201 * Gets the path of the resource.
204 * Resource, guaranteed to be an instance of
205 * {@link #resourceClass}.
207 * @return Path of the resource.
209 protected abstract String getResourcePath(Object aResource);
214 * @see java.lang.Object#toString()
217 public String toString() {
218 return "UrlAUthorizationRule(result = " + result +
219 ", pathCondition = " + pathCondition + ", userCondition = " +
220 userCondition + ", resourceClass = " + resourceClass + ")";
224 * Gets the authorization result for OR mapping.
228 @Column(name = "AUTH_RESULT", nullable = false)
229 protected String getAuthorizationResultString() {
230 if (result == null) {
234 return result.toString();
238 * Sets the authorization result, for OR mapping.
243 protected void setAuthorizationResultString(String aResult) {
244 result = AuthorizationResult.valueOf(aResult);
247 @Column(name = "RES_CLASSNAME", nullable = false)
248 protected String getResourceClassName() {
249 if (resourceClass == null) {
253 return resourceClass.getName();
256 protected void setResourceClassName(String aResourceClass) {
258 resourceClass = Class.forName(aResourceClass);
259 } catch (ClassNotFoundException e) {
260 LOGGER.error("Cannot find resource class '" + aResourceClass + "'",
262 throw new IllegalArgumentException(e.getMessage(), e);
268 * @return Returns the operationCondition.
270 @ManyToOne(cascade = CascadeType.ALL)
271 @JoinColumn(name = "OPER_COND_PK")
272 public OperationCondition getOperationCondition() {
273 return operationCondition;
278 * @param aOperationCondition
279 * The operationCondition to set.
281 protected void setOperationCondition(OperationCondition aOperationCondition) {
282 operationCondition = aOperationCondition;
287 * @return Returns the pathCondition.
289 @ManyToOne(cascade = CascadeType.ALL)
290 @JoinColumn(name = "PATH_COND_PK")
291 public PathCondition getPathCondition() {
292 return pathCondition;
297 * @param aPathCondition
298 * The pathCondition to set.
300 protected void setPathCondition(PathCondition aPathCondition) {
301 pathCondition = aPathCondition;
306 * @return Returns the userCondition.
308 @ManyToOne(cascade = CascadeType.ALL)
309 @JoinColumn(name = "USER_COND_PK")
310 public UserCondition getUserCondition() {
311 return userCondition;
316 * @param aUserCondition
317 * The userCondition to set.
319 protected void setUserCondition(UserCondition aUserCondition) {
320 userCondition = aUserCondition;