    001    package 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
    024    import java.io.IOException;
    025    import java.util.ArrayList;
    026    import java.util.Enumeration;
    027    import java.util.List;
    028
    029    import javax.servlet.http.HttpSession;
    030
    031    import org.apache.turbine.Turbine;
    032    import org.apache.turbine.TurbineConstants;
    033    import org.apache.turbine.modules.Action;
    034    import org.apache.turbine.modules.ActionLoader;
    035    import org.apache.turbine.services.assemblerbroker.TurbineAssemblerBroker;
    036    import org.apache.turbine.services.velocity.VelocityService;
    037    import org.apache.turbine.util.RunData;
    038    import org.apache.turbine.util.TurbineException;
    039    import org.apache.turbine.util.template.TemplateInfo;
    040
    041    /**
    042     * Handles the Login and Logout actions in the request process
    043     * cycle.
    044     *
    045     * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    046     * @author <a href="mailto:dlr@apache.org">Daniel Rall</a>
    047     * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
    048     * @version $Id: DefaultLoginValve.java 1078552 2011-03-06 19:58:46Z tv $
    049     */
    050    public class DefaultLoginValve
    051        extends AbstractValve
    052    {
    053        private ActionLoader actionLoader;
    054
    055        /**
    056         * Here we can setup objects that are thread safe and can be
    057         * reused. We setup the session validator and the access
    058         * controller.
    059         */
    060        public DefaultLoginValve()
    061            throws Exception
    062        {
    063            // empty constructor
    064        }
    065
    066        /**
    067         * Initialize this valve for use in a pipeline.
    068         *
    069         * @see org.apache.turbine.pipeline.AbstractValve#initialize()
    070         */
    071        @Override
    072        public void initialize() throws Exception
    073        {
    074            super.initialize();
    075
    076            this.actionLoader = (ActionLoader)TurbineAssemblerBroker.getLoader(Action.NAME);
    077        }
    078
    079        /**
    080         * @see org.apache.turbine.Valve#invoke(RunData, ValveContext)
    081         */
    082        @Override
    083        public void invoke(PipelineData pipelineData, ValveContext context)
    084            throws IOException, TurbineException
    085        {
    086            try
    087            {
    088                process(pipelineData);
    089            }
    090            catch (Exception e)
    091            {
    092                throw new TurbineException(e);
    093            }
    094
    095            // Pass control to the next Valve in the Pipeline
    096            context.invokeNext(pipelineData);
    097        }
    098
    099        /**
    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    }