1 64 65 70 71 package com.jcorporate.expresso.core.security; 72 73 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap; 74 import com.jcorporate.expresso.core.controller.ControllerRequest; 75 import com.jcorporate.expresso.core.dataobjects.ContextNested; 76 import com.jcorporate.expresso.core.dataobjects.DataObject; 77 import com.jcorporate.expresso.core.dataobjects.Mappable; 78 import com.jcorporate.expresso.core.db.DBConnection; 79 import com.jcorporate.expresso.core.db.DBException; 80 import com.jcorporate.expresso.core.dbobj.LookupInterface; 81 import com.jcorporate.expresso.core.dbobj.SecuredDBObject; 82 import com.jcorporate.expresso.core.dbobj.ValidValue; 83 import com.jcorporate.expresso.core.logging.LogException; 84 import com.jcorporate.expresso.core.misc.Base64; 85 import com.jcorporate.expresso.core.misc.ByteArrayDataSource; 86 import com.jcorporate.expresso.core.misc.ConfigManager; 87 import com.jcorporate.expresso.core.misc.ConfigurationException; 88 import com.jcorporate.expresso.core.misc.EMailSender; 89 import com.jcorporate.expresso.core.misc.EventHandler; 90 import com.jcorporate.expresso.core.misc.StringUtil; 91 import com.jcorporate.expresso.kernel.util.FastStringBuffer; 92 import com.jcorporate.expresso.services.dbobj.UserGroup; 93 import org.apache.log4j.Logger; 94 95 import java.util.ArrayList ; 96 import java.util.Enumeration ; 97 import java.util.Hashtable ; 98 import java.util.Iterator ; 99 import java.util.List ; 100 import java.util.Vector ; 101 102 103 118 public class User 119 implements LookupInterface, Mappable, ContextNested { 120 121 private static final String thisClass = User.class.getName(); 123 124 private UserInfo myUserInfo = null; 126 127 130 protected static UserInfo notLoggedInUser = null; 131 132 private String dbName = "default"; 134 135 138 private static Logger log = Logger.getLogger(User.class); 139 140 143 private static ConcurrentReaderHashMap listeners = null; 144 145 150 public static final String ANONYMOUS_ALLOWED_GUEST_USER = "Anonymous"; 151 152 155 public static final String UNKNOWN_USER = "NONE"; 156 157 160 public static final String ADMIN_USER = "Admin"; 161 162 167 public static final String ACTIVE_ACCOUNT_STATUS = "A"; 168 169 174 public static final String DISABLED_ACCOUNT_STATUS = "D"; 175 176 181 public static final String INACTIVE_ACCOUNT_STATUS = "I"; 182 183 184 189 public static final String WAITING_FOR_APPROVAL_ACCOUNT_STATUS = "W"; 190 191 192 195 public User() { 196 } 197 198 199 206 public User(UserInfo uInfo) { 207 myUserInfo = uInfo; 208 } 209 210 211 216 public void add() 217 throws DBException { 218 219 if ("".equals(getAccountStatus())) { 222 setAccountStatus("I"); 223 } 224 225 getUserInfo().add(); 227 } 231 232 238 public void addNotify(UserInfo uif) throws DBException { 239 this.myUserInfo = uif; 240 241 245 if (listeners != null) { 246 ArrayList theListeners = null; 247 synchronized (listeners) { 248 theListeners = new ArrayList (listeners.values()); 249 } 250 251 for (Iterator iterator = theListeners.iterator(); iterator.hasNext();) { 252 UserListener listener = (UserListener) iterator.next(); 253 listener.addedUser(this); 254 } 255 } 256 } 257 258 259 271 public static synchronized void addListener(UserListener listener) { 272 if (listeners == null) { 273 listeners = new ConcurrentReaderHashMap(); 274 } 275 276 listeners.put(listener.getClass().getName(), listener); 277 } 278 279 285 public static synchronized boolean isListener(UserListener listener) { 286 if (listeners == null) { 287 return false; 288 } 289 290 return listeners.get(listener.getClass().getName()) != null; 291 } 292 293 294 305 public boolean checkEmailAuthCode(String emailAuthCode) 306 throws DBException { 307 try { 308 String realEmailAuthCode = ""; 309 realEmailAuthCode = getEmailAuthCode(); 310 311 if (realEmailAuthCode == null) { 312 realEmailAuthCode = ""; 313 } 314 if (realEmailAuthCode.equals(emailAuthCode)) { 315 return true; 316 } else { 317 return false; 318 } 319 } catch (Exception e) { 320 throw new DBException("Error in checking Email Auth Code: " + 321 e.toString()); 322 } 323 } 324 325 326 332 public synchronized void clear() 333 throws DBException { 334 myUserInfo = null; 335 } 336 337 338 344 public void delete() 345 throws DBException { 346 347 351 getUserInfo().delete(); 353 } 354 355 361 public void deleteNotify(UserInfo uif) throws DBException { 362 this.myUserInfo = uif; 368 369 373 if (listeners != null) { 374 ArrayList theListeners = null; 375 synchronized (listeners) { 376 theListeners = new ArrayList (listeners.values()); 377 } 378 379 for (Iterator iterator = theListeners.iterator(); iterator.hasNext();) { 380 UserListener listener = (UserListener) iterator.next(); 381 listener.deletedUser(this); 382 } 383 } 384 } 385 386 387 393 public boolean find() 394 throws DBException { 395 return getUserInfo().find(); 396 } 397 398 399 406 public String getAccountStatus() 407 throws DBException { 408 return getUserInfo().getAccountStatus(); 409 } 410 411 412 419 public Vector getAllUsers() 420 throws DBException { 421 return getUserInfo().getAllUsers(); 422 } 423 424 425 430 public String getDataContext() { 431 return dbName; 432 } 433 434 441 public String getEmail() 442 throws DBException { 443 return getUserInfo().getEmail(); 444 } 445 446 447 463 public String getEmailAuthCode() 464 throws DBException { 465 return getUserInfo().getEmailAuthCode(); 466 } 467 468 469 475 public String getEmailValCode() 476 throws DBException { 477 return getUserInfo().getEmailValCode(); 478 } 479 480 481 487 public Vector getGroups() 488 throws DBException { 489 UserInfo myInfo = getUserInfo(); 490 return myInfo.getGroups(); 491 } 492 493 494 502 public List getGroupsList() 503 throws DBException { 504 UserInfo myInfo = getUserInfo(); 505 506 return new ArrayList (myInfo.getGroups()); 507 } 508 509 515 public String getLoginName() 516 throws DBException { 517 return getUserInfo().getLoginName(); 518 } 519 520 521 531 public String getPassword() 532 throws DBException { 533 return getUserInfo().getPassword(); 534 } 535 536 537 542 public synchronized UserInfo getNotLoggedInUser() throws DBException { 543 if (notLoggedInUser == null) { 544 notLoggedInUser = constructNotLoggedInUser(); 545 } 546 547 return notLoggedInUser; 548 } 549 550 553 protected UserInfo constructNotLoggedInUser() throws DBException { 554 UserInfo ui = this.getUserInfo(); 555 ui.setLoginName(UNKNOWN_USER); 556 ui.find(); 557 558 return ui; 559 } 560 561 567 public boolean getRegComplete() 568 throws DBException { 569 return getUserInfo().getRegComplete(); 570 } 571 572 573 580 public String getRegistrationDomain() 581 throws DBException { 582 return getUserInfo().getRegistrationDomain(); 583 } 584 585 586 593 public String getUidString() 594 throws DBException { 595 return Integer.toString(getUserInfo().getUid()); 596 } 597 598 599 public int getUid() 600 throws DBException { 601 return getUserInfo().getUid(); 602 } 603 604 611 public UserInfo getUserInfo() 612 throws DBException { 613 614 if (myUserInfo != null) { 615 return myUserInfo; 616 } 617 618 String infoClass = StringUtil.notNull(ConfigManager.getClassHandler("userInfo")); 619 620 if (infoClass.equals("")) { 621 infoClass = com.jcorporate.expresso.services.dbobj.DefaultUserInfo.class.getName(); 622 } 623 try { 624 Object o = Class.forName(infoClass).newInstance(); 625 626 if (!(o instanceof UserInfo)) { 627 throw new DBException(thisClass + "getUserInfo()" + ":The class " + infoClass + 628 " is not a UserInfo object - it's a " + 629 o.getClass().getName()); 630 } 631 632 myUserInfo = (UserInfo) o; 633 } catch (ClassNotFoundException ce) { 634 throw new DBException(thisClass + "getUserInfo()" + ":Class not found '" + infoClass, 635 ce); 636 } catch (InstantiationException ie) { 637 throw new DBException(thisClass + "getUserInfo()" + ":Error instantiating class '" + 638 infoClass, ie); 639 } catch (IllegalAccessException iae) { 640 throw new DBException(thisClass + "getUserInfo()" + ":Illegal access error " + 641 "instantiating class '" + infoClass, iae); 642 } 643 644 myUserInfo.setDBName(this.getDataContext()); 645 646 return myUserInfo; 647 } 648 649 657 public String getDisplayName() 658 throws DBException { 659 return getUserInfo().getUserName(); 660 } 661 662 663 670 public synchronized Vector getValidValues(String fieldName) 671 throws DBException { 672 673 if ("AccountStatus".equals(fieldName)) { 674 Vector values = new Vector (); 675 values.addElement(new ValidValue("A", "Active")); 676 values.addElement(new ValidValue("I", 677 "Inactive Until Email Confirmation")); 678 values.addElement(new ValidValue("D", "Disabled")); 679 values.addElement(new ValidValue("W", "Waiting For Approval")); 680 values.addElement(new ValidValue("X", 681 "Registration Denied By Administrator")); 682 683 return values; 684 } 685 686 return null; 687 } 688 689 690 public Vector getValues() 691 throws com.jcorporate.expresso.core.db.DBException { 692 return getUserInfo().getValues(); 693 } 694 695 707 private String hashEncodePassword(String plaintext) 708 throws DBException { 709 if (plaintext == null) { 710 throw new DBException(thisClass + "hashEncodePassword()" + ": Password Must not be NULL"); 711 } 712 if (plaintext.length() == 0) { 713 return plaintext; 714 } 715 try { 716 return Base64.encode(CryptoManager.getInstance().getStringHash().produceHash(plaintext.getBytes())); 717 } catch (Exception ex) { 718 throw new DBException(thisClass + "hashEncodePassword()" + ":Error hashing Password:" + 719 " You may not have installed the" + 720 " Cryptography Extensions Properly:", ex); 721 } 722 } 723 724 725 732 public void notify(String subject, String message) 733 throws DBException { 734 notify(subject, message, false); 735 } 736 737 745 public void notify(String subject, String message, boolean htmlFormat) 746 throws DBException { 747 notify(subject, message, htmlFormat, null); 748 } 749 750 761 public void notify(String subject, String message, boolean htmlFormat, 762 ByteArrayDataSource attachments[]) 763 throws DBException { 764 765 if (log.isDebugEnabled()) { 766 log.debug("Notifying user " + getUserInfo().getLoginName() 767 + " of " + subject); 768 } 769 770 String sendToUser = getUserInfo().getEmail(); 771 772 try { 773 EMailSender ems = new EMailSender(); 774 ems.setDBName(this.getDataContext()); 775 if (htmlFormat) { 776 ems.setEmailHtmlFormat(); 777 } 778 779 if (attachments != null) { 780 for (int k = 0; k < attachments.length; ++k) { 782 ems.addDataSourceAttachment(attachments[k]); 783 } 784 } 785 786 ems.send(sendToUser, subject, message); 787 } catch (Exception e) { 788 throw new DBException(thisClass + "notify()" + 789 ":Uncaught exception sending e-mail", e); 790 } 791 } 792 793 794 802 private boolean okNumber(double x) { 803 int oneNumber = new Double (x).intValue(); 804 805 if ((oneNumber >= 65) && (oneNumber <= 90)) { 806 return true; 807 } 808 if ((oneNumber >= 48) && (oneNumber <= 57)) { 809 return true; 810 } 811 if ((oneNumber >= 97) && (oneNumber <= 122)) { 812 return true; 813 } 814 815 return false; 816 } 817 818 825 public boolean passwordEquals(String tryPassword) 826 throws DBException { 827 if (tryPassword == null) { 828 throw new DBException(thisClass + ":tryPassword Must not be NULL"); 829 } 830 831 return getUserInfo().passwordEquals(tryPassword); 832 } 833 834 835 839 public void postLogin() 840 throws DBException, LogException { 841 UserInfo myInfo = getUserInfo(); 842 UserGroup oneGroup = new UserGroup(SecuredDBObject.SYSTEM_ACCOUNT); 843 oneGroup.setDataContext(getDataContext()); 844 845 String theEvent = null; 846 Hashtable allEvents = new Hashtable (1); 847 String oneGroupName = null; 848 849 for (Enumeration gl = getGroups().elements(); gl.hasMoreElements();) { 850 oneGroupName = (String ) gl.nextElement(); 851 oneGroup.clear(); 852 oneGroup.setField("GroupName", oneGroupName); 853 854 if (oneGroup.find()) { 855 theEvent = oneGroup.getField("LoginEvent"); 856 857 if (!theEvent.equals("")) { 858 allEvents.put(theEvent, oneGroup.getField("GroupName")); 859 } 860 } 861 862 } 863 864 865 866 String theMessage = null; 867 868 if (allEvents.size() > 0) { 869 for (Enumeration el = allEvents.keys(); el.hasMoreElements();) { 870 theEvent = (String ) el.nextElement(); 871 theMessage = "User " + myInfo.getLoginName() + 872 " (" + myInfo.getUserName() + 873 ") who is a member " + " of group " + 874 (String ) allEvents.get(theEvent) + 875 " has just logged in."; 876 EventHandler.Event(getDataContext(), theEvent, theMessage, true); 877 } 878 879 } 880 881 } 882 883 884 889 public String randomPassword() { 890 int passwordLength; 891 double oneNumber = 0; 892 char oneChar; 893 int iterations = 0; 894 895 String propValue = ""; 899 900 try { 901 StringUtil.notNull(ConfigManager.getContext(getDataContext()).getMinPasswordSize()); 902 } catch (ConfigurationException ce) { 903 propValue = ""; 904 } 905 if (!propValue.equals("")) { 906 try { 907 passwordLength = Integer.parseInt(propValue, 10); 908 } catch (NumberFormatException ex) { 909 910 passwordLength = 6; 912 } 913 } else { 914 passwordLength = 6; 915 } 916 917 FastStringBuffer newPassword = new FastStringBuffer(passwordLength); 918 while ((newPassword.length() < passwordLength) && (iterations < 200)) { 923 iterations++; 924 oneNumber = Math.random() * 100; 925 926 if (okNumber(oneNumber)) { 927 oneChar = (char) new Double (oneNumber).intValue(); 928 newPassword.append(oneChar); 929 } 930 } 931 932 return newPassword.toString(); 933 } 934 935 939 public void retrieve() 940 throws DBException { 941 getUserInfo().retrieve(); 942 } 943 944 945 948 public void sendAuthEmail() 949 throws DBException { 950 getUserInfo().sendAuthEmail(); 951 } 952 953 954 962 public void sendFileTo(String subject, String message, Vector fileNames) 963 throws DBException, LogException { 964 UserInfo myInfo = getUserInfo(); 965 log.debug("Sending " + fileNames.size() + " files via e-mail to " + 966 myInfo.getLoginName()); 967 968 String sendToUser = getUserInfo().getEmail(); 969 970 try { EMailSender ems = new EMailSender(); 972 ems.setDBName(getDataContext()); 973 ems.addFileAttachments(fileNames); 974 ems.send(sendToUser, subject, message); 975 } catch (Exception e) { 976 throw new DBException(thisClass + "sendFileTo" + ":Error sending e-mail", e); 977 } 978 } 979 980 981 984 public void sendFollowUpEmail() 985 throws DBException { 986 getUserInfo().sendFollowUpEmail(); 987 } 988 989 990 996 public void setAccountStatus(String accountStatus) 997 throws DBException { 998 getUserInfo().setAccountStatus(accountStatus); 999 } 1000 1001 1002 1009 public synchronized void setDBName(String newDBName) 1010 throws DBException { 1011 dbName = newDBName; 1012 getUserInfo().setDBName(newDBName); 1013 } 1014 1015 1016 1023 public void setEmail(String email) 1024 throws DBException { 1025 getUserInfo().setEmail(email); 1026 } 1027 1028 1029 1034 public void setEmailValCode(String code) 1035 throws DBException { 1036 getUserInfo().setEmailValCode(code); 1037 } 1038 1039 1046 public void setLoginName(String loginName) 1047 throws DBException { 1048 getUserInfo().setLoginName(loginName); 1049 } 1050 1051 1052 1059 public void setPassword(String password) 1060 throws DBException { 1061 getUserInfo().setPassword(getUserInfo().hashEncodePassword(password)); 1063 } 1064 1065 1071 public void setRegComplete(boolean status) 1072 throws DBException { 1073 getUserInfo().setRegComplete(status); 1074 } 1075 1076 1077 1084 public void setRegistrationDomain(String domain) 1085 throws DBException { 1086 getUserInfo().setRegistrationDomain(domain); 1087 } 1088 1089 1090 1097 public void setUid(int uid) 1098 throws DBException { 1099 getUserInfo().setUid(uid); 1100 } 1101 1102 1103 1109 public void setUid(String uid) 1110 throws DBException { 1111 try { 1112 int uidAsInt = new Integer (uid).intValue(); 1113 getUserInfo().setUid(uidAsInt); 1114 } catch (NumberFormatException ne) { 1115 throw new DBException(ne); 1116 } 1117 } 1118 1119 1126 public void setDisplayName(String name) 1127 throws DBException { 1128 getUserInfo().setUserName(name); 1129 } 1130 1131 1132 1141 public void update() 1142 throws DBException { 1143 1144 getUserInfo().update(); 1146 1147 } 1151 1152 1158 public void updateNotify(UserInfo uif) throws DBException { 1159 this.myUserInfo = uif; 1165 1166 if (listeners != null) { 1170 ArrayList theListeners = null; 1171 synchronized (listeners) { 1172 theListeners = new ArrayList (listeners.values()); 1173 } 1174 1175 for (Iterator iterator = theListeners.iterator(); iterator.hasNext();) { 1176 UserListener listener = (UserListener) iterator.next(); 1177 listener.modifiedUser(this); 1178 } 1179 } 1180 } 1181 1182 1185 private static Integer ADMIN_ID = null; 1186 1187 1192 public boolean isAdmin() throws DBException { 1193 if (ADMIN_ID == null) { 1194 int id = getIdFromLogin(ADMIN_USER, getDataContext()); 1195 ADMIN_ID = new Integer (id); 1196 } 1197 1198 return ADMIN_ID.intValue() == this.getUid(); 1199 } 1200 1201 1209 public static boolean isAdmin(int id) throws DBException { 1210 User user = new User(); 1211 user.setUid(id); 1212 return user.isAdmin(); 1213 } 1214 1215 1222 public static int getAdminId() throws DBException { 1223 return getAdminId(DBConnection.DEFAULT_DB_CONTEXT_NAME); 1224 } 1225 1226 1234 public static User getAdmin(String dbName) throws DBException { 1235 User user = new User(); 1236 user.setDataContext(dbName); 1237 user.setLoginName(ADMIN_USER); 1238 if (!user.find()) { 1239 throw new DBException("Unable to locate: " + ADMIN_USER); 1240 } 1241 1242 return user; 1243 } 1244 1245 1252 public static int getAdminId(String dbname) throws DBException { 1253 User user = new User(); 1254 user.setDataContext(dbname); 1255 user.isAdmin(); return ADMIN_ID.intValue(); 1257 } 1258 1259 1265 public static boolean isAdmin(String name) { 1266 return ADMIN_USER.equals(name); 1267 } 1268 1269 1275 public static boolean isUnknownUser(String name) { 1276 return UNKNOWN_USER.equals(name); 1277 } 1278 1279 1286 public String getPrimaryGroup() throws DBException { 1287 return getUserInfo().getPrimaryGroup(); 1288 } 1289 1290 1298 public static int getIdFromLogin(String login, String myDBname) throws DBException { 1299 User user = new User(); 1300 user.setDataContext(myDBname); 1301 user.setLoginName(login); 1302 if (!user.find()) { 1303 throw new DBException("cannot find user: " + login); 1304 } 1305 1306 return user.getUid(); 1307 } 1308 1309 1317 public static User getUserFromId(int uid, String dataContext) throws DBException { 1318 User user = new User(); 1319 user.setDataContext(dataContext); 1320 user.setUid(uid); 1321 if (!user.find()) { 1322 throw new DBException("cannot find user: " + uid); 1323 } 1324 return user; 1325 } 1326 1327 1335 public static String getLoginFromId(int uid, String dataContext) throws DBException { 1336 User user = User.getUserFromId(uid, dataContext); 1337 return user.getLoginName(); 1338 } 1339 1340 1341 1349 public String getKeyValue(String mappedValue) { 1350 try { 1351 User u = new User(); 1352 u.setDataContext(this.getDataContext()); 1353 u.setLoginName(mappedValue); 1354 if (u.find()) { 1355 return u.getUidString(); 1356 } else { 1357 return null; 1358 } 1359 } catch (DBException ex) { 1360 log.error("Error getting key value", ex); 1361 return null; 1362 } 1363 } 1364 1365 1373 public String getMappedValue(String keyValue) { 1374 try { 1375 User u = new User(); 1376 u.setDataContext(this.getDataContext()); 1377 u.setUid(keyValue); 1378 if (u.find()) { 1379 return u.getLoginName(); 1380 } else { 1381 return null; 1382 } 1383 } catch (DBException ex) { 1384 log.error("Error getting key value", ex); 1385 return null; 1386 } 1387 1388 } 1389 1390 1398 public String getMappedDescription() { 1399 try { 1400 return ((DataObject) this.getUserInfo()).getFieldMetaData("LoginName").getDescription(); 1401 } catch (DBException ex) { 1402 log.error("Error getting description", ex); 1403 return "Login Name"; 1404 } catch (ClassCastException cce) { 1405 return "Login Name"; 1406 } 1407 } 1408 1409 1410 1416 public void setDataContext(String newContext) { 1417 try { 1418 this.setDBName(newContext); 1419 } catch (DBException ex) { 1420 log.error("Error setting data context", ex); 1421 throw new IllegalArgumentException (ex.getMessage()); 1422 } 1423 } 1424 1425 1430 public String getDBName() { 1431 return this.getDataContext(); 1432 } 1433 1434 1441 public static User getUser(ControllerRequest request) throws DBException { 1442 return getUserFromId(request.getUid(), request.getDataContext()); 1443 } 1444 1445 1452 public boolean isMember(String candidategroupname) throws DBException { 1453 boolean result = false; 1454 List list = getGroupsList(); 1455 for (Iterator iterator = list.iterator(); iterator.hasNext();) { 1456 String grpname = (String ) iterator.next(); 1457 if (grpname.equals(candidategroupname)) { 1458 result = true; 1459 break; 1460 } 1461 } 1462 return result; 1463 } 1464} 1465 | Popular Tags |