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 }