View Javadoc

1   /*
2    * This software was designed and created by Jason Carroll.
3    * Copyright (c) 2002, 2003, 2004 Jason Carroll.
4    * The author can be reached at jcarroll@cowsultants.com
5    * ITracker website: http://www.cowsultants.com
6    * ITracker forums: http://www.cowsultants.com/phpBB/index.php
7    *
8    * This program is free software; you can redistribute it and/or modify
9    * it only under the terms of the GNU General Public License as published by
10   * the Free Software Foundation; either version 2 of the License, or
11   * (at your option) any later version.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.
17   */
18  
19  package org.itracker.web.util;
20  
21  import java.util.Enumeration;
22  import java.util.Locale;
23  import java.util.Map;
24  import java.util.ResourceBundle;
25  import java.util.Set;
26  
27  import javax.servlet.http.Cookie;
28  import javax.servlet.http.HttpServletRequest;
29  import javax.servlet.http.HttpServletResponse;
30  import javax.servlet.http.HttpSession;
31  
32  import org.apache.log4j.Logger;
33  import org.itracker.core.resources.ITrackerResources;
34  import org.itracker.model.PermissionType;
35  import org.itracker.model.User;
36  import org.itracker.model.UserPreferences;
37  import org.itracker.services.UserService;
38  import org.itracker.services.util.AuthenticationConstants;
39  
40  public class LoginUtilities {
41  
42  	private static final Logger logger = Logger.getLogger(LoginUtilities.class);
43  	private static final int DEFAULT_SESSION_TIMEOUT = 30;
44  
45  	public static boolean checkAutoLogin(HttpServletRequest request,
46  			boolean allowSaveLogin) {
47  		boolean foundLogin = false;
48  
49  		if (request != null) {
50  			int authType = getRequestAuthType(request);
51  
52  			// Check for auto login in request
53  			if (!foundLogin) {
54  				if (authType == AuthenticationConstants.AUTH_TYPE_REQUEST) {
55  					String redirectURL = request.getRequestURI().substring(
56  							request.getContextPath().length())
57  							+ (request.getQueryString() != null ? "?"
58  									+ request.getQueryString() : "");
59  					request.setAttribute(Constants.AUTH_TYPE_KEY,
60  							AuthenticationConstants.AUTH_TYPE_REQUEST);
61  					request.setAttribute(Constants.AUTH_REDIRECT_KEY,
62  							redirectURL);
63  					request.setAttribute("processLogin", "true");
64  					foundLogin = true;
65  				}
66  			}
67  
68  			// Add in check for client certs
69  
70  			// Check for auto login with cookies, this will only happen if users
71  			// are allowed to save
72  			// their logins to cookies
73  			if (allowSaveLogin && !foundLogin) {
74  				Cookie[] cookies = request.getCookies();
75  				if (cookies != null) {
76  					for (int i = 0; i < cookies.length; i++) {
77  						if (Constants.COOKIE_NAME.equals(cookies[i].getName())) {
78  							int seperator = cookies[i].getValue().indexOf('~');
79  							final String login;
80  							if (seperator > 0) {
81  								login = cookies[i].getValue()
82  								.substring(0,
83  										seperator);
84  								if (logger.isDebugEnabled()) {
85  									logger
86  											.debug("Attempting autologin for user "
87  													+ login
88  													+ ".");
89  								}
90  
91  								String redirectURL = request.getRequestURI()
92  										.substring(
93  												request.getContextPath()
94  														.length())
95  										+ (request.getQueryString() != null ? "?"
96  												+ request.getQueryString()
97  												: "");
98  								request.setAttribute(Constants.AUTH_LOGIN_KEY,
99  										cookies[i].getValue().substring(0,
100 												seperator));
101 								request.setAttribute(Constants.AUTH_TYPE_KEY,
102 								AuthenticationConstants.AUTH_TYPE_PASSWORD_ENC);
103 								
104 								request.setAttribute(Constants.AUTH_VALUE_KEY,
105 										cookies[i].getValue().substring(
106 												seperator + 1));
107 								request.setAttribute(
108 										Constants.AUTH_REDIRECT_KEY,
109 										redirectURL);
110 								request.setAttribute("processLogin", "true");
111 								foundLogin = true;
112 							}
113 						}
114 					}
115 				}
116 			}
117 
118 		}
119 
120 		return foundLogin;
121 	}
122 
123 	public static int getRequestAuthType(HttpServletRequest request) {
124 		int authType = AuthenticationConstants.AUTH_TYPE_UNKNOWN;
125 
126 		try {
127 			if (request.getAttribute(Constants.AUTH_TYPE_KEY) != null) {
128 				authType = ((Integer) request
129 						.getAttribute(Constants.AUTH_TYPE_KEY)).intValue();
130 			}
131 			if (request.getParameter(Constants.AUTH_TYPE_KEY) != null) {
132 				authType = Integer.valueOf(request
133 						.getParameter(Constants.AUTH_TYPE_KEY));
134 			}
135 		} catch (Exception e) {
136 			logger
137 					.debug("Error retrieving auth type while checking auto login.  "
138 							+ e.getMessage());
139 		}
140 
141 		return authType;
142 	}
143 
144 	/**
145 	 * Get a locale from request
146 	 * 
147 	 * <p>
148 	 * TODO the order of retrieving locale from request should be:
149 	 * <ol>
150 	 * <li>request-attribute Constants.LOCALE_KEY</li>
151 	 * <li>request-param 'loc'</li>
152 	 * <li>session attribute <code>Constants.LOCALE_KEY</code></li>
153 	 * <li>cookie 'loc'</li>
154 	 * <li>request.getLocale()/request.getLocales()</li>
155 	 * <li>ITrackerResources.DEFAULT_LOCALE</li>
156 	 * </ol>
157 	 * </p>
158 	 * 
159 	 * @param request
160 	 * @return
161 	 */
162 	@SuppressWarnings("unchecked")
163 	public static Locale getCurrentLocale(HttpServletRequest request) {
164 		Locale requestLocale = null;
165 		HttpSession session = request.getSession(true);
166 		try {
167 
168 			requestLocale = (Locale) request.getAttribute(Constants.LOCALE_KEY);
169 
170 //			if (logger.isDebugEnabled()) {
171 //				logger.debug("getCurrentLocale: request-attribute was "
172 //						+ requestLocale);
173 //			}
174 
175 			if (null == requestLocale) {
176 				// get locale from request param
177 				String loc = request
178 				.getParameter("loc");
179 				if (null != loc && loc.trim().length() > 1) {
180 					requestLocale = ITrackerResources.getLocale(loc);
181 				}
182 //				if (logger.isDebugEnabled()) {
183 //					logger.debug("getCurrentLocale: request-parameter was "
184 //							+ loc);
185 //				}
186 			}
187 
188 			if (null == requestLocale) {
189 				// get it from the session
190 				requestLocale = (Locale) session
191 						.getAttribute(Constants.LOCALE_KEY);
192 //				if (logger.isDebugEnabled()) {
193 //					logger.debug("getCurrentLocale: session-attribute was "
194 //							+ requestLocale);
195 //				}
196 			}
197 
198 			if (null == requestLocale) {
199 				ResourceBundle bundle = ITrackerResources.getBundle(request
200 						.getLocale());
201 //				if (logger.isDebugEnabled()) {
202 //					logger
203 //							.debug("getCurrentLocale: trying request header locale "
204 //									+ request.getLocale());
205 //				}
206 				if (bundle.getLocale().getLanguage().equals(
207 						request.getLocale().getLanguage())) {
208 					requestLocale = request.getLocale();
209 //					if (logger.isDebugEnabled()) {
210 //						logger.debug("getCurrentLocale: request-locale was "
211 //								+ requestLocale);
212 //					}
213 				}
214 			}
215 
216 			// is there no way to detect supported locales of current
217 			// installation?
218 
219 			if (null == requestLocale) {
220 				Enumeration<Locale> locales = (Enumeration<Locale>) request.getLocales();
221 				ResourceBundle bundle;
222 				Locale locale;
223 				while (locales.hasMoreElements()) {
224 					locale = (Locale) locales.nextElement();
225 					bundle = ITrackerResources.getBundle(locale);
226 //					if (logger.isDebugEnabled()) {
227 //						logger
228 //								.debug("getCurrentLocale: request-locales prcessing "
229 //										+ locale + ", bundle: " + bundle);
230 //					}
231 					if (bundle.getLocale().getLanguage().equals(
232 							locale.getLanguage())) {
233 						requestLocale = locale;
234 //						if (logger.isDebugEnabled()) {
235 //							logger
236 //									.debug("getCurrentLocale: request-locales locale was "
237 //											+ requestLocale);
238 //						}
239 					}
240 				}
241 			}
242 
243 		} finally {
244 			if (null == requestLocale) {
245 				// fall back to default locale
246 				requestLocale = ITrackerResources.getLocale();
247 //				if (logger.isDebugEnabled()) {
248 //					logger
249 //							.debug("getCurrentLocale: fallback default locale was "
250 //									+ requestLocale);
251 //				}
252 			}
253 			session.setAttribute(Constants.LOCALE_KEY, requestLocale);
254 			request.setAttribute(Constants.LOCALE_KEY, requestLocale);
255 			request.setAttribute("currLocale", requestLocale);
256 //			if (logger.isDebugEnabled()) {
257 //				logger
258 //						.debug("getCurrentLocale: request and session was setup with "
259 //								+ requestLocale);
260 //			}
261 		}
262 
263 		return requestLocale;
264 	}
265 
266 	/**
267 	 * get current user from request-attribute currUser, if not set from request-session
268 	 * 
269 	 * @param request
270 	 * @return current user or null if unauthenticated
271 	 * @throws NullPointerException
272 	 *             if the request was null
273 	 */
274 	public static final User getCurrentUser(HttpServletRequest request) {
275 
276 		User currUser = (User) request.getAttribute("currUser");
277 		if (null == currUser) {
278 			currUser = (User) request.getSession().getAttribute("currUser");
279 		}
280 		
281 
282 		
283 //		try {
284 //			ITrackerServices iTrackerServices = ServletContextUtils.getItrackerServices();
285 //			// autologin
286 //			if (null == currUser && 
287 //					checkAutoLogin(request, iTrackerServices.getConfigurationService().getBooleanProperty(
288 //					"allow_save_login", true))) {			
289 //				if (Boolean.valueOf(String.valueOf(request.getAttribute("processLogin")))) {
290 //					currUser = LoginUtilities.processAutoLogin(request, iTrackerServices);
291 //				}
292 //			}
293 //		} catch (Exception e) {
294 //			currUser = null;
295 //			if (logger.isInfoEnabled()) {
296 //				logger.info("getCurrentUser: could not authenticate from request.");
297 //				if (logger.isDebugEnabled()) {
298 //					logger.debug("getCurrentUser: exception caught", e);
299 //				}
300 //			}
301 //		}
302 		return currUser;
303 	}
304 //	public static final User processAutoLogin(HttpServletRequest request, ITrackerServices iTrackerServices) {
305 //		
306 //		UserService userService = iTrackerServices.getUserService();
307 //		final int authType = LoginUtilities.getRequestAuthType(request);
308 //		final User user;
309 //		final String login;
310 //		if (authType == AuthenticationConstants.AUTH_TYPE_PASSWORD_ENC) {
311 //			login = (String) request
312 //					.getAttribute(Constants.AUTH_LOGIN_KEY);
313 //			String authenticator = (String) request
314 //					.getAttribute(Constants.AUTH_VALUE_KEY);
315 //
316 //			logger
317 //					.debug("Attempting login with encrypted password for user "
318 //							+ login);
319 //			user = userService.checkLogin(login, authenticator,
320 //					AuthenticationConstants.AUTH_TYPE_PASSWORD_ENC,
321 //					AuthenticationConstants.REQ_SOURCE_WEB);
322 //			if (user != null) {
323 //				return user;
324 //			}
325 //		}
326 //
327 //		throw new AuthenticatorException(
328 //				AuthenticatorException.UNKNOWN_USER);
329 //		
330 //	}
331 	public static final Boolean allowSaveLogin(HttpServletRequest request) {
332 		return Boolean.valueOf((String)request.getAttribute("allowSaveLogin"));
333 	}
334 	
335 	public static User setupSession(String login, HttpServletRequest request,
336 			HttpServletResponse response) {
337 		if (null == login) {
338 			logger.warn("setupSession: null login", (logger.isDebugEnabled()? new RuntimeException(): null));
339 			throw new IllegalArgumentException("null login");
340 		}
341 		UserService userService = ServletContextUtils.getItrackerServices().getUserService();
342 		User user = userService.getUserByLogin(login);
343 		if (user != null) {
344 			String encPassword = null;
345 			Cookie[] cookies = request.getCookies();
346 			if (cookies != null) {
347 				for (int i = 0; i < cookies.length; i++) {
348 					if (Constants.COOKIE_NAME.equals(cookies[i].getName())) {
349 						int seperator = cookies[i].getValue().indexOf('~');
350 						if (seperator > 0) {
351 							encPassword = cookies[i].getValue().substring(
352 									seperator + 1);
353 						}
354 					}
355 				}
356 			}
357 
358 			return setupSession(user, encPassword, request, response);
359 		}
360 		return null;
361 	}
362 
363 	public static User setupSession(User user, String encPassword,
364 			HttpServletRequest request, HttpServletResponse response) {
365 		if (user == null) {
366 			logger.warn("setupSession: null user", (logger.isDebugEnabled()? new RuntimeException(): null));
367 			throw new IllegalArgumentException("null user");
368 		}
369 
370 		UserService userService = ServletContextUtils.getItrackerServices().getUserService();
371 
372 		if (logger.isDebugEnabled()) {
373 			logger.debug("Creating new session");
374 		}
375 		HttpSession session = request.getSession(true);
376 
377 		if (logger.isDebugEnabled()) {
378 			logger.debug("Setting session timeout to "
379 					+ getConfiguredSessionTimeout() + " minutes");
380 		}
381 		session.setMaxInactiveInterval(getConfiguredSessionTimeout() * 60);
382 
383 		if (logger.isDebugEnabled()) {
384 			logger.debug("Setting session tracker");
385 		}
386 		session.setAttribute(Constants.SESSION_TRACKER_KEY, new SessionTracker(
387 				user.getLogin(), session.getId()));
388 
389 		if (logger.isDebugEnabled()) {
390 			logger.debug("Setting user information");
391 		}
392 		session.setAttribute(Constants.USER_KEY, user);
393 
394 		if (logger.isDebugEnabled()) {
395 			logger.debug("Setting preferences for user " + user.getLogin());
396 		}
397 		UserPreferences userPrefs = user.getPreferences();
398 		// TODO : this is a hack, remove when possible
399 		if (userPrefs == null) {
400 			logger.warn("setupSession: got user with no preferences!: " + user + " (prefs: " + user.getPreferences() + ")");
401 			userPrefs = new UserPreferences();
402 		}
403 		session.setAttribute(Constants.PREFERENCES_KEY, userPrefs);
404 
405 		if (logger.isDebugEnabled()) {
406 			logger.debug("Setting user " + user + " locale to "+ ITrackerResources
407 					.getLocale(userPrefs.getUserLocale()));
408 		}
409 		session.setAttribute(Constants.LOCALE_KEY, ITrackerResources
410 				.getLocale(userPrefs.getUserLocale()));
411 
412 		if (logger.isDebugEnabled()) {
413 			logger.debug("Setting autologin cookie for user " + user.getLogin());
414 		}
415 		Cookie cookie = new Cookie(Constants.COOKIE_NAME, "");
416 		cookie.setPath(request.getContextPath());
417 		if (userPrefs.getSaveLogin()) {
418 			if (encPassword != null) {
419 				if (logger.isDebugEnabled()) {
420 					logger.debug("User allows autologin");
421 				}
422 				cookie.setComment("ITracker autologin cookie");
423 				cookie.setValue(user.getLogin() + "~" + encPassword);
424 				cookie.setMaxAge(30 * 24 * 60 * 60);
425 			}
426 		} else {
427 			if (logger.isDebugEnabled()) {
428 				logger.debug("User does not allow autologin");
429 			}
430 			cookie.setValue("");
431 			cookie.setMaxAge(0);
432 		}
433 		response.addCookie(cookie);
434 
435 		if (logger.isDebugEnabled()) {
436 			logger.debug("Setting permissions for user " + user.getLogin());
437 		}
438 		Map<Integer, Set<PermissionType>> usersMapOfProjectIdsAndSetOfPermissionTypes = userService
439 				.getUsersMapOfProjectIdsAndSetOfPermissionTypes(user,
440 						AuthenticationConstants.REQ_SOURCE_WEB);
441 		session.setAttribute(Constants.PERMISSIONS_KEY,
442 				usersMapOfProjectIdsAndSetOfPermissionTypes);
443 
444 		// Reset some session forms
445 		session.setAttribute(Constants.SEARCH_QUERY_KEY, null);
446 
447 		SessionManager.clearSessionNeedsReset(user.getLogin());
448 		if (logger.isDebugEnabled()) {
449 			logger.debug("User session data updated.");
450 		}
451 		return user;
452 	}
453 
454 	public static int getConfiguredSessionTimeout() {
455 		return (ServletContextUtils.getItrackerServices().getConfigurationService()
456 				.getIntegerProperty("web_session_timeout", DEFAULT_SESSION_TIMEOUT));
457 	}
458 }