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.turbine.TurbineConstants; 032import org.apache.turbine.annotation.TurbineConfiguration; 033import org.apache.turbine.annotation.TurbineLoader; 034import org.apache.turbine.modules.Action; 035import org.apache.turbine.modules.ActionLoader; 036import org.apache.turbine.services.velocity.VelocityService; 037import org.apache.turbine.util.RunData; 038import org.apache.turbine.util.TurbineException; 039import 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$ 049 */ 050public class DefaultLoginValve 051 implements Valve 052{ 053 /** Injected loader instance */ 054 @TurbineLoader( Action.class ) 055 private ActionLoader actionLoader; 056 057 @TurbineConfiguration( TurbineConstants.ACTION_LOGIN_KEY ) 058 private String actionLogin; 059 060 @TurbineConfiguration( TurbineConstants.ACTION_LOGOUT_KEY ) 061 private String actionLogout; 062 063 /** 064 * @see org.apache.turbine.pipeline.Valve#invoke(PipelineData, ValveContext) 065 */ 066 @Override 067 public void invoke(PipelineData pipelineData, ValveContext context) 068 throws IOException, TurbineException 069 { 070 try 071 { 072 process(pipelineData); 073 } 074 catch (Exception e) 075 { 076 throw new TurbineException(e); 077 } 078 079 // Pass control to the next Valve in the Pipeline 080 context.invokeNext(pipelineData); 081 } 082 083 /** 084 * Handles user sessions, parsing of the action from the query 085 * string, and access control. 086 * 087 * @param pipelineData The run-time data. 088 * 089 * @throws Exception if executing the action fails 090 */ 091 protected void process(PipelineData pipelineData) 092 throws Exception 093 { 094 RunData data = pipelineData.getRunData(); 095 // Special case for login and logout, this must happen before the 096 // session validator is executed in order either to allow a user to 097 // even login, or to ensure that the session validator gets to 098 // mandate its page selection policy for non-logged in users 099 // after the logout has taken place. 100 String actionName = data.getAction(); 101 if (data.hasAction() && 102 actionName.equalsIgnoreCase(actionLogin) || 103 actionName.equalsIgnoreCase(actionLogout)) 104 { 105 // If a User is logging in, we should refresh the 106 // session here. Invalidating session and starting a 107 // new session would seem to be a good method, but I 108 // (JDM) could not get this to work well (it always 109 // required the user to login twice). Maybe related 110 // to JServ? If we do not clear out the session, it 111 // is possible a new User may accidently (if they 112 // login incorrectly) continue on with information 113 // associated with the previous User. Currently the 114 // only keys stored in the session are "turbine.user" 115 // and "turbine.acl". 116 if (actionName.equalsIgnoreCase(actionLogin)) 117 { 118 Enumeration<String> names = data.getSession().getAttributeNames(); 119 if (names != null) 120 { 121 // copy keys into a new list, so we can clear the session 122 // and not get ConcurrentModificationException 123 List<String> nameList = new ArrayList<>(); 124 while (names.hasMoreElements()) 125 { 126 nameList.add(names.nextElement()); 127 } 128 129 HttpSession session = data.getSession(); 130 for (String name : nameList) 131 { 132 try 133 { 134 session.removeAttribute(name); 135 } 136 catch (IllegalStateException invalidatedSession) 137 { 138 break; 139 } 140 } 141 } 142 } 143 144 actionLoader.exec(pipelineData, data.getAction()); 145 cleanupTemplateContext(data); 146 data.setAction(null); 147 } 148 } 149 150 /** 151 * cleans the Velocity Context if available. 152 * 153 * @param data A RunData Object 154 */ 155 private void cleanupTemplateContext(RunData data) 156 { 157 // This is Velocity specific and shouldn't be done here. 158 // But this is a band aid until we get real listeners 159 // here. 160 TemplateInfo ti = data.getTemplateInfo(); 161 if (ti != null) 162 { 163 ti.removeTemp(VelocityService.CONTEXT); 164 } 165 } 166}