    001package org.apache.turbine.pipeline;
    002
    003
    004/*
    005 * Licensed to the Apache Software Foundation (ASF) under one
    006 * or more contributor license agreements.  See the NOTICE file
    007 * distributed with this work for additional information
    008 * regarding copyright ownership.  The ASF licenses this file
    009 * to you under the Apache License, Version 2.0 (the
    010 * "License"); you may not use this file except in compliance
    011 * with the License.  You may obtain a copy of the License at
    012 *
    013 *   http://www.apache.org/licenses/LICENSE-2.0
    014 *
    015 * Unless required by applicable law or agreed to in writing,
    016 * software distributed under the License is distributed on an
    017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    018 * KIND, either express or implied.  See the License for the
    019 * specific language governing permissions and limitations
    020 * under the License.
    021 */
    022
    023
    024import java.io.IOException;
    025import java.util.ArrayList;
    026import java.util.Enumeration;
    027import java.util.List;
    028
    029import javax.servlet.http.HttpSession;
    030
    031import org.apache.commons.configuration.Configuration;
    032import org.apache.turbine.TurbineConstants;
    033import org.apache.turbine.annotation.TurbineConfiguration;
    034import org.apache.turbine.annotation.TurbineLoader;
    035import org.apache.turbine.modules.Action;
    036import org.apache.turbine.modules.ActionLoader;
    037import org.apache.turbine.services.velocity.VelocityService;
    038import org.apache.turbine.util.RunData;
    039import org.apache.turbine.util.TurbineException;
    040import org.apache.turbine.util.template.TemplateInfo;
    041
    042/**
    043 * Handles the Login and Logout actions in the request process
    044 * cycle.
    045 *
    046 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    047 * @author <a href="mailto:dlr@apache.org">Daniel Rall</a>
    048 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
    049 * @version $Id: DefaultLoginValve.java 1706239 2015-10-01 13:18:35Z tv $
    050 */
    051public class DefaultLoginValve
    052    extends AbstractValve
    053{
    054    /** Injected loader instance */
    055    @TurbineLoader( Action.class )
    056    private ActionLoader actionLoader;
    057
    058    /** Injected configuration instance */
    059    @TurbineConfiguration
    060    private Configuration config;
    061
    062    /**
    063     * @see org.apache.turbine.pipeline.Valve#invoke(PipelineData, ValveContext)
    064     */
    065    @Override
    066    public void invoke(PipelineData pipelineData, ValveContext context)
    067        throws IOException, TurbineException
    068    {
    069        try
    070        {
    071            process(pipelineData);
    072        }
    073        catch (Exception e)
    074        {
    075            throw new TurbineException(e);
    076        }
    077
    078        // Pass control to the next Valve in the Pipeline
    079        context.invokeNext(pipelineData);
    080    }
    081
    082    /**
    083     * Handles user sessions, parsing of the action from the query
    084     * string, and access control.
    085     *
    086     * @param pipelineData The run-time data.
    087     */
    088    protected void process(PipelineData pipelineData)
    089        throws Exception
    090    {
    091        RunData data = getRunData(pipelineData);
    092        // Special case for login and logout, this must happen before the
    093        // session validator is executed in order either to allow a user to
    094        // even login, or to ensure that the session validator gets to
    095        // mandate its page selection policy for non-logged in users
    096        // after the logout has taken place.
    097        String actionName = data.getAction();
    098        if (data.hasAction() &&
    099            actionName.equalsIgnoreCase
    100            (config.getString(TurbineConstants.ACTION_LOGIN_KEY)) ||
    101            actionName.equalsIgnoreCase
    102            (config.getString(TurbineConstants.ACTION_LOGOUT_KEY)))
    103        {
    104            // If a User is logging in, we should refresh the
    105            // session here.  Invalidating session and starting a
    106            // new session would seem to be a good method, but I
    107            // (JDM) could not get this to work well (it always
    108            // required the user to login twice).  Maybe related
    109            // to JServ?  If we do not clear out the session, it
    110            // is possible a new User may accidently (if they
    111            // login incorrectly) continue on with information
    112            // associated with the previous User.  Currently the
    113            // only keys stored in the session are "turbine.user"
    114            // and "turbine.acl".
    115            if (actionName.equalsIgnoreCase
    116                (config.getString(TurbineConstants.ACTION_LOGIN_KEY)))
    117            {
    118                @SuppressWarnings("unchecked")
    119                Enumeration<String> names = data.getSession().getAttributeNames();
    120                if (names != null)
    121                {
    122                    // copy keys into a new list, so we can clear the session
    123                    // and not get ConcurrentModificationException
    124                    List<String> nameList = new ArrayList<String>();
    125                    while (names.hasMoreElements())
    126                    {
    127                        nameList.add(names.nextElement());
    128                    }
    129
    130                    HttpSession session = data.getSession();
    131                    for (String name : nameList)
    132                    {
    133                        try
    134                        {
    135                            session.removeAttribute(name);
    136                        }
    137                        catch (IllegalStateException invalidatedSession)
    138                        {
    139                            break;
    140                        }
    141                    }
    142                }
    143            }
    144
    145            actionLoader.exec(pipelineData, data.getAction());
    146            cleanupTemplateContext(data);
    147            data.setAction(null);
    148        }
    149    }
    150    /**
    151     * cleans the Velocity Context if available.
    152     *
    153     * @param pipelineData A RunData Object
    154     *
    155     * @throws Exception A problem while cleaning out the Template Context occured.
    156     */
    157    private void cleanupTemplateContext(RunData data)
    158    throws Exception
    159    {
    160        // This is Velocity specific and shouldn't be done here.
    161        // But this is a band aid until we get real listeners
    162        // here.
    163        TemplateInfo ti = data.getTemplateInfo();
    164        if (ti != null)
    165        {
    166            ti.removeTemp(VelocityService.CONTEXT);
    167        }
    168    }
    169}