/*
* Copyright 2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wamblee.security.authorization;
import static org.wamblee.security.authorization.AuthorizationResult.DENIED;
import static org.wamblee.security.authorization.AuthorizationResult.GRANTED;
import static org.wamblee.security.authorization.AuthorizationResult.UNDECIDED;
import static org.wamblee.security.authorization.AuthorizationResult.UNSUPPORTED_RESOURCE;
import org.apache.log4j.Logger;
import org.wamblee.persistence.AbstractPersistent;
import org.wamblee.usermgt.User;
/**
* Utility base class for implementation of authentication rules based on the
*
* - The path of the resource. To obtain the path of a resource, subclasses
* must implement {@link #getResourcePath(Object)}.
* Whether a path is appropriate is determined by a
* {@link org.wamblee.security.authorization.PathCondition}.
*
* - The user identity with which the resource is accessed.
* Whether a user is appropriate is determined by
* a {@link org.wamblee.security.authorization.UserCondition}.
*
* - The operation that is requested.
* Whether the operation is appropriate is determined by a
* {@link org.wamblee.security.authorization.OperationCondition}.
*
*
*
* In case all three conditions match, the condition returns the configured
* result passed at construction (GRANTED or DENIED). If the resource is not
* of the specified type, the result is UNSUPPORTED_RESOURCE, otherwise, the
* result is UNDECIDED.
*/
public abstract class UrlAuthorizationRule extends AbstractPersistent implements AuthorizationRule {
private static final Logger LOGGER = Logger.getLogger(UrlAuthorizationRule.class);
/**
* Result that the rule will return in case there is a match.
*/
private AuthorizationResult _result;
/**
* A condition which specifies which users the rule is for.
*/
private UserCondition _userCondition;
/**
* Path the rule applies for.
*/
private PathCondition _pathCondition;
/**
* Resource class that the rule applies for.
*/
private Class _resourceClass;
/**
* Operation that this rule is for.
*/
private OperationCondition _operationCondition;
/**
* Constructs an authorization rule.
* IF the group and path match, then the provided result will be returned.
* @param aResult Result of the authorization when the path and group match.
* @param aUserCondition Condition to match users.
* @param aPathCondition Condition to match paths with.
* @param aResourceClass Supported resource class this is for.
* @param aOperationCondition Condition to match the operation with.
*/
protected UrlAuthorizationRule(AuthorizationResult aResult, UserCondition aUserCondition,
PathCondition aPathCondition, Class aResourceClass, OperationCondition aOperationCondition) {
if ( !aResult.equals(GRANTED) && !aResult.equals(DENIED)) {
throw new IllegalArgumentException("Only GRANTED or DENIED may be used: " + aResult);
}
_result = aResult;
_userCondition = aUserCondition;
_pathCondition = aPathCondition;
_resourceClass = aResourceClass;
_operationCondition = aOperationCondition;
}
/**
* For OR mapping.
*
*/
protected UrlAuthorizationRule(Class aResourceClass) {
_result = null;
_userCondition = null;
_pathCondition = null;
_resourceClass = aResourceClass;
_operationCondition = null;
}
/**
* For OR mapping.
*
*/
protected UrlAuthorizationRule() {
_result = null;
_userCondition = null;
_pathCondition = null;
_resourceClass = null;
_operationCondition = null;
}
/*
* (non-Javadoc)
*
* @see org.wamblee.security.authorization.AuthorizationRule#getSupportedTypes()
*/
public Class[] getSupportedTypes() {
return new Class[] { _resourceClass };
}
/*
* (non-Javadoc)
*
* @see org.wamblee.security.authorization.AuthorizationRule#isAllowed(java.lang.Object,
* org.wamblee.security.authorization.Operation)
*/
public AuthorizationResult isAllowed(Object aResource, Operation anOperation, User aUser) {
if ( ! _resourceClass.isInstance(aResource)) {
return UNSUPPORTED_RESOURCE;
}
String path = getResourcePath(aResource);
return isAllowed(path, anOperation, aUser);
}
/**
* Determines if the operation is allowed on the resource.
* @param aPath Path of the resource.
* @param aOperation Operation to be done.
* @param aUser Currently logged in user or null if no user is logged in.
* @return Authorization result,
*/
protected AuthorizationResult isAllowed(String aPath, Operation aOperation, User aUser) {
if ( ! _pathCondition.matches(aPath) ) {
return UNDECIDED;
}
if ( !_operationCondition.matches(aOperation) ) {
return UNDECIDED;
}
if ( !_userCondition.matches(aUser)) {
return UNDECIDED;
}
return _result;
}
/**
* Gets the path of the resource.
* @param aResource Resource, guaranteed to be an instance of
* {@link #_resourceClass}.
* @return Path of the resource.
*/
protected abstract String getResourcePath(Object aResource);
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "UrlAUthorizationRule(result = " + _result +
", pathCondition = " + _pathCondition +
", userCondition = " + _userCondition +
", resourceClass = " + _resourceClass + ")";
}
/**
* Gets the authorization result for OR mapping.
* @return Result.
*/
protected String getAuthorizationResultString() {
if ( _result == null ) {
return null;
}
return _result.toString();
}
/**
* Sets the authorization result, for OR mapping.
* @param aResult Result.
*/
protected void setAuthorizationResultString(String aResult) {
_result = AuthorizationResult.valueOf(aResult);
}
protected String getResourceClassName() {
if ( _resourceClass == null ) {
return "";
}
return _resourceClass.getName();
}
protected void setResourceClassName(String aResourceClass) {
try {
_resourceClass = Class.forName(aResourceClass);
} catch (ClassNotFoundException e) {
LOGGER.error("Cannot find resource class '" + aResourceClass + "'", e);
throw new IllegalArgumentException(e.getMessage(), e);
}
}
/**
* @return Returns the _operationCondition.
*/
public OperationCondition getOperationCondition() {
return _operationCondition;
}
/**
* @param aOperationCondition The _operationCondition to set.
*/
protected void setOperationCondition(OperationCondition aOperationCondition) {
_operationCondition = aOperationCondition;
}
/**
* @return Returns the _pathCondition.
*/
public PathCondition getPathCondition() {
return _pathCondition;
}
/**
* @param aPathCondition The _pathCondition to set.
*/
protected void setPathCondition(PathCondition aPathCondition) {
_pathCondition = aPathCondition;
}
/**
* @return Returns the _userCondition.
*/
public UserCondition getUserCondition() {
return _userCondition;
}
/**
* @param aUserCondition The _userCondition to set.
*/
protected void setUserCondition(UserCondition aUserCondition) {
_userCondition = aUserCondition;
}
}