View Javadoc

    1   package org.apache.turbine.pipeline;
    2
    3
    4   /*
    5    * Licensed to the Apache Software Foundation (ASF) under one
    6    * or more contributor license agreements.  See the NOTICE file
    7    * distributed with this work for additional information
    8    * regarding copyright ownership.  The ASF licenses this file
    9    * to you under the Apache License, Version 2.0 (the
    10   * "License"); you may not use this file except in compliance
    11   * with the License.  You may obtain a copy of the License at
    12   *
    13   *   http://www.apache.org/licenses/LICENSE-2.0
    14   *
    15   * Unless required by applicable law or agreed to in writing,
    16   * software distributed under the License is distributed on an
    17   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    18   * KIND, either express or implied.  See the License for the
    19   * specific language governing permissions and limitations
    20   * under the License.
    21   */
    22
    23
    24  import java.io.IOException;
    25  import java.util.ArrayList;
    26  import java.util.Enumeration;
    27  import java.util.List;
    28
    29  import javax.servlet.http.HttpSession;
    30
    31  import org.apache.turbine.Turbine;
    32  import org.apache.turbine.TurbineConstants;
    33  import org.apache.turbine.modules.Action;
    34  import org.apache.turbine.modules.ActionLoader;
    35  import org.apache.turbine.services.assemblerbroker.TurbineAssemblerBroker;
    36  import org.apache.turbine.services.velocity.VelocityService;
    37  import org.apache.turbine.util.RunData;
    38  import org.apache.turbine.util.TurbineException;
    39  import org.apache.turbine.util.template.TemplateInfo;
    40
    41  /**
    42   * Handles the Login and Logout actions in the request process
    43   * cycle.
    44   *
    45   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    46   * @author <a href="mailto:dlr@apache.org">Daniel Rall</a>
    47   * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
    48   * @version $Id: DefaultLoginValve.java 1078552 2011-03-06 19:58:46Z tv $
    49   */
    50  public class DefaultLoginValve
    51      extends AbstractValve
    52  {
    53      private ActionLoader actionLoader;
    54
    55      /**
    56       * Here we can setup objects that are thread safe and can be
    57       * reused. We setup the session validator and the access
    58       * controller.
    59       */
    60      public DefaultLoginValve()
    61          throws Exception
    62      {
    63          // empty constructor
    64      }
    65
    66      /**
    67       * Initialize this valve for use in a pipeline.
    68       *
    69       * @see org.apache.turbine.pipeline.AbstractValve#initialize()
    70       */
    71      @Override
    72      public void initialize() throws Exception
    73      {
    74          super.initialize();
    75
    76          this.actionLoader = (ActionLoader)TurbineAssemblerBroker.getLoader(Action.NAME);
    77      }
    78
    79      /**
    80       * @see org.apache.turbine.Valve#invoke(RunData, ValveContext)
    81       */
    82      @Override
    83      public void invoke(PipelineData pipelineData, ValveContext context)
    84          throws IOException, TurbineException
    85      {
    86          try
    87          {
    88              process(pipelineData);
    89          }
    90          catch (Exception e)
    91          {
    92              throw new TurbineException(e);
    93          }
    94
    95          // Pass control to the next Valve in the Pipeline
    96          context.invokeNext(pipelineData);
    97      }
    98
    99      /**
    100      * Handles user sessions, parsing of the action from the query
    101      * string, and access control.
    102      *
    103      * @param data The run-time data.
    104      */
    105     protected void process(PipelineData pipelineData)
    106         throws Exception
    107     {
    108         RunData data = getRunData(pipelineData);
    109         // Special case for login and logout, this must happen before the
    110         // session validator is executed in order either to allow a user to
    111         // even login, or to ensure that the session validator gets to
    112         // mandate its page selection policy for non-logged in users
    113         // after the logout has taken place.
    114         String actionName = data.getAction();
    115         if (data.hasAction() &&
    116             actionName.equalsIgnoreCase
    117             (Turbine.getConfiguration().getString(TurbineConstants.ACTION_LOGIN_KEY)) ||
    118             actionName.equalsIgnoreCase
    119             (Turbine.getConfiguration().getString(TurbineConstants.ACTION_LOGOUT_KEY)))
    120         {
    121             // If a User is logging in, we should refresh the
    122             // session here.  Invalidating session and starting a
    123             // new session would seem to be a good method, but I
    124             // (JDM) could not get this to work well (it always
    125             // required the user to login twice).  Maybe related
    126             // to JServ?  If we do not clear out the session, it
    127             // is possible a new User may accidently (if they
    128             // login incorrectly) continue on with information
    129             // associated with the previous User.  Currently the
    130             // only keys stored in the session are "turbine.user"
    131             // and "turbine.acl".
    132             if (actionName.equalsIgnoreCase
    133                 (Turbine.getConfiguration().getString(TurbineConstants.ACTION_LOGIN_KEY)))
    134             {
    135                 @SuppressWarnings("unchecked")
    136                 Enumeration<String> names = data.getSession().getAttributeNames();
    137                 if (names != null)
    138                 {
    139                     // copy keys into a new list, so we can clear the session
    140                     // and not get ConcurrentModificationException
    141                     List<String> nameList = new ArrayList<String>();
    142                     while (names.hasMoreElements())
    143                     {
    144                         nameList.add(names.nextElement());
    145                     }
    146
    147                     HttpSession session = data.getSession();
    148                     for (String name : nameList)
    149                     {
    150                         try
    151                         {
    152                             session.removeAttribute(name);
    153                         }
    154                         catch (IllegalStateException invalidatedSession)
    155                         {
    156                             break;
    157                         }
    158                     }
    159                 }
    160             }
    161
    162             actionLoader.exec(pipelineData, data.getAction());
    163             cleanupTemplateContext(data);
    164             data.setAction(null);
    165         }
    166     }
    167     /**
    168      * cleans the Velocity Context if available.
    169      *
    170      * @param data A RunData Object
    171      *
    172      * @throws Exception A problem while cleaning out the Template Context occured.
    173      */
    174     private void cleanupTemplateContext(RunData data)
    175     throws Exception
    176     {
    177         // This is Velocity specific and shouldn't be done here.
    178         // But this is a band aid until we get real listeners
    179         // here.
    180         TemplateInfo ti = data.getTemplateInfo();
    181         if (ti != null)
    182         {
    183             ti.removeTemp(VelocityService.CONTEXT);
    184         }
    185     }
    186 }