View Javadoc

1   package org.apache.turbine.modules.actions.sessionvalidator;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.commons.configuration.Configuration;
23  
24  import org.apache.commons.lang.StringUtils;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  
29  import org.apache.turbine.Turbine;
30  import org.apache.turbine.TurbineConstants;
31  
32  import org.apache.turbine.pipeline.PipelineData;
33  import org.apache.turbine.services.security.TurbineSecurity;
34  
35  import org.apache.turbine.util.RunData;
36  import org.apache.turbine.util.TurbineException;
37  
38  /**
39   * SessionValidator that requires login for use with Template Services
40   * like Velocity or WebMacro.
41   *
42   * <br>
43   *
44   * Templating services requires a different Session Validator
45   * because of the way it handles screens.  If you use the WebMacro or
46   * Velocity Service with the DefaultSessionValidator, users will be able to
47   * bypass login by directly addressing the template using
48   * template/index.wm.  This is because the Page class looks for the
49   * keyword "template" in the Path information and if it finds it will
50   * reset the screen using it's lookup mechanism and thereby bypass
51   * Login.
52   *
53   * Note that you will need to set the template.login property to the
54   * login template.
55   *
56   * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a>
57   * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
58   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
59   * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
60   * @version $Id: TemplateSecureSessionValidator.java 1066518 2011-02-02 16:30:53Z ludwig $
61   */
62  public class TemplateSecureSessionValidator
63      extends SessionValidator
64  {
65      /** Logging */
66      private static Log log = LogFactory.getLog(
67              TemplateSecureSessionValidator.class);
68  
69      /**
70       * doPerform is virtually identical to DefaultSessionValidator
71       * except that it calls template methods instead of bare screen
72       * methods. For example, it uses <code>setScreenTemplate</code> to
73       * load the tr.props TEMPLATE_LOGIN instead of the default's
74       * setScreen to TurbineConstants.SCREEN_LOGIN.
75       * @deprecated Use PipelineData version instead.
76       * @see DefaultSessionValidator
77       * @param data Turbine information.
78       * @throws TurbineException The anonymous user could not be obtained
79       *         from the security service
80       */
81      @Deprecated
82      @Override
83      public void doPerform(RunData data)
84              throws TurbineException
85      {
86          Configuration conf = Turbine.getConfiguration();
87  
88          // Pull user from session.
89          data.populate();
90  
91          // The user may have not logged in, so create a "guest/anonymous" user.
92          if (data.getUser() == null)
93          {
94              log.debug("Fixing up empty User Object!");
95              data.setUser(TurbineSecurity.getAnonymousUser());
96              data.save();
97          }
98  
99          // This is the secure sessionvalidator, so user must be logged in.
100         if (!data.getUser().hasLoggedIn())
101         {
102             log.debug("User is not logged in!");
103 
104             // only set the message if nothing else has already set it
105             // (e.g. the LogoutUser action).
106             if (StringUtils.isEmpty(data.getMessage()))
107             {
108                 data.setMessage(conf.getString(TurbineConstants.LOGIN_MESSAGE));
109             }
110 
111             // Set the screen template to the login page.
112             String loginTemplate =
113                 conf.getString(TurbineConstants.TEMPLATE_LOGIN);
114 
115             log.debug("Sending User to the Login Screen ("
116                     + loginTemplate + ")");
117             data.getTemplateInfo().setScreenTemplate(loginTemplate);
118 
119             // We're not doing any actions buddy! (except action.login which
120             // will have been performed already)
121             data.setAction(null);
122         }
123 
124         log.debug("Login Check finished!");
125 
126         // Make sure we have some way to return a response.
127         if (!data.hasScreen() && StringUtils.isEmpty(
128                 data.getTemplateInfo().getScreenTemplate()))
129         {
130             String template = conf.getString(
131                     TurbineConstants.TEMPLATE_HOMEPAGE);
132 
133             if (StringUtils.isNotEmpty(template))
134             {
135                 data.getTemplateInfo().setScreenTemplate(template);
136             }
137             else
138             {
139                 data.setScreen(conf.getString(
140                         TurbineConstants.SCREEN_HOMEPAGE));
141             }
142         }
143 
144         // The session_access_counter can be placed as a hidden field in
145         // forms.  This can be used to prevent a user from using the
146         // browsers back button and submitting stale data.
147         // FIXME!! a template needs to be written to use this with templates.
148 
149         if (data.getParameters().containsKey("_session_access_counter")
150                 && !TurbineSecurity.isAnonymousUser(data.getUser()))
151         {
152             // See comments in screens.error.InvalidState.
153             if (data.getParameters().getInt("_session_access_counter")
154                     < (((Integer) data.getUser().getTemp(
155                     "_session_access_counter")).intValue() - 1))
156             {
157                 if (data.getTemplateInfo().getScreenTemplate() != null)
158                 {
159                     data.getUser().setTemp("prev_template",
160                             data.getTemplateInfo().getScreenTemplate()
161                             .replace('/', ','));
162                     data.getTemplateInfo().setScreenTemplate(conf.getString(
163                             TurbineConstants.TEMPLATE_INVALID_STATE));
164                 }
165                 else
166                 {
167                     data.getUser().setTemp("prev_screen",
168                                            data.getScreen().replace('/', ','));
169                     data.setScreen(conf.getString(
170                             TurbineConstants.SCREEN_INVALID_STATE));
171                 }
172                 data.getUser().setTemp("prev_parameters", data.getParameters());
173                 data.setAction("");
174             }
175         }
176 
177         // We do not want to allow both a screen and template parameter.
178         // The template parameter is dominant.
179         if (data.getTemplateInfo().getScreenTemplate() != null)
180         {
181             data.setScreen(null);
182         }
183     }
184 
185     /**
186      * doPerform is virtually identical to DefaultSessionValidator
187      * except that it calls template methods instead of bare screen
188      * methods. For example, it uses <code>setScreenTemplate</code> to
189      * load the tr.props TEMPLATE_LOGIN instead of the default's
190      * setScreen to TurbineConstants.SCREEN_LOGIN.
191      *
192      * @see DefaultSessionValidator
193      * @param pipelineData Turbine information.
194      * @throws TurbineException The anonymous user could not be obtained
195      *         from the security service
196      */
197     @Override
198     public void doPerform(PipelineData pipelineData)
199     throws TurbineException
200     {
201         RunData data = getRunData(pipelineData);
202         doPerform(data);
203     }
204 
205 
206 }