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.lang3.StringUtils;
23  import org.apache.logging.log4j.LogManager;
24  import org.apache.logging.log4j.Logger;
25  import org.apache.turbine.Turbine;
26  import org.apache.turbine.TurbineConstants;
27  import org.apache.turbine.annotation.TurbineConfiguration;
28  import org.apache.turbine.om.security.User;
29  import org.apache.turbine.pipeline.PipelineData;
30  import org.apache.turbine.util.RunData;
31  
32  /**
33   * SessionValidator that requires login for use with Template Services
34   * like Velocity or WebMacro.
35   *
36   * <br>
37   *
38   * Templating services requires a different Session Validator
39   * because of the way it handles screens.  If you use the WebMacro or
40   * Velocity Service with the {@link DefaultSessionValidator}, users will be able to
41   * bypass login by directly addressing the template using
42   * template/index.wm.  This is because the Page class looks for the
43   * keyword "template" in the Path information and if it finds it will
44   * reset the screen using it's lookup mechanism and thereby bypass
45   * Login.
46   *
47   * Note that you will need to set the template.login property to the
48   * login template.
49   *
50   * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a>
51   * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
52   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
53   * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
54   * @version $Id$
55   */
56  public class TemplateSecureSessionValidator
57      extends SessionValidator
58  {
59      /** Logging */
60      private static Logger log = LogManager.getLogger(
61              TemplateSecureSessionValidator.class);
62  
63  
64      @TurbineConfiguration( TurbineConstants.LOGIN_MESSAGE )
65      private String loginMessage;
66  
67      @TurbineConfiguration( TurbineConstants.TEMPLATE_LOGIN )
68      private String templateLogin;
69  
70  
71      /**
72       * doPerform is virtually identical to DefaultSessionValidator
73       * except that it calls template methods instead of bare screen
74       * methods. For example, it uses <code>setScreenTemplate</code> to
75       * load the tr.props TEMPLATE_LOGIN instead of the default's
76       * setScreen to TurbineConstants.SCREEN_LOGIN.
77       *
78       * @see DefaultSessionValidator
79       * @param pipelineData Turbine information.
80       * @throws Exception The anonymous user could not be obtained
81       *         from the security service
82       */
83      @Override
84      public void doPerform(PipelineData pipelineData)
85      throws Exception
86      {
87          RunData data = pipelineData.getRunData();
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("Creating an anonymous user object!");
95              User anonymousUser = security.getAnonymousUser();
96              data.setUser(anonymousUser);
97              data.save();
98          }
99  
100         // This is the secure session validator, so user must be logged in.
101         if (!data.getUser().hasLoggedIn())
102         {
103             log.debug("User is not logged in!");
104 
105             // only set the message if nothing else has already set it
106             // (e.g. the LogoutUser action).
107             if (StringUtils.isEmpty(data.getMessage()))
108             {
109                 data.setMessage(loginMessage);
110             }
111 
112             // Set the screen template to the login page.
113             log.debug("Sending User to the Login Screen ({})", templateLogin);
114             data.getTemplateInfo().setScreenTemplate(templateLogin);
115 
116             // We're not doing any actions buddy! (except action.login which
117             // will have been performed already)
118             data.setAction(null);
119         }
120 
121         log.debug("Login Check finished!");
122 
123         // Make sure we have some way to return a response.
124         if (!data.hasScreen() && StringUtils.isEmpty(
125                 data.getTemplateInfo().getScreenTemplate()))
126         {
127             if (StringUtils.isNotEmpty(templateHomepage))
128             {
129                 data.getTemplateInfo().setScreenTemplate(templateHomepage);
130             }
131             else
132             {
133                 data.setScreen(screenHomepage);
134             }
135         } else {
136             handleFormCounterToken(data, false);
137         }
138 
139         // We do not want to allow both a screen and template parameter.
140         // The template parameter is dominant.
141         if (data.getTemplateInfo().getScreenTemplate() != null)
142         {
143             data.setScreen(null);
144         }
145 
146         // Comply with Turbine 4.0 standards
147         pipelineData.get(Turbine.class).put(User.class, data.getUser());
148     }
149 }