View Javadoc

1   /*
2    * $Id: AbstractAuthorizeAction.java 481115 2006-12-01 00:16:41Z germuska $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.struts.chain.commands;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.struts.chain.contexts.ActionContext;
26  import org.apache.struts.config.ActionConfig;
27  
28  /**
29   * <p>Determine whether the requested action is authorized for the current
30   * user. If not, abort chain processing and perferably, return an error
31   * message of some kind.</p>
32   *
33   * @version $Rev: 481115 $ $Date: 2005-11-12 13:01:44 -0500 (Sat, 12 Nov 2005)
34   *          $
35   */
36  public abstract class AbstractAuthorizeAction extends ActionCommandBase {
37      // ------------------------------------------------------ Instance Variables
38  
39      /**
40       * Provide a Commons logging instance for this class.
41       */
42      private static final Log LOG =
43          LogFactory.getLog(AbstractAuthorizeAction.class);
44  
45      // ---------------------------------------------------------- Public Methods
46  
47      /**
48       * <p>Determine whether the requested action is authorized for the current
49       * user.  If not, abort chain processing and perferably, return an error
50       * message of some kind.</p>
51       *
52       * @param actionCtx The <code>Context</code> for the current request
53       * @return <code>false</code> if the user is authorized for the selected
54       *         action, else <code>true</code> to abort processing.
55       * @throws UnauthorizedActionException if authorization fails 
56       * or if an error is encountered in the course of performing the authorization.
57       */
58      public boolean execute(ActionContext actionCtx)
59          throws Exception {
60          // Retrieve ActionConfig
61          ActionConfig actionConfig = actionCtx.getActionConfig();
62  
63          // Is this action protected by role requirements?
64          if (!isAuthorizationRequired(actionConfig)) {
65              return (false);
66          }
67  
68          boolean throwEx;
69  
70          try {
71              throwEx =
72                  !(isAuthorized(actionCtx, actionConfig.getRoleNames(),
73                      actionConfig));
74          } catch (UnauthorizedActionException ex) {
75          	throw ex;
76          } catch (Exception ex) {
77              throwEx = true;
78              LOG.error("Unable to complete authorization process", ex);
79          }
80  
81          if (throwEx) {
82              // The current user is not authorized for this action
83              throw new UnauthorizedActionException(getErrorMessage(actionCtx,
84                      actionConfig));
85          } else {
86              return (false);
87          }
88      }
89  
90      /**
91       * <p>Must authorization rules be consulted?  The base implementation
92       * returns <code>true</code> if the given <code>ActionConfig</code> has
93       * one or more roles defined.</p>
94       *
95       * @param actionConfig the current ActionConfig object
96       * @return true if the <code>isAuthorized</code> method should be
97       *         consulted.
98       */
99      protected boolean isAuthorizationRequired(ActionConfig actionConfig) {
100         String[] roles = actionConfig.getRoleNames();
101 
102         return (roles != null) && (roles.length > 0);
103     }
104 
105     // ------------------------------------------------------- Protected Methods
106 
107     /**
108      * <p>Determine if the action is authorized for the given roles.</p>
109      *
110      * @param context      The <code>Context</code> for the current request
111      * @param roles        An array of valid roles for this request
112      * @param actionConfig The current action mapping
113      * @return <code>true</code> if the request is authorized, else
114      *         <code>false</code>
115      * @throws UnauthorizedActionException If the logic determines that the request is not authorized 
116      * but does not wish to rely upon the default mechanism reporting the error.
117      * @throws Exception If the action cannot be tested for authorization
118      */
119     protected abstract boolean isAuthorized(ActionContext context,
120         String[] roles, ActionConfig actionConfig)
121         throws Exception;
122 
123     /**
124      * <p> Retrieve error message from context. </p>
125      *
126      * @param context      The <code>Context</code> for the current request
127      * @param actionConfig The current action mapping
128      * @return error message
129      */
130     protected abstract String getErrorMessage(ActionContext context,
131         ActionConfig actionConfig);
132 }