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 }