001: /*
002: * NEMESIS-FORUM.
003: * Copyright (C) 2002 David Laurent(lithium2@free.fr). All rights reserved.
004: *
005: * Copyright (c) 2000 The Apache Software Foundation. All rights reserved.
006: *
007: * Copyright (C) 2001 Yasna.com. All rights reserved.
008: *
009: * Copyright (C) 2000 CoolServlets.com. All rights reserved.
010: *
011: * NEMESIS-FORUM. is free software; you can redistribute it and/or
012: * modify it under the terms of the Apache Software License, Version 1.1,
013: * or (at your option) any later version.
014: *
015: * NEMESIS-FORUM core framework, NEMESIS-FORUM backoffice, NEMESIS-FORUM frontoffice
016: * application are parts of NEMESIS-FORUM and are distributed under
017: * same terms of licence.
018: *
019: *
020: * NEMESIS-FORUM includes software developed by the Apache Software Foundation (http://www.apache.org/)
021: * and software developed by CoolServlets.com (http://www.coolservlets.com).
022: * and software developed by Yasna.com (http://www.yasna.com).
023: *
024: */
025: package org.nemesis.forum.webapp.front;
026:
027: import java.text.SimpleDateFormat;
028: import java.util.Date;
029:
030: import javax.servlet.http.Cookie;
031: import javax.servlet.http.HttpServletRequest;
032: import javax.servlet.http.HttpServletResponse;
033: import javax.servlet.http.HttpSession;
034:
035: import org.nemesis.forum.Authorization;
036: import org.nemesis.forum.AuthorizationFactory;
037: import org.nemesis.forum.Message;
038: import org.nemesis.forum.exception.NotFoundException;
039: import org.nemesis.forum.exception.UnauthorizedException;
040: import org.nemesis.forum.util.CookieManager;
041: import org.nemesis.forum.util.StringUtils;
042:
043: /**
044: * @author dlaurent
045: */
046: public class Tools {
047: /** Name of the authentication token (is stored in the user's session) */
048: public static final String AUTH_TOKEN = "_Authorization_";
049:
050: /** Name of the cookie used to store user info for auto-login purposes */
051: public static final String AUTOLOGIN_COOKIE = "_AutoLogin_";
052:
053: /** Name of the last visited token (is stored in the user's session) */
054: public static final String LASTVISITED_TOKEN = "_LastVisited_";
055:
056: /** Name of the cookie used to store last visited timestamp */
057: public static final String LASTVISITED_COOKIE = "_LastVisited_";
058:
059: /**
060: * Returns an Authorization token for the user. The following steps are
061: * performed to determine the token:<ol>
062: *
063: * <li>Check the session for the existence of a authorization token.
064: * If one is found, it is returned as we assume that the user has logged
065: * in and is authorized.
066: * <li>Check the authorization cookie for a username and password. If found,
067: * attempt to create a authorization token using that data. If
068: * successful, save the token to the session and return it.
069: * NOTE: This check can be skipped by setting
070: * <code>checkCookie</code> to false.
071: * </ol><p>
072: *
073: * @param request the HttpServletRequest object, known as "request" in a
074: * JSP page.
075: * @param response the HttpServletResponse object, known as "response" in
076: * a JSP page.
077: * @param checkCookie a boolean that indicates whether or not we want
078: * to use a cookie for authorization.
079: * @return the authorization token if authenticated, otherwise
080: * <code>null</code>.
081: * @see Authorization
082: */
083: public static Authorization getUserAuthorization(
084: HttpServletRequest request, HttpServletResponse response,
085: boolean checkCookie) {
086: // we can get the session object from the request object:
087: HttpSession session = request.getSession();
088:
089: // Check 1: check for the authentication token in the user's session.
090: Authorization authToken = (Authorization) session
091: .getAttribute(AUTH_TOKEN);
092: if (authToken != null) {
093: return authToken;
094: }
095:
096: // Check 2: check the cookie for username and password, if we're allowing that
097: if (checkCookie) {
098: Cookie cookie = CookieManager.getCookie(request,
099: AUTOLOGIN_COOKIE);
100: try {
101: if (cookie != null) {
102: // at this point, we found a cookie so grab the username & password
103: // from it, create an authorization token and store that in the session
104: String[] values = CookieManager
105: .decodePasswordCookie(cookie.getValue());
106: String username = values[0];
107: String password = values[1];
108: // try to validate the user based on the info from the cookie
109: authToken = AuthorizationFactory.getAuthorization(
110: username, password);
111:
112: // put that token in the user's session:
113: session.setAttribute(AUTH_TOKEN, authToken);
114:
115: // return the authorization token
116: return authToken;
117: }
118: } catch (Exception e) {
119: //We want any exceptions in this block to be caught so that an
120: //anonymous authorization token can be returned. The
121: //getAuthorzation(username,password) method above throws an
122: //UnauthorizedException. In the case of this exception or others,
123: //the cookie holds invalid login info, so we should remove it:
124: CookieManager.setCookie(response, AUTOLOGIN_COOKIE,
125: null, 0);
126: }
127: }
128:
129: //Got this far, so return null.
130: return null;
131: }
132:
133: /**
134: * Returns an Authorization token for the user. This is a convenience method
135: * that that calls the other getUserAuthorization method with
136: * <code>checkCookie</code> set to true.
137: *
138: * @param request the HttpServletRequest object, known as "request" in a
139: * JSP page.
140: * @param response The HttpServletResponse object, known as "response" in
141: * a JSP page.
142: * @return The authorization token if authenticated, otherwise
143: * <code>null</code>.
144: */
145: public static Authorization getUserAuthorization(
146: HttpServletRequest request, HttpServletResponse response) {
147: return getUserAuthorization(request, response, true);
148: }
149:
150: /**
151: * Validates the user and optionally enables auto-login by creating an
152: * auto-login cookie.
153: *
154: * @param request the HttpServletRequest object, known as "request" in a JSP page.
155: * @param response the HttpServletResponse object, known as "response" in a JSP page.
156: * @param username the username.
157: * @param password the password.
158: * @param autoLogin if <code>true</code> create a cookie that enables auto-login.
159: * @throws UserNotFoundException
160: * @throws UnauthorizedException
161: * @return The authorization token if authenticated, otherwise
162: * <code>null</code>
163: */
164: public static Authorization setUserAuthorization(
165: HttpServletRequest request, HttpServletResponse response,
166: String username, String password, boolean autoLogin)
167: throws NotFoundException, UnauthorizedException {
168: HttpSession session = request.getSession();
169: Authorization authToken = AuthorizationFactory
170: .getAuthorization(username, password);
171: session.setAttribute(AUTH_TOKEN, authToken);
172:
173: if (autoLogin) {
174: CookieManager.setCookie(response, AUTOLOGIN_COOKIE,
175: CookieManager.encodePasswordCookie(username,
176: password), CookieManager.MAX_COOKIE_AGE);
177: }
178:
179: return authToken;
180: }
181:
182: /**
183: * Invalidates the cookie that otherwise lets a user auto-login.
184: *
185: * @param request The HttpServletRequest object, known as "request" in a JSP page.
186: * @param response The HttpServletResponse object, known as "response" in a JSP page.
187: */
188: public static void removeUserAuthorization(
189: HttpServletRequest request, HttpServletResponse response) {
190: HttpSession session = request.getSession();
191: session.removeAttribute(AUTH_TOKEN);
192:
193: CookieManager.setCookie(response, AUTOLOGIN_COOKIE, null, 0);
194:
195: }
196:
197: /**
198: * Returns the time in milliseconds that the user last visited the system.
199: *
200: * @param request the HttpServletRequest object, known as "request" on a JSP page.
201: * @param response the HttpServletRequest object, known as "response" on a JSP page.
202: * @param updateLastVisitedTime Set to <code>true</code> if you wish to update
203: * the user's last visited time to the current time; set to <code>false</code> otherwise.
204: * @return The time (in milliseconds) that the suer last visited .
205: */
206: public static long getLastVisited(HttpServletRequest request,
207: HttpServletResponse response, boolean updateLastVisitedTime) {
208: //Get session object
209: HttpSession session = request.getSession();
210:
211: //The current instant in time.
212: long now = System.currentTimeMillis();
213:
214: //First, try to retrieve the value from the session
215: String lastTime = (String) session
216: .getAttribute(LASTVISITED_TOKEN);
217:
218: //Found a value in the session, so return it
219: if (lastTime != null) {
220: try {
221: long time = Long.parseLong(lastTime);
222: // update the last visited time to now, but don't update the
223: // last visited time in the session:
224: CookieManager.setCookie(response, LASTVISITED_TOKEN,
225: Long.toString(now),
226: CookieManager.MAX_COOKIE_AGE);
227: // return the time value
228: return time;
229: } catch (NumberFormatException e) {
230: //log.error("",e);
231: }
232: }
233:
234: // getting to this point means no time value was found in the session,
235: // so look for it in the cookie:
236: long time = now;
237: lastTime = CookieManager.getCookieValue(request,
238: LASTVISITED_TOKEN);
239: if (lastTime != null) {
240: try {
241: time = Long.parseLong(lastTime);
242: } catch (NumberFormatException e) {
243: }
244: }
245:
246: // set the value in the cookie, return the time
247:
248: session.setAttribute(LASTVISITED_TOKEN, Long.toString(time));
249: CookieManager.setCookie(response, LASTVISITED_TOKEN, Long
250: .toString(now), CookieManager.MAX_COOKIE_AGE);
251:
252: return time;
253: }
254:
255: /**
256: * Returns the time in milliseconds that the user last visited .
257: *
258: * @param request the HttpServletRequest object, known as "request" on a JSP page.
259: * @param response the HttpServletRequest object, known as "response" on a JSP page.
260: * @return The time (in milliseconds) that the suer last visited .
261: */
262: public static long getLastVisited(HttpServletRequest request,
263: HttpServletResponse response) {
264: return getLastVisited(request, response, true);
265: }
266:
267: private static final long SECOND = 1000;
268: private static final long MINUTE = 60 * SECOND;
269: private static final long HOUR = 60 * MINUTE;
270: private static final long DAY = 24 * HOUR;
271: private static final long WEEK = 7 * DAY;
272: // Days of the week
273: private static final String[] DAYS_OF_WEEK = { "Sunday", "Monday",
274: "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
275:
276: // SimpleDateFormat objects for use in the dateToText method
277: private static final SimpleDateFormat dateFormatter = new SimpleDateFormat(
278: "EEEE, MMM d 'at' h:mm a");
279: private static final SimpleDateFormat yesterdayFormatter = new SimpleDateFormat(
280: "'Yesterday at' h:mm a");
281:
282: /**
283: * Returns a String describing the amount of time between now (current
284: * system time) and the passed in date time. Example output is "5 hours
285: * ago" or "Yesterday at 3:30 pm"
286: *
287: * @param date the Date to compare the current time with.
288: * @return a description of the difference in time, ie: "5 hours ago"
289: * or "Yesterday at 3:30pm"
290: */
291: public static String dateToText(Date date) {
292: if (date == null) {
293: return "";
294: }
295:
296: long delta = System.currentTimeMillis() - date.getTime();
297:
298: // within the last hour
299: if ((delta / HOUR) < 1) {
300: long minutes = (delta / MINUTE);
301: if (minutes == 0) {
302: return "Less than 1 min ago";
303: } else if (minutes == 1) {
304: return "1 minute ago";
305: } else {
306: return (minutes + " minutes ago");
307: }
308: }
309:
310: // sometime today
311: if ((delta / DAY) < 1) {
312: long hours = (delta / HOUR);
313: if (hours <= 1) {
314: return "1 hour ago";
315: } else {
316: return (hours + " hours ago");
317: }
318: }
319:
320: // within the last week
321: if ((delta / WEEK) < 1) {
322: double days = ((double) delta / (double) DAY);
323: if (days <= 1.0) {
324: return yesterdayFormatter.format(date);
325: } else {
326: return dateFormatter.format(date);
327: }
328: }
329:
330: // before a week ago
331: else {
332: return dateFormatter.format(date);
333: }
334: }
335:
336: /**
337: * Formats the unfiltered body of a message to make it appear in the "quote
338: * original" format. This is simply the body of the message with the
339: * delimiter appended to the beginning of each line. The delimiter
340: * is most often "> " by convention. A desired length for each line in the
341: * returned String can be specified to aid in formatting.<p>
342: *
343: * This method uses message.getUnfilteredBody() in order to get the body of
344: * the message. This usually yields better results for the formatting
345: * required by this method. However, it also has the potential of being
346: * a security risk if malicious HTML code is embedded in the body. Therefore,
347: * you should always filter HTML from the result of this method before
348: * showing it in an environment where HTML is interpreted. If you are
349: * showing the results of this method in an HTML <textarea>, there is
350: * no need to worry about malicious HTML.
351: *
352: * @param message the message to quote.
353: * @param delimiter a String that will start each line of the quoted
354: * message. For example, "> ";
355: * @param lineLength the desired length of each line in the quoted message.
356: * @return the unfiltered body of the message in the "quote original" format.
357: */
358: public static String quoteOriginal(String body, String delimiter,
359: int lineLength) {
360: if (body == null || body.length() == 0) {
361: return "";
362: }
363: int length = body.length();
364: //Create a StringBuffer to hold the quoted body; approximate size.
365: StringBuffer buf = new StringBuffer(body.length());
366: //i maintains the current position in the String.
367: for (int i = 0; i < length;) {
368: String partialString = StringUtils.chopAtWord(body
369: .substring(i), lineLength);
370:
371: i += partialString.length() + 1;
372: buf.append(delimiter).append(partialString.trim()).append(
373: "\\n");
374: }
375: return buf.toString();
376: }
377:
378: /**
379: * Returns true if the message has been created or updated since
380: * the last time the user visisted.
381: *
382: * @param message the message to check.
383: * @param lastVisted the time the user last visisted the forum.
384: * @return true if the message has been created or updated since the user's
385: * last visit.
386: */
387: public static boolean isNewMessage(Message message, long lastVisited) {
388: if (message.getModifiedDate().getTime() > lastVisited) {
389: return true;
390: } else {
391: return false;
392: }
393: }
394:
395: }
|