001: /*
002: * $Id: AbstractAuthorizeAction.java 481115 2006-12-01 00:16:41Z germuska $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts.chain.commands;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.apache.struts.chain.contexts.ActionContext;
026: import org.apache.struts.config.ActionConfig;
027:
028: /**
029: * <p>Determine whether the requested action is authorized for the current
030: * user. If not, abort chain processing and perferably, return an error
031: * message of some kind.</p>
032: *
033: * @version $Rev: 481115 $ $Date: 2005-11-12 13:01:44 -0500 (Sat, 12 Nov 2005)
034: * $
035: */
036: public abstract class AbstractAuthorizeAction extends ActionCommandBase {
037: // ------------------------------------------------------ Instance Variables
038:
039: /**
040: * Provide a Commons logging instance for this class.
041: */
042: private static final Log LOG = LogFactory
043: .getLog(AbstractAuthorizeAction.class);
044:
045: // ---------------------------------------------------------- Public Methods
046:
047: /**
048: * <p>Determine whether the requested action is authorized for the current
049: * user. If not, abort chain processing and perferably, return an error
050: * message of some kind.</p>
051: *
052: * @param actionCtx The <code>Context</code> for the current request
053: * @return <code>false</code> if the user is authorized for the selected
054: * action, else <code>true</code> to abort processing.
055: * @throws UnauthorizedActionException if authorization fails
056: * or if an error is encountered in the course of performing the authorization.
057: */
058: public boolean execute(ActionContext actionCtx) throws Exception {
059: // Retrieve ActionConfig
060: ActionConfig actionConfig = actionCtx.getActionConfig();
061:
062: // Is this action protected by role requirements?
063: if (!isAuthorizationRequired(actionConfig)) {
064: return (false);
065: }
066:
067: boolean throwEx;
068:
069: try {
070: throwEx = !(isAuthorized(actionCtx, actionConfig
071: .getRoleNames(), actionConfig));
072: } catch (UnauthorizedActionException ex) {
073: throw ex;
074: } catch (Exception ex) {
075: throwEx = true;
076: LOG.error("Unable to complete authorization process", ex);
077: }
078:
079: if (throwEx) {
080: // The current user is not authorized for this action
081: throw new UnauthorizedActionException(getErrorMessage(
082: actionCtx, actionConfig));
083: } else {
084: return (false);
085: }
086: }
087:
088: /**
089: * <p>Must authorization rules be consulted? The base implementation
090: * returns <code>true</code> if the given <code>ActionConfig</code> has
091: * one or more roles defined.</p>
092: *
093: * @param actionConfig the current ActionConfig object
094: * @return true if the <code>isAuthorized</code> method should be
095: * consulted.
096: */
097: protected boolean isAuthorizationRequired(ActionConfig actionConfig) {
098: String[] roles = actionConfig.getRoleNames();
099:
100: return (roles != null) && (roles.length > 0);
101: }
102:
103: // ------------------------------------------------------- Protected Methods
104:
105: /**
106: * <p>Determine if the action is authorized for the given roles.</p>
107: *
108: * @param context The <code>Context</code> for the current request
109: * @param roles An array of valid roles for this request
110: * @param actionConfig The current action mapping
111: * @return <code>true</code> if the request is authorized, else
112: * <code>false</code>
113: * @throws UnauthorizedActionException If the logic determines that the request is not authorized
114: * but does not wish to rely upon the default mechanism reporting the error.
115: * @throws Exception If the action cannot be tested for authorization
116: */
117: protected abstract boolean isAuthorized(ActionContext context,
118: String[] roles, ActionConfig actionConfig) throws Exception;
119:
120: /**
121: * <p> Retrieve error message from context. </p>
122: *
123: * @param context The <code>Context</code> for the current request
124: * @param actionConfig The current action mapping
125: * @return error message
126: */
127: protected abstract String getErrorMessage(ActionContext context,
128: ActionConfig actionConfig);
129: }
|