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.enterprise.inject.Typed;
21 import javax.persistence.Access;
22 import javax.persistence.AccessType;
23 import javax.persistence.CascadeType;
24 import javax.persistence.Column;
25 import javax.persistence.DiscriminatorValue;
26 import javax.persistence.Entity;
27 import javax.persistence.JoinColumn;
28 import javax.persistence.ManyToOne;
29 import javax.persistence.Transient;
31 import org.apache.log4j.Logger;
32 import org.wamblee.usermgt.User;
35 * Utility base class for implementation of authentication rules based on the
37 * <li>The path of the resource. To obtain the path of a resource, subclasses
38 * must implement {@link #getResourcePath(Object)}. Whether a path is
39 * appropriate is determined by a
40 * {@link org.wamblee.security.authorization.AbstractPathCondition}.</li>
41 * <li>The user identity with which the resource is accessed. Whether a user is
42 * appropriate is determined by a
43 * {@link org.wamblee.security.authorization.AbstractUserCondition}.</li>
44 * <li>The operation that is requested. Whether the operation is appropriate is
45 * determined by a {@link org.wamblee.security.authorization.AbstractOperationCondition}
48 * In case all three conditions match, the condition returns the configured
49 * result passed at construction (GRANTED or DENIED). If the resource is not of
50 * the specified type, the result is UNSUPPORTED_RESOURCE, otherwise, the result
54 @Access(AccessType.PROPERTY)
55 public abstract class UrlAuthorizationRule extends AbstractAuthorizationRule {
56 private static final Logger LOGGER = Logger
57 .getLogger(UrlAuthorizationRule.class);
60 * Result that the rule will return in case there is a match.
62 private AuthorizationResult result;
65 * A condition which specifies which users the rule is for.
67 private UserCondition userCondition;
70 * Path the rule applies for.
72 private PathCondition pathCondition;
75 * Resource class that the rule applies for.
77 private Class resourceClass;
80 * Operation that this rule is for.
83 private OperationCondition operationCondition;
86 * Constructs an authorization rule. IF the group and path match, then the
87 * provided result will be returned.
90 * Result of the authorization when the path and group match.
91 * @param aUserCondition
92 * Condition to match users.
93 * @param aPathCondition
94 * Condition to match paths with.
95 * @param aResourceClass
96 * Supported resource class this is for.
97 * @param aOperationCondition
98 * Condition to match the operation with.
100 protected UrlAuthorizationRule(AuthorizationResult aResult,
101 UserCondition aUserCondition, PathCondition aPathCondition,
102 Class aResourceClass, OperationCondition aOperationCondition) {
103 if (!aResult.equals(GRANTED) && !aResult.equals(DENIED)) {
104 throw new IllegalArgumentException(
105 "Only GRANTED or DENIED may be used: " + aResult);
109 userCondition = aUserCondition;
110 pathCondition = aPathCondition;
111 resourceClass = aResourceClass;
112 operationCondition = aOperationCondition;
119 protected UrlAuthorizationRule(Class aResourceClass) {
121 userCondition = null;
122 pathCondition = null;
123 resourceClass = aResourceClass;
124 operationCondition = null;
131 protected UrlAuthorizationRule() {
133 userCondition = null;
134 pathCondition = null;
135 resourceClass = null;
136 operationCondition = null;
143 * org.wamblee.security.authorization.AuthorizationRule#getSupportedTypes()
146 public Class[] getSupportedTypes() {
147 return new Class[] { resourceClass };
154 * org.wamblee.security.authorization.AuthorizationRule#isAllowed(java.lang
155 * .Object, org.wamblee.security.authorization.Operation)
157 public AuthorizationResult isAllowed(Object aResource,
158 Operation aOperation, User aUser) {
159 if (!resourceClass.isInstance(aResource)) {
160 return UNSUPPORTED_RESOURCE;
163 String path = getResourcePath(aResource);
165 return isAllowed(path, aOperation, aUser);
169 * Determines if the operation is allowed on the resource.
172 * Path of the resource.
174 * Operation to be done.
176 * Currently logged in user or null if no user is logged in.
178 * @return Authorization result,
180 protected AuthorizationResult isAllowed(String aPath, Operation aOperation,
182 if (!pathCondition.matches(aPath)) {
186 if (!operationCondition.matches(aOperation)) {
190 if (!userCondition.matches(aUser)) {
198 * Gets the path of the resource.
201 * Resource, guaranteed to be an instance of
202 * {@link #resourceClass}.
204 * @return Path of the resource.
206 protected abstract String getResourcePath(Object aResource);
211 * @see java.lang.Object#toString()
214 public String toString() {
215 return "UrlAUthorizationRule(result = " + result +
216 ", pathCondition = " + pathCondition + ", userCondition = " +
217 userCondition + ", resourceClass = " + resourceClass + ")";
221 * Gets the authorization result for OR mapping.
225 @Column(name = "AUTH_RESULT", nullable = false)
226 protected String getAuthorizationResultString() {
227 if (result == null) {
231 return result.toString();
235 * Sets the authorization result, for OR mapping.
240 protected void setAuthorizationResultString(String aResult) {
241 result = AuthorizationResult.valueOf(aResult);
244 @Column(name = "RES_CLASSNAME", nullable = false)
245 protected String getResourceClassName() {
246 if (resourceClass == null) {
250 return resourceClass.getName();
253 protected void setResourceClassName(String aResourceClass) {
255 resourceClass = Class.forName(aResourceClass);
256 } catch (ClassNotFoundException e) {
257 LOGGER.error("Cannot find resource class '" + aResourceClass + "'",
259 throw new IllegalArgumentException(e.getMessage(), e);
265 * @return Returns the operationCondition.
267 @ManyToOne(cascade = CascadeType.ALL, targetEntity = AbstractOperationCondition.class)
268 @JoinColumn(name = "OPER_COND_PK")
269 public OperationCondition getOperationCondition() {
270 return operationCondition;
275 * @param aOperationCondition
276 * The operationCondition to set.
278 protected void setOperationCondition(OperationCondition aOperationCondition) {
279 operationCondition = aOperationCondition;
284 * @return Returns the pathCondition.
286 @ManyToOne(cascade = CascadeType.ALL, targetEntity = AbstractPathCondition.class)
287 @JoinColumn(name = "PATH_COND_PK")
288 public PathCondition getPathCondition() {
289 return pathCondition;
294 * @param aPathCondition
295 * The pathCondition to set.
297 protected void setPathCondition(PathCondition aPathCondition) {
298 pathCondition = aPathCondition;
303 * @return Returns the userCondition.
305 @ManyToOne(cascade = CascadeType.ALL, targetEntity = AbstractUserCondition.class)
306 @JoinColumn(name = "USER_COND_PK")
307 public UserCondition getUserCondition() {
308 return userCondition;
313 * @param aUserCondition
314 * The userCondition to set.
316 protected void setUserCondition(UserCondition aUserCondition) {
317 userCondition = aUserCondition;