KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mvnforum > auth > OnlineUserManager


1 /*
2  * $Header: /cvsroot/mvnforum/mvnforum/src/com/mvnforum/auth/OnlineUserManager.java,v 1.44 2006/04/14 17:05:26 minhnn Exp $
3  * $Author: minhnn $
4  * $Revision: 1.44 $
5  * $Date: 2006/04/14 17:05:26 $
6  *
7  * ====================================================================
8  *
9  * Copyright (C) 2002-2006 by MyVietnam.net
10  *
11  * All copyright notices regarding mvnForum MUST remain
12  * intact in the scripts and in the outputted HTML.
13  * The "powered by" text/logo with a link back to
14  * http://www.mvnForum.com and http://www.MyVietnam.net in
15  * the footer of the pages MUST remain visible when the pages
16  * are viewed on the internet or intranet.
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2 of the License, or
21  * any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31  *
32  * Support can be obtained from support forums at:
33  * http://www.mvnForum.com/mvnforum/index
34  *
35  * Correspondence and Marketing Questions can be sent to:
36  * info at MyVietnam net
37  *
38  * @author: Minh Nguyen
39  * @author: Mai Nguyen
40  */

41 package com.mvnforum.auth;
42
43 import java.sql.Timestamp JavaDoc;
44 import java.util.*;
45
46 import javax.servlet.http.*;
47
48 import com.mvnforum.*;
49 import com.mvnforum.db.DAOFactory;
50 import net.myvietnam.mvncore.exception.*;
51 import net.myvietnam.mvncore.security.Encoder;
52 import net.myvietnam.mvncore.security.FloodControl;
53 import net.myvietnam.mvncore.util.*;
54 import net.myvietnam.mvncore.web.GenericRequest;
55 import net.myvietnam.mvncore.web.GenericResponse;
56 import net.myvietnam.mvncore.web.impl.GenericRequestServletImpl;
57 import net.myvietnam.mvncore.web.impl.GenericResponseServletImpl;
58
59 public class OnlineUserManager {
60     private static final int REMOVE_INTERVAL = 2000; //update every 2 second
61

62     private static final String JavaDoc MVNFORUM_SESSION_USERNAME = "mvnforum.membername";
63     private static final String JavaDoc MVNFORUM_SESSION_PASSWORD = "mvnforum.encodedpassword";
64
65     private static final String JavaDoc MVNFORUM_COOKIE_USERNAME = "mvnforum.membername";
66     private static final String JavaDoc MVNFORUM_COOKIE_PASSWORD = "mvnforum.encodedpassword";
67
68     private static final String JavaDoc MVNFORUM_COOKIE_PATH = "/";
69
70     public static final String JavaDoc PASSWORD_OF_METHOD_REALM = "Realm"; //must not be changed in all cases
71
public static final String JavaDoc PASSWORD_OF_METHOD_CUSTOMIZATION = "Remote";//must not be changed in all cases
72

73     //static variable
74
private static OnlineUserManager instance = new OnlineUserManager();
75
76     //instance variable
77
private Map userMap = new TreeMap();
78     private long timeOfLastRemoveAction = 0;
79     private transient Vector onlineUserListeners;
80
81     private Authenticator authenticator = null;
82
83     private OnlineUserManager() {
84     }
85
86     public static OnlineUserManager getInstance() {
87         return instance;
88     }
89
90     public Authenticator getAuthenticator() {
91         return authenticator;
92     }
93
94     public void setAuthenticator(Authenticator authenticator) {
95         this.authenticator = authenticator;
96     }
97
98     /**
99      * MemberUtil method to be called from Processor.
100      * It assumes that to input parameters are
101      * MemberName for username
102      * MemberMatkhau for password
103      */

104     public void processLogin(HttpServletRequest request, HttpServletResponse response)
105         throws AuthenticationException, AssertionException, DatabaseException, BadInputException, FloodException {
106
107         String JavaDoc memberName = ParamUtil.getParameter(request, "MemberName", true);
108         StringUtil.checkGoodName(memberName);// check for better security
109
String JavaDoc memberPassword = "";
110         String JavaDoc memberPasswordMD5 = ParamUtil.getParameter(request, "md5pw", false);
111         if (memberPasswordMD5.length() == 0 || (memberPasswordMD5.endsWith("==") == false)) {
112             // md5 is not valid, try to use unencoded password method
113
memberPassword = ParamUtil.getParameterPassword(request, "MemberMatkhau", 3, 0);
114
115             if (memberPassword.length() == 0) {
116                 throw new AssertionException("Cannot allow memberPassword's length is 0. Serious Assertion Failed.");
117             }
118         }
119
120         processLogin(request, response, memberName, memberPassword, memberPasswordMD5);
121         /*
122         String currentIP = request.getRemoteAddr();
123         try {
124             // Control the login action, we dont want user to try too many login attempt
125             FloodControl.ensureNotReachMaximum(MVNForumGlobal.FLOOD_ID_LOGIN, currentIP);
126
127             OnlineUser user = null;
128             if (memberPassword.length() > 0) {
129                 // that is we cannot find the md5 password
130                 user = login(request, response, memberName, memberPassword, false);
131             } else {
132                 // have the md5, go ahead
133                 user = login(request, response, memberName, memberPasswordMD5, true);
134             }
135             ((OnlineUserImpl)user).setAuthenticationType(OnlineUser.AUTHENTICATION_TYPE_HTML_FORM);
136         } catch (AuthenticationException ex) {
137             // only increase login count if unsucessful
138             FloodControl.increaseCount(MVNForumGlobal.FLOOD_ID_LOGIN, currentIP);
139
140             if (ex.getReason() == NotLoginException.WRONG_PASSWORD) {
141                 request.setAttribute("MemberName", memberName);// so user dont have to retype USER NAME
142             }
143             throw ex;
144         } catch (FloodException fe) {
145             Locale locale = I18nUtil.getLocaleInRequest(request);
146             Integer maxWrongLogins = new Integer(FloodControl.getActionsPerHour(MVNForumGlobal.FLOOD_ID_LOGIN));
147             //throw new FloodException("You have reached the maximum number of wrong login actions for this page. Please try this page later. This is to prevent forum from being flooded.");
148             String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.FloodException.login_too_many_times", new Object[]{ maxWrongLogins });
149             throw new FloodException(localizedMessage);
150         }*/

151     }
152
153     /**
154      * Login method, if memberPassword length == 0, then login with memberPasswordMD5
155      */

156     public void processLogin(HttpServletRequest request, HttpServletResponse response,
157                              String JavaDoc memberName, String JavaDoc memberPassword, String JavaDoc memberPasswordMD5)
158         throws AuthenticationException, AssertionException, DatabaseException, BadInputException, FloodException {
159
160         StringUtil.checkGoodName(memberName);// check for better security
161

162         String JavaDoc currentIP = request.getRemoteAddr();
163         try {
164             // Control the login action, we dont want user to try too many login attempt
165
FloodControl.ensureNotReachMaximum(MVNForumGlobal.FLOOD_ID_LOGIN, currentIP);
166
167             OnlineUser user = null;
168             if (memberPassword.length() > 0) {
169                 // that is we cannot find the md5 password
170
user = login(request, response, memberName, memberPassword, false);
171             } else {
172                 // have the md5, go ahead
173
user = login(request, response, memberName, memberPasswordMD5, true);
174             }
175             ((OnlineUserImpl)user).setAuthenticationType(OnlineUser.AUTHENTICATION_TYPE_HTML_FORM);
176         } catch (AuthenticationException ex) {
177             // only increase login count if unsucessful
178
FloodControl.increaseCount(MVNForumGlobal.FLOOD_ID_LOGIN, currentIP);
179
180             if (ex.getReason() == NotLoginException.WRONG_PASSWORD) {
181                 request.setAttribute("MemberName", memberName);// so user dont have to retype USER NAME
182
}
183             throw ex;
184         } catch (FloodException fe) {
185             Locale locale = I18nUtil.getLocaleInRequest(request);
186             Integer JavaDoc maxWrongLogins = new Integer JavaDoc(FloodControl.getActionsPerHour(MVNForumGlobal.FLOOD_ID_LOGIN));
187             //throw new FloodException("You have reached the maximum number of wrong login actions for this page. Please try this page later. This is to prevent forum from being flooded.");
188
String JavaDoc localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.FloodException.login_too_many_times", new Object JavaDoc[]{ maxWrongLogins });
189             throw new FloodException(localizedMessage);
190         }
191     }
192
193     /**
194      * NOTE: This method MUST be the only way to authenticate a user
195      * NOTE: the parameter response can be equals null
196      */

197     protected OnlineUser login(HttpServletRequest request, HttpServletResponse response,
198                                String JavaDoc memberName, String JavaDoc memberPassword, boolean passwordEncoded)
199         throws AuthenticationException, DatabaseException, AssertionException {
200
201         try {
202             StringUtil.checkGoodName(memberName);
203         } catch (Exception JavaDoc ex) {
204             throw new AuthenticationException(ex.getMessage(), NotLoginException.WRONG_NAME);
205         }
206         String JavaDoc encodedPassword;
207         OnlineUser user;
208
209         if (passwordEncoded) {
210             encodedPassword = memberPassword;
211             user = ManagerFactory.getOnlineUserFactory().getAuthenticatedUser(request, response, memberName, encodedPassword, true);
212         } else {
213             encodedPassword = ManagerFactory.getOnlineUserFactory().getEncodedPassword(memberName, memberPassword);
214             //user = ManagerFactory.getOnlineUserFactory().getAuthenticatedUser(request, response, memberName, memberPassword, false);
215
user = ManagerFactory.getOnlineUserFactory().getAuthenticatedUser(request, response, memberName, encodedPassword, true);
216         }
217
218         HttpSession session = request.getSession();
219         String JavaDoc sessionID = session.getId();
220         setOnlineUser(sessionID, user);
221
222         // now save the login info in the session only if we support
223
// encoded passwords
224
if (null != encodedPassword) {
225             session.setAttribute(MVNFORUM_SESSION_USERNAME, memberName);
226             session.setAttribute(MVNFORUM_SESSION_PASSWORD, encodedPassword);
227         }
228
229         boolean fromLoginPage = ParamUtil.getParameterBoolean(request, "FromLoginPage");
230         if ( fromLoginPage && (response != null) ) {
231             manageAutoLogin(memberName, encodedPassword, request, response);
232         }
233
234         // Now call the postLogin method, in the default implementation, the default folder
235
// is checked and created if not existed
236
ManagerFactory.getOnlineUserFactory().postLogin(request, response, user);
237
238         return user;
239     }
240
241     protected OnlineUser login(GenericRequest request, GenericResponse response,
242                                String JavaDoc memberName, String JavaDoc memberPassword, boolean passwordEncoded)
243         throws AuthenticationException, DatabaseException, AssertionException {
244
245         try {
246             StringUtil.checkGoodName(memberName);
247         } catch (Exception JavaDoc ex) {
248             throw new AuthenticationException(ex.getMessage(), NotLoginException.WRONG_NAME);
249         }
250
251         String JavaDoc encodedPassword;
252         OnlineUser user;
253
254         if (passwordEncoded) {
255             encodedPassword = memberPassword;
256             user = ManagerFactory.getOnlineUserFactory().getAuthenticatedUser(request, null, memberName, encodedPassword, true);
257
258         } else {
259             encodedPassword = ManagerFactory.getOnlineUserFactory().getEncodedPassword(memberName, memberPassword);
260             //user = ManagerFactory.getOnlineUserFactory().getAuthenticatedUser(request, response, memberName, memberPassword, false);
261
user = ManagerFactory.getOnlineUserFactory().getAuthenticatedUser(request, null, memberName, encodedPassword, true);
262         }
263
264         String JavaDoc sessionID = request.getSessionId();
265         setOnlineUser(sessionID, user);
266
267         // now save the login info in the session only if we support
268
// encoded passwords
269
/*if (null != encodedPassword) {
270             session.setAttribute(MVNFORUM_SESSION_USERNAME, memberName);
271             session.setAttribute(MVNFORUM_SESSION_PASSWORD, encodedPassword);
272         }*/

273
274         /*
275         boolean fromLoginPage = ParamUtil.getParameterBoolean(request, "FromLoginPage");
276         if ( fromLoginPage && (response != null) ) {
277             manageAutoLogin(memberName, encodedPassword, request, response);
278         }*/

279
280         // Now call the postLogin method, in the default implementation, the default folder
281
// is checked and created if not existed
282
ManagerFactory.getOnlineUserFactory().postLogin(null, null, user);
283
284         return user;
285     }
286
287     protected void manageAutoLogin(String JavaDoc memberName, String JavaDoc encodedPassword,
288                                    HttpServletRequest request, HttpServletResponse response) {
289
290         boolean autoLogin = ParamUtil.getParameterBoolean(request, "AutoLogin");
291         if (autoLogin) {
292             int autoLoginExpire = (60 * 60 * 24) * 1; // 1 day
293
try {
294                 autoLoginExpire = ParamUtil.getParameterInt(request, "AutoLoginExpire");
295             } catch (Exception JavaDoc ex) {
296                 // do nothing
297
}
298             Cookie nameCookie = new Cookie(MVNFORUM_COOKIE_USERNAME, Encoder.encodeURL(memberName));
299             nameCookie.setMaxAge(autoLoginExpire);
300             nameCookie.setPath(MVNFORUM_COOKIE_PATH);
301
302             Cookie passwordCookie = new Cookie(MVNFORUM_COOKIE_PASSWORD, encodedPassword);
303             passwordCookie.setMaxAge(autoLoginExpire);
304             passwordCookie.setPath(MVNFORUM_COOKIE_PATH);
305
306             response.addCookie(nameCookie);
307             response.addCookie(passwordCookie);
308         }
309     }
310
311     public void logout(HttpServletRequest request, HttpServletResponse response)
312         throws DatabaseException, AssertionException, AuthenticationException {
313
314         GenericRequest genericRequest = new GenericRequestServletImpl(request);
315         GenericResponse genericResponse = new GenericResponseServletImpl(response);
316
317         logout(genericRequest, genericResponse);
318     }
319
320     public void logout(GenericRequest request, GenericResponse response)
321         throws DatabaseException, AssertionException, AuthenticationException {
322
323         String JavaDoc sessionID = request.getSessionId();
324
325         OnlineUser oldUser = getOnlineUser(request);
326         String JavaDoc cssPath = oldUser.getCssPath();
327         String JavaDoc logoPath = oldUser.getLogoPath();
328
329         OnlineUser user = null;
330         if (authenticator == null) {
331             // temporary hack, if no authenticator has been set,
332
// then we use the old method
333
// @todo: more thought on this later
334
user = ManagerFactory.getOnlineUserFactory().getAnonymousUser(request);
335             user.setCssPath(cssPath);
336             user.setLogoPath(logoPath);
337         }
338
339         // remove current user, then set new user is a guest
340
setOnlineUser(sessionID, user);
341         ManagerFactory.getOnlineUserFactory().logout(request, response);
342
343         // now always clear the session information
344
request.setSessionAttribute(MVNFORUM_SESSION_USERNAME, null);
345         request.setSessionAttribute(MVNFORUM_SESSION_PASSWORD, null);
346     }
347
348     public void deleteCookie(HttpServletRequest request, HttpServletResponse response) {
349
350         Cookie nameCookie = new Cookie(MVNFORUM_COOKIE_USERNAME, "");
351         nameCookie.setPath(MVNFORUM_COOKIE_PATH);
352         nameCookie.setMaxAge(0);// delete this cookie
353

354         Cookie passwordCookie = new Cookie(MVNFORUM_COOKIE_PASSWORD, "");
355         passwordCookie.setPath(MVNFORUM_COOKIE_PATH);
356         passwordCookie.setMaxAge(0);// delete this cookie
357

358         response.addCookie(nameCookie);
359         response.addCookie(passwordCookie);
360     }
361
362     public OnlineUser getOnlineUser(GenericRequest request)
363         throws AuthenticationException, AssertionException, DatabaseException {
364
365         if (request.isServletRequest()) {
366             return getOnlineUser(request.getServletRequest());
367         }
368
369         String JavaDoc sessionID = request.getSessionId();
370         OnlineUser user = getOnlineUser(sessionID);
371
372         // When logged in as remote or customization, the remote user is logged out
373
// and mvnForum still have the old non-guest users, then we should logout this user
374
// in OnlineUser too.
375
if ( (user != null) && (user.isGuest() == false) ) {
376             if (user.getAuthenticationType() == OnlineUser.AUTHENTICATION_TYPE_REALM){
377                 String JavaDoc currentRemoteUser = request.getRemoteUser();
378                 if (currentRemoteUser == null) {
379                     logout(request, null /*response*/);
380                 } else if (currentRemoteUser.equalsIgnoreCase(user.getMemberName()) == false) {
381                     throw new AssertionException("ASSERTION: Current remote user should equals the current member in OnlineUser: Remote User: " + currentRemoteUser + ". But forum user is " + user.getMemberName() +". Please report bug to mvnForum developers.");
382                 }
383             } else if (user.getAuthenticationType() == OnlineUser.AUTHENTICATION_TYPE_CUSTOMIZATION) {
384                 String JavaDoc currentRemoteUser = StringUtil.getEmptyStringIfNull(authenticator.getRemoteUser(request));
385                 if (currentRemoteUser.equals("")) {
386                     logout(request, null /*response*/);
387                 } else if (currentRemoteUser.equalsIgnoreCase(user.getMemberName()) == false) {
388                     throw new AssertionException("ASSERTION: Current remote user should equals the current member in OnlineUser: Remote User: " + currentRemoteUser + ". But forum user is " + user.getMemberName() +". Please report bug to mvnForum developers.");
389                 }
390             }
391         }
392         // end of checking
393

394         // re-get the online user to continue
395
user = getOnlineUser(sessionID);
396
397         boolean enableLoginInfoInRealm = MVNForumConfig.getEnableLoginInfoInRealm();
398         if (user == null) {
399             // when authencator is null
400
user = ManagerFactory.getOnlineUserFactory().getAnonymousUser(request);
401             setOnlineUser(sessionID, user);
402         }
403
404         if (user.isGuest() && enableLoginInfoInRealm && (null != request.getRemoteUser())) {
405             String JavaDoc memberName = StringUtil.getEmptyStringIfNull(request.getRemoteUser());
406             if ( memberName.length() > 0 ) {
407                 try {
408                     DAOFactory.getMemberDAO().findByAlternateKey_MemberName(memberName);
409                     user = login(request, null, memberName, PASSWORD_OF_METHOD_REALM, true);
410                     ((OnlineUserImpl)user).setAuthenticationType(OnlineUser.AUTHENTICATION_TYPE_REALM);
411                 } catch (ObjectNotFoundException oe) {
412                     // ignore
413
}
414             }
415         }
416
417         // now we have the user, check if it is a Guest and we can login in CUSTOM
418
boolean enableLoginInfoInCustomization = MVNForumConfig.getEnableLoginInfoInCustomization();
419         if (authenticator == null) {
420             authenticator = ManagerFactory.getAuthenticator();
421         }
422         if (authenticator != null) {
423             if (user.isGuest() && enableLoginInfoInCustomization && (null != authenticator.getRemoteUser(request))) {
424                 String JavaDoc memberName = StringUtil.getEmptyStringIfNull(authenticator.getRemoteUser(request));
425                 if (memberName.length() > 0) {
426                     try {
427                         DAOFactory.getMemberDAO().findByAlternateKey_MemberName(memberName);
428                         user = login(request, null, memberName, PASSWORD_OF_METHOD_CUSTOMIZATION, true);
429                         ( (OnlineUserImpl) user).setAuthenticationType(OnlineUser.AUTHENTICATION_TYPE_CUSTOMIZATION);
430                     } catch (ObjectNotFoundException oe) {
431                         // ignore, the implementation of Authenticator should create the member in database first
432
}
433                 }
434             }
435         }
436
437         user.getOnlineUserAction().updateLastRequestTime();
438         return user;
439     }
440
441     public OnlineUser getOnlineUser(HttpServletRequest request)
442         throws AuthenticationException, AssertionException, DatabaseException {
443
444         long currentTime = System.currentTimeMillis();
445         if (currentTime - timeOfLastRemoveAction > REMOVE_INTERVAL) {//update every minute
446
removeTimeoutUsers();
447             // update MostOnline here
448
int currentOnlineUserCount = userMap.size();
449             fireDataChanged(new OnlineUserEvent(this, currentOnlineUserCount));
450         }
451
452         HttpSession session = request.getSession();
453         String JavaDoc sessionID = session.getId();
454         OnlineUser user = getOnlineUser(sessionID);
455
456         // When logged in as remote or customization, the remote user is logged out
457
// and mvnForum still have the old non-guest users, then we should logout this user
458
// in OnlineUser too.
459
if ( (user != null) && (user.isGuest() == false) ) {
460             if (user.getAuthenticationType() == OnlineUser.AUTHENTICATION_TYPE_REALM){
461                 String JavaDoc currentRemoteUser = request.getRemoteUser();
462                 if (currentRemoteUser == null) {
463                     logout(request, null /*response*/);
464                 } else if (currentRemoteUser.equalsIgnoreCase(user.getMemberName()) == false) {
465                     throw new AssertionException("ASSERTION: Current remote user should equals the current member in OnlineUser. Please report bug to mvnForum developers.");
466                 }
467             } else if (user.getAuthenticationType() == OnlineUser.AUTHENTICATION_TYPE_CUSTOMIZATION) {
468                 String JavaDoc currentRemoteUser = StringUtil.getEmptyStringIfNull(authenticator.getRemoteUser(request));
469                 if (currentRemoteUser.equals("")) {
470                     logout(request, null /*response*/);
471                 } else if (currentRemoteUser.equalsIgnoreCase(user.getMemberName()) == false) {
472                     throw new AssertionException("ASSERTION: Current remote user should equals the current member in OnlineUser. Please report bug to mvnForum developers.");
473                 }
474             }
475         }
476         // end of checking
477

478         // re-get the online user to continue
479
user = getOnlineUser(sessionID);
480         if (user == null) {
481
482             boolean enableLoginInfoInCookie = MVNForumConfig.getEnableLoginInfoInCookie();
483             boolean enableLoginInfoInSession = MVNForumConfig.getEnableLoginInfoInSession();
484             boolean enableLoginInfoInRealm = MVNForumConfig.getEnableLoginInfoInRealm();
485             boolean enableLoginInfoInCustomization = MVNForumConfig.getEnableLoginInfoInCustomization();
486
487             if ((user == null) && enableLoginInfoInSession) {
488                 String JavaDoc memberName = ParamUtil.getAttribute(session, MVNFORUM_SESSION_USERNAME);
489                 String JavaDoc encodedPassword = ParamUtil.getAttribute(session, MVNFORUM_SESSION_PASSWORD);
490                 if ( (memberName.length() > 0) && (encodedPassword.length() > 0)) {
491                     try {
492                         user = login(request, null, memberName, encodedPassword, true);
493                         ((OnlineUserImpl) user).setAuthenticationType(OnlineUser.AUTHENTICATION_TYPE_SESSION);
494                     } catch (AuthenticationException e) {
495                         // do nothing, some time the login info in the session
496
// is not correct, we dont consider this case as error
497
}
498                 }
499             }
500             if ((user == null) && enableLoginInfoInCookie) {
501                 String JavaDoc memberName = "";
502                 String JavaDoc encodedPassword = "";
503                 Cookie[] cookies = request.getCookies();
504                 if (cookies != null) {
505                     for (int i = 0; i < cookies.length; i++) {
506                         Cookie cookie = cookies[i];
507                         String JavaDoc cookieName = cookie.getName();
508                         if (cookieName.equals(MVNFORUM_COOKIE_USERNAME)) {
509                             memberName = Encoder.decodeURL(cookie.getValue()) ;
510                         } else if (cookieName.equals(MVNFORUM_COOKIE_PASSWORD)) {
511                             encodedPassword = cookie.getValue();
512                         }
513                     }
514                 }
515                 if ( (memberName.length() > 0) && (encodedPassword.length() > 0) &&
516                      (encodedPassword.equalsIgnoreCase(PASSWORD_OF_METHOD_REALM) == false) &&
517                      (encodedPassword.equalsIgnoreCase(PASSWORD_OF_METHOD_CUSTOMIZATION) == false) ) {
518                     try {
519                         user = login(request, null, memberName, encodedPassword, true);
520                         ((OnlineUserImpl)user).setAuthenticationType(OnlineUser.AUTHENTICATION_TYPE_COOKIE);
521                     } catch (AuthenticationException e) {
522                         // do nothing, some time the login info in the cookie
523
// is not correct, we dont consider this case as error
524
}
525                 }
526             }
527             if ((user == null) && enableLoginInfoInRealm && (null != request.getRemoteUser())) {
528                 String JavaDoc memberName = StringUtil.getEmptyStringIfNull(request.getRemoteUser());
529                 if ( memberName.length() > 0 ) {
530                     try {
531                         DAOFactory.getMemberDAO().findByAlternateKey_MemberName(memberName);
532                         user = login(request, null, memberName, PASSWORD_OF_METHOD_REALM, true);
533                         ((OnlineUserImpl)user).setAuthenticationType(OnlineUser.AUTHENTICATION_TYPE_REALM);
534                     } catch (ObjectNotFoundException oe) {
535                         // ignore
536
}
537                 }
538             }
539             if ((user == null) && enableLoginInfoInCustomization) {
540                 if (authenticator == null) {
541                     authenticator = ManagerFactory.getAuthenticator();
542                 }
543                 if (authenticator != null) {
544                     String JavaDoc memberName = StringUtil.getEmptyStringIfNull(authenticator.getRemoteUser(request));
545                     if (memberName.length() > 0) {
546                         try {
547                             DAOFactory.getMemberDAO().findByAlternateKey_MemberName(memberName);
548                             user = login(request, null, memberName, PASSWORD_OF_METHOD_CUSTOMIZATION, true);
549                             ((OnlineUserImpl)user).setAuthenticationType(OnlineUser.AUTHENTICATION_TYPE_CUSTOMIZATION);
550                         } catch (ObjectNotFoundException oe) {
551                             // ignore
552
}
553                     }
554                 }
555             }
556             if (user == null) {
557                 user = ManagerFactory.getOnlineUserFactory().getAnonymousUser(request);
558                 setOnlineUser(sessionID, user);
559             }
560         } else { //user != null
561
// now we have the user, check if it is a Guest and we can login in REALM
562
boolean enableLoginInfoInRealm = MVNForumConfig.getEnableLoginInfoInRealm();
563             if (user.isGuest() && enableLoginInfoInRealm && (null != request.getRemoteUser())) {
564                 String JavaDoc memberName = StringUtil.getEmptyStringIfNull(request.getRemoteUser());
565                 if ( memberName.length() > 0 ) {
566                     try {
567                         DAOFactory.getMemberDAO().findByAlternateKey_MemberName(memberName);
568                         user = login(request, null, memberName, PASSWORD_OF_METHOD_REALM, true);
569                         ((OnlineUserImpl)user).setAuthenticationType(OnlineUser.AUTHENTICATION_TYPE_REALM);
570                     } catch (ObjectNotFoundException oe) {
571                         // ignore
572
}
573                 }
574             }
575
576             // now we have the user, check if it is a Guest and we can login in CUSTOM
577
boolean enableLoginInfoInCustomization = MVNForumConfig.getEnableLoginInfoInCustomization();
578             if (authenticator == null) {
579                 authenticator = ManagerFactory.getAuthenticator();
580             }
581             if (authenticator != null) {
582                 if (user.isGuest() && enableLoginInfoInCustomization && (null != authenticator.getRemoteUser(request))) {
583                     String JavaDoc memberName = StringUtil.getEmptyStringIfNull(authenticator.getRemoteUser(request));
584                     if (memberName.length() > 0) {
585                         try {
586                             DAOFactory.getMemberDAO().findByAlternateKey_MemberName(memberName);
587                             user = login(request, null, memberName, PASSWORD_OF_METHOD_CUSTOMIZATION, true);
588                             ( (OnlineUserImpl) user).setAuthenticationType(OnlineUser.AUTHENTICATION_TYPE_CUSTOMIZATION);
589                         } catch (ObjectNotFoundException oe) {
590                             // ignore, the implementation of Authenticator should create the member in database first
591
}
592                     }
593                 }
594             }
595         }
596         user.getOnlineUserAction().updateLastRequestTime();
597         return user;
598     }
599
600     public Collection getOnlineUserActions(int sortOption, boolean duplicateUsers) {
601
602         Collection collection = userMap.values();
603         // @todo: find a better sollution, I dont want to copy the Collection
604
// this ArrayList is used to copy the values
605
ArrayList retValue = new ArrayList(collection.size());
606
607         // Get members first
608
if (duplicateUsers) {
609             for (Iterator memberIterator = collection.iterator(); memberIterator.hasNext(); ) {
610                 OnlineUser onlineUser = (OnlineUser) memberIterator.next();
611                 if (onlineUser.isMember()) {
612                     OnlineUserAction onlineUserAction = onlineUser.getOnlineUserAction();
613                     retValue.add(onlineUserAction);
614                 }
615             }
616         } else {
617             // now we combine the duplicated users
618
Hashtable distinctUserActions = new Hashtable();
619             OnlineUserAction lastUserAction = null;
620             for (Iterator memberIterator = collection.iterator(); memberIterator.hasNext(); ) {
621                 OnlineUser onlineUser = (OnlineUser) memberIterator.next();
622                 if (onlineUser.isMember()) {
623                     OnlineUserAction onlineUserAction = onlineUser.getOnlineUserAction();
624                     String JavaDoc memberName = onlineUserAction.getMemberName();
625                     onlineUserAction.resetSessionCount();
626                     lastUserAction = (OnlineUserAction) distinctUserActions.get(memberName);
627                     if (lastUserAction == null) {
628                         distinctUserActions.put(memberName, onlineUserAction);
629                     } else if (onlineUserAction.getLastRequestTime().after(lastUserAction.getLastRequestTime())) {
630                         distinctUserActions.put(memberName, onlineUserAction);
631                         onlineUserAction.increaseSessionCount(lastUserAction.getSessionCount());
632                     } else {
633                         lastUserAction.increaseSessionCount(1);
634                     }
635                 }
636             }
637             // now add the distinct member to the returned value
638
Collection distinctCollection = distinctUserActions.values();
639             for (Iterator iterator = distinctCollection.iterator(); iterator.hasNext(); ) {
640                 OnlineUserAction onlineUserAction = (OnlineUserAction)iterator.next();
641                 retValue.add(onlineUserAction);
642             }
643         }
644
645         // then get guest last
646
for (Iterator guestIterator = collection.iterator(); guestIterator.hasNext(); ) {
647             OnlineUser onlineUser = (OnlineUser)guestIterator.next();
648             if (onlineUser.isGuest()) {
649                 OnlineUserAction onlineUserAction = onlineUser.getOnlineUserAction();
650                 retValue.add(onlineUserAction);
651             }
652         }
653         return retValue;
654     }
655
656     public void updateOnlineUserAction(HttpServletRequest request, Action action)
657         throws AssertionException, DatabaseException, AuthenticationException {
658
659         if (action != null) {
660             OnlineUser onlineUser = getOnlineUser(request);
661             OnlineUserAction onlineUserAction = onlineUser.getOnlineUserAction();
662             // the setAction has package-default access
663
// so this is the only way to set action to a user
664
onlineUserAction.setAction(action);
665         }
666     }
667
668     public synchronized boolean isUserOnline(String JavaDoc username) {
669
670         Collection collection = userMap.values();
671         Iterator iterator = collection.iterator();
672         while (iterator.hasNext()) {
673             OnlineUser onlineUser = (OnlineUser)iterator.next();
674             String JavaDoc currentUser = onlineUser.getMemberName();
675             if (username.equalsIgnoreCase(currentUser)) {
676                 return true;
677             }
678         }
679         return false;
680     }
681
682 /************************************************************************
683  * private methods
684  ************************************************************************/

685     private synchronized OnlineUser getOnlineUser(String JavaDoc sessionID) {
686
687         return (OnlineUser)userMap.get(sessionID);
688     }
689
690     private synchronized void setOnlineUser(String JavaDoc sessionID, OnlineUser user) {
691
692         if (null == user) {
693             userMap.remove(sessionID);
694         } else {
695             userMap.put(sessionID, user);
696         }
697     }
698
699     private synchronized void removeTimeoutUsers() {
700
701         long currentTimeMillis = System.currentTimeMillis();
702         // try to resolve problem with synchronization on the class-varible : timeOfLastRemoveAction
703
if (currentTimeMillis - timeOfLastRemoveAction < REMOVE_INTERVAL) {
704             return;
705         }
706         // okie now, go ahead
707
timeOfLastRemoveAction = currentTimeMillis;
708
709         Timestamp JavaDoc currentTime = DateUtil.getCurrentGMTTimestamp();
710
711         Collection collection = userMap.values();
712         Iterator iterator = collection.iterator();
713         while (iterator.hasNext()) {
714             OnlineUser onlineUser = (OnlineUser)iterator.next();
715             OnlineUserAction onlineUserAction = onlineUser.getOnlineUserAction();
716             long duration = currentTime.getTime() - onlineUserAction.getLastRequestTime().getTime();
717             if (duration > MVNForumConfig.SESSION_DURATION) {
718                 iterator.remove();
719             }
720         }
721     }
722
723     /************************************************************************
724      * Event method
725      ************************************************************************/

726     public synchronized void removeOnlineUserListener(OnlineUserListener l) {
727
728         if (onlineUserListeners != null && onlineUserListeners.contains(l)) {
729             Vector v = (Vector) onlineUserListeners.clone();
730             v.removeElement(l);
731             onlineUserListeners = v;
732         }
733     }
734     public synchronized void addOnlineUserListener(OnlineUserListener l) {
735
736         Vector v = onlineUserListeners == null ? new Vector(2) : (Vector) onlineUserListeners.clone();
737         if (!v.contains(l)) {
738             v.addElement(l);
739             onlineUserListeners = v;
740         }
741     }
742
743     protected void fireDataChanged(OnlineUserEvent e) {
744
745         if (onlineUserListeners != null) {
746             Vector listeners = onlineUserListeners;
747             int count = listeners.size();
748             for (int i = 0; i < count; i++) {
749                 ((OnlineUserListener) listeners.elementAt(i)).dataChanged(e);
750             }
751         }
752     }
753 }
754
Popular Tags