2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.usecases.profile;
19
20 import java.util.Map;
21 import javax.faces.context.FacesContext;
22 import javax.servlet.http.Cookie;
23 import javax.servlet.http.HttpServletRequest;
24 import javax.servlet.http.HttpServletResponse;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.shale.usecases.logic.LogonLogic;
28 import org.apache.shale.usecases.model.User;
29 import org.apache.shale.util.Messages;
30 import org.apache.shale.view.AbstractViewController;
31
32 /***
33 * <p><code>ViewController</code> and action methods for the Logon dialog.</p>
34 *
35 * <p><strong>WARNING</strong> - The format of the cookie used to store
36 * "remember me" credentials is <strong>NOT</strong> secure, and should
37 * be considered demo quality. The architecture of a production quality
38 * version of this function would be identical; more effort would need
39 * to be invested in improving security around the cookie values.</p>
40 *
41 * $Id: LogonActions.java 464373 2006-10-16 04:21:54Z rahul $
42 */
43 public class LogonActions extends AbstractViewController {
44
45
46
47
48
49 /***
50 * <p>Log instance for this class.</p>
51 */
52 private static final Log log = LogFactory.getLog(LogonActions.class);
53
54
55 /***
56 * <p>Message resources for this application.</p>
57 */
58 private static final Messages messages =
59 new Messages("org.apache.shale.usecases.view.Bundle");
60
61
62
63
64
65
66 /***
67 * <p>Logical outcome indicating an authenticated user.</p>
68 */
69 static final String AUTHENTICATED = "authenticated";
70
71
72 /***
73 * <p>Logical outcome indicating the user wishes to create a new
74 * user profile.</p>
75 */
76 static final String CREATE = "create";
77
78
79 /***
80 * <p>Managed bean name under which the business logic bean instance
81 * for this dialog is stored.</p>
82 */
83 static final String LOGIC_BEAN = "profile$logic";
84
85
86 /***
87 * <p>Name of the HTTP cookie in which we store "remember me" credentials.</p>
88 */
89 static final String COOKIE_NAME = "remember_me";
90
91
92 /***
93 * <p>Logical outcome indicating an unauthenticated user.</p>
94 */
95 static final String UNAUTHENTICATED = "unauthenticated";
96
97
98
99
100
101 /***
102 * <p>Flag indicating that "remember me" cookies are enabled.</p>
103 */
104 private boolean rememberMe = false;
105 public boolean isRememberMe() { return this.rememberMe; }
106 public void setRememberMe(boolean rememberMe) { this.rememberMe = rememberMe; }
107
108
109 /***
110 * <p>Session scope attribute under which a {@link User} instance for the
111 * currently logged in user is stored.</p>
112 */
113 private String userKey = "user";
114 public String getUserKey() { return this.userKey; }
115 public void setUserKey(String userKey) { this.userKey = userKey; }
116
117
118
119
120
121 /***
122 * <p>Password entered by the user.</p>
123 */
124 private String password = null;
125 public String getPassword() { return this.password; }
126 public void setPassword(String password) { this.password = password; }
127
128
129 /***
130 * <p>Flag indicating that the user wishes to have a "remember me"
131 * cookie created this time.</p>
132 */
133 private boolean remember = false;
134 public boolean isRemember() { return this.remember; }
135 public void setRemember(boolean remember) { this.remember = remember; }
136
137
138 /***
139 * <p>Username entered by the user.</p>
140 */
141 private String username = null;
142 public String getUsername() { return this.username; }
143 public void setUsername(String username) { this.username = username; }
144
145
146
147
148
149 /***
150 * <p>Skip the logon dialog if an appropriate "remember me" cookie
151 * is discovered, and this facility is enabled.</p>
152 *
153 * <p>The following logical outcome values are returned:</p>
154 * <ul>
155 * <li><code>AUTHENTICATED</code> - User has been authenticated.</li>
156 * <li><code>UNAUTHENTICATED</code> - User has not been authenticated
157 * (no cookie, "remember me" not supported).</li>
158 * </ul>
159 */
160 public String check() {
161
162
163 if (!isRememberMe()) {
164 return UNAUTHENTICATED;
165 }
166
167
168 FacesContext context = getFacesContext();
169 Map map = context.getExternalContext().getRequestCookieMap();
170 Cookie cookie = (Cookie) map.get(COOKIE_NAME);
171 if (cookie == null) {
172 return UNAUTHENTICATED;
173 }
174
175
176 int id = 0;
177 try {
178 id = Integer.parseInt(cookie.getValue());
179 } catch (NumberFormatException e) {
180 return UNAUTHENTICATED;
181 }
182
183
184 LogonLogic logic = (LogonLogic) getBean(LOGIC_BEAN);
185 User user = logic.findUser(id);
186 if (user == null) {
187 return UNAUTHENTICATED;
188 }
189
190
191 register(user);
192 return AUTHENTICATED;
193
194 }
195
196
197 /***
198 * <p>Request creation of a new user profile.</p>
199 */
200 public String create() {
201
202
203
204
205
206 return CREATE;
207
208 }
209
210
211 /***
212 * <p>Alternate exit action for this dialog. Remove the currently
213 * logged on user (if any), remove this instance from session scope,
214 * and return outcome <code>unauthenticated</code>.</p>
215 */
216 public String logoff() {
217
218 unregister();
219 return UNAUTHENTICATED;
220
221 }
222
223
224 /***
225 * <p>Authenticate the entered username and password.</p>
226 */
227 public String logon() {
228
229
230 LogonLogic logic = (LogonLogic) getBean(LOGIC_BEAN);
231 User user = logic.authenticate(username, password);
232 if (user != null) {
233 if (user.isConfirmed()) {
234
235 register(user);
236 if (isRememberMe()) {
237 if (isRemember()) {
238 remember(user);
239 } else {
240 forget(user);
241 }
242 }
243 return AUTHENTICATED;
244 } else {
245
246 error(messages.getMessage("profile.unconfirmed"));
247 return UNAUTHENTICATED;
248 }
249 }
250
251
252 error(messages.getMessage("profile.incorrect"));
253 return null;
254
255 }
256
257
258
259
260
261 /***
262 * <p>Remove any existing "remember me" cookie that was included.</p>
263 *
264 * @param user {@link User} to be forgotten
265 */
266 private void forget(User user) {
267
268 FacesContext context = getFacesContext();
269 HttpServletRequest request =
270 (HttpServletRequest) context.getExternalContext().getRequest();
271 Cookie cookie =
272 new Cookie(COOKIE_NAME, "");
273 cookie.setDomain(request.getServerName());
274 cookie.setMaxAge(0);
275 cookie.setPath(request.getContextPath());
276 HttpServletResponse response =
277 (HttpServletResponse) context.getExternalContext().getResponse();
278 response.addCookie(cookie);
279
280 }
281
282
283 /***
284 * <p>Store the specified {@link User} in session scope, and take whatever
285 * other actions are necessary to mark the user as being logged on.</p>
286 *
287 * @param user {@link User} who is to be logged on
288 */
289 private void register(User user) {
290
291
292 FacesContext context = getFacesContext();
293 context.getExternalContext().getSessionMap().
294 put(getUserKey(), user);
295
296 }
297
298
299 /***
300 * <p>Add a "remember me" cookie to the current response.</p>
301 *
302 * @param user {@link User} whose identity is to be persisted
303 */
304 private void remember(User user) {
305
306 FacesContext context = getFacesContext();
307 HttpServletRequest request =
308 (HttpServletRequest) context.getExternalContext().getRequest();
309 Cookie cookie =
310 new Cookie(COOKIE_NAME, "" + user.getId());
311
312 cookie.setMaxAge(60 * 60 * 24 * 365);
313 cookie.setPath(request.getContextPath());
314 HttpServletResponse response =
315 (HttpServletResponse) context.getExternalContext().getResponse();
316 response.addCookie(cookie);
317
318 }
319
320
321 /***
322 * <p>Remove registration of the currently logged in user, as needed.</p>
323 */
324 private void unregister() {
325
326
327 getFacesContext().getExternalContext().getSessionMap().
328 remove(getUserKey());
329
330 }
331
332
333 }