001 /*----------------------------------------------------------------------- 002 * Copyright (C) 2006 003 * Associated Universities, Inc. Washington DC, USA. 004 * This program is free software; you can redistribute it and/or 005 * modify it under the terms of the GNU General Public License as 006 * published by the Free Software Foundation; either version 2 of 007 * the License, or (at your option) any later version. 008 * 009 * This program is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU General Public License for more details. 013 * 014 * Correspondence concerning this software should be addressed as follows: 015 * Internet email: switz@nrao.edu 016 * Postal address: User Database 017 * National Radio Astronomy Observatory 018 * Post Office Box 0 019 * Socorro, NM 87801 USA 020 *-----------------------------------------------------------------------*/ 021 package edu.nrao.sss.model.user; 022 023 import java.security.MessageDigest; 024 import java.security.NoSuchAlgorithmException; 025 import java.security.SecureRandom; 026 import java.util.ArrayList; 027 import java.util.Collection; 028 import java.util.Date; 029 import java.util.HashSet; 030 import java.util.Iterator; 031 import java.util.Random; 032 import java.util.Set; 033 import java.util.TimeZone; 034 035 //import org.apache.log4j.Logger; 036 037 import sun.misc.BASE64Encoder; 038 import edu.nrao.sss.xml.XMLTransform; 039 040 /** 041 * Outdated; use new 042 * <a href="https://staff.nrao.edu/evla/maven/m2-sites/shared/nrao-user/apidocs/edu/nrao/user/package-summary.html">NRAO User</a> package. 043 */ 044 @Deprecated 045 public class User extends ContactCollection implements XMLable { 046 047 //private static Logger log = Logger.getLogger(User.class.getName()); 048 049 public static final int AUTH_TOKEN_SIZE = 24; 050 051 private static final char[] RAND_PW_ALPHABET = { 'A', 'B', 'C', 'D', 'E', 052 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'W', 053 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 054 'm', 'n', 'p', 'q', 'r', 's', 't', 'w', 'x', 'y', 'z', '2', '3', 055 '4', '5', '6', '7', '8', '9', }; 056 057 private static final int RAND_PW_MAX_SIZE = 8; 058 059 private static final int RAND_PW_MIN_SIZE = 6; 060 061 private static final long serialVersionUID = 1L; 062 063 public static final String XML_VERSION = "https://e2e.nrao.edu/schemas/user-v1.0beta6.xsd"; 064 065 private String accountName; 066 067 private Set<Institution> affiliations; 068 069 private short aipsNumber; 070 071 private String authenticationToken; 072 073 private UserContactLevel contactLevel; 074 075 private Institution defaultInstitution; 076 077 private String encryptedPassword; 078 079 private EntryStatus entryStatus; 080 081 private String firstName; 082 083 private Character gender; 084 085 private short graduationYear; 086 087 private Set<UserGroup> groups; 088 089 private Date lastLogin; 090 091 private String lastName; 092 093 private Date lastObservation; 094 095 private String middleName; 096 097 private Collection<UserNote> notes; 098 099 private int outOfDateReporterId; 100 101 private String preferredName; 102 103 private UserPrefix prefix; 104 105 private boolean rememberLogin; 106 107 private UserSuffix suffix; 108 109 private TimeZone timezone; 110 111 private Set<UserType> types; 112 113 private AddressCountry unknownAffiliationCountry; 114 115 private String unknownAffiliationName; 116 117 public User() throws InfrastructureException { 118 super(); 119 } 120 121 private String accountInfoXML(boolean showAll) { 122 StringBuffer result = new StringBuffer(); 123 result.append("<account-info>\n"); 124 125 if (showAll && getAccountName() != null) 126 result.append("<account-name>" 127 + XMLTransform.encode(getAccountName()) 128 + "</account-name>\n"); 129 130 if (showAll && getEncryptedPassword() != null) 131 result.append("<encrypted-password>" 132 + XMLTransform.encode(getEncryptedPassword()) 133 + "</encrypted-password>\n"); 134 135 if (showAll && getAuthenticationToken() != null) 136 result.append("<authentication-token>" 137 + XMLTransform.encode(getAuthenticationToken()) 138 + "</authentication-token>\n"); 139 140 if (getEntryStatus() != null) 141 result.append("<entry-status>" 142 + XMLTransform.encode(getEntryStatus().getEntryStatus()) 143 + "</entry-status>\n"); 144 else 145 result.append("<entry-status>Unknown</entry-status>\n"); 146 147 if (showAll && getUpdatedOn() != null) 148 result.append("<updated-on>" + 149 XMLTransform.dateToXMLDateTime(getUpdatedOn()) + "</updated-on>\n"); 150 151 if (showAll && getUpdatedBy() > 0) 152 result.append("<updated-by>" + getUpdatedBy() + "</updated-by>\n"); 153 154 if (showAll && getLastLogin() != null) 155 result.append("<last-login>" + 156 XMLTransform.dateToXMLDateTime(getLastLogin()) + "</last-login>\n"); 157 158 result.append("</account-info>\n"); 159 return result.toString(); 160 } 161 162 public void addToAffiliations(Institution institution) { 163 if (institution == null) 164 return; 165 if (affiliations == null) 166 affiliations = new HashSet<Institution>(); 167 affiliations.add(institution); 168 } 169 170 public void addToGroups(UserGroup userGroup) { 171 if (userGroup == null) 172 return; 173 if (groups == null) 174 groups = new HashSet<UserGroup>(); 175 groups.add(userGroup); 176 } 177 178 public void addToNotes(UserNote userNote) { 179 if (userNote == null) 180 return; 181 if (notes == null) 182 notes = new HashSet<UserNote>(); 183 notes.add(userNote); 184 } 185 186 public void addToTypes(UserType userType) { 187 if (userType == null) 188 return; 189 if (types == null) 190 types = new HashSet<UserType>(); 191 types.add(userType); 192 } 193 194 private String affiliationInfoXML(boolean showAll) { 195 StringBuffer result = new StringBuffer(); 196 result.append("<affiliation-info>\n"); 197 198 if (getDefaultInstitution() == null) { 199 result.append("<default-affiliation>\n"); 200 if (getUnknownAffiliationName() != null) { 201 result.append("<formal-name>" 202 + XMLTransform.encode(getUnknownAffiliationName()) 203 + "</formal-name>\n"); 204 } else { 205 result.append("<formal-name>Unknown</formal-name>\n"); 206 } 207 result.append("</default-affiliation>\n"); 208 } else { 209 result.append(getDefaultInstitution().toXML(false, true, true)); 210 if (showAll) { 211 for (Institution inst : getAffiliations()) { 212 if (!inst.equals(getDefaultInstitution())) { 213 result.append(inst.toXML(false, true, false)); 214 } 215 } 216 } 217 } 218 result.append("</affiliation-info>\n"); 219 return result.toString(); 220 } 221 222 public void copy(User user) throws InfrastructureException { 223 super.copy(user); 224 set(user); 225 notes = new HashSet<UserNote>(); 226 for (UserNote userNote : user.getNotes()) { 227 UserNote newNote = new UserNote(); 228 newNote.copy(userNote); 229 addToNotes(newNote); 230 } 231 } 232 233 private String encryptPassword(String password) 234 throws InfrastructureException { 235 BASE64Encoder encoder = null; 236 MessageDigest d = null; 237 encoder = new sun.misc.BASE64Encoder(); 238 try { 239 d = java.security.MessageDigest.getInstance("MD5"); 240 } catch (NoSuchAlgorithmException ex) { 241 throw new InfrastructureException(ex); 242 } 243 d.reset(); 244 d.update(password.getBytes()); 245 return (encoder.encode(d.digest())); 246 } 247 248 public boolean equals(Object obj) { 249 if (null == obj) 250 return false; 251 if (!(obj instanceof User)) 252 return false; 253 else { 254 User mObj = (User) obj; 255 return (this.getId() == mObj.getId()); 256 } 257 } 258 259 private String footerXML() { 260 return "</user>\n"; 261 } 262 263 public String getAccountName() { 264 return accountName; 265 } 266 267 public Set<Institution> getAffiliations() { 268 if (affiliations == null) 269 affiliations = new HashSet<Institution>(); 270 return affiliations; 271 } 272 273 public short getAipsNumber() { 274 return aipsNumber; 275 } 276 277 public String getAuthenticationToken() { 278 return authenticationToken; 279 } 280 281 public UserContactLevel getContactLevel() { 282 return contactLevel; 283 } 284 285 public Institution getDefaultInstitution() { 286 return defaultInstitution; 287 } 288 289 public String getEncryptedPassword() { 290 return encryptedPassword; 291 } 292 293 public EntryStatus getEntryStatus() { 294 return entryStatus; 295 } 296 297 public String getFirstName() { 298 return firstName; 299 } 300 301 public String getFormalName() { 302 StringBuffer sb = new StringBuffer(); 303 if (getPrefix() != null) 304 sb.append(getPrefix().getUserPrefix() + ". "); 305 if (getFirstName() != null) 306 sb.append(getFirstName() + " "); 307 if (getMiddleName() != null && getMiddleName().length() > 0) { 308 char c = getMiddleName().toUpperCase().charAt(0); 309 sb.append("" + c + ". "); 310 } 311 if (getPreferredName() != null && getPreferredName().length() > 0) 312 sb.append("\"" + getPreferredName() + "\" "); 313 if (getLastName() != null) 314 sb.append(getLastName() + " "); 315 if (getSuffix() != null) 316 sb.append(getSuffix().getUserSuffix()); 317 return sb.toString().trim(); 318 } 319 320 public String getFormalNameLastNameFirst() { 321 StringBuffer sb = new StringBuffer(); 322 if (getLastName() != null) 323 sb.append(getLastName() + ", "); 324 if (getPrefix() != null) 325 sb.append(getPrefix().getUserPrefix() + ". "); 326 if (getFirstName() != null) 327 sb.append(getFirstName() + " "); 328 if (getMiddleName() != null && getMiddleName().length() > 0) { 329 char c = getMiddleName().toUpperCase().charAt(0); 330 sb.append("" + c + ". "); 331 } 332 if (getPreferredName() != null && getPreferredName().length() > 0) 333 sb.append("\"" + getPreferredName() + "\" "); 334 if (getSuffix() != null) 335 sb.append(getSuffix().getUserSuffix()); 336 return sb.toString().trim(); 337 } 338 339 public Character getGender() { 340 return gender; 341 } 342 343 public short getGraduationYear() { 344 return graduationYear; 345 } 346 347 public Set<UserGroup> getGroups() { 348 if (groups == null) 349 groups = new HashSet<UserGroup>(); 350 return groups; 351 } 352 353 public Date getLastLogin() { 354 return lastLogin; 355 } 356 357 public String getLastName() { 358 return lastName; 359 } 360 361 public Date getLastObservation() { 362 return lastObservation; 363 } 364 365 public String getMiddleName() { 366 return middleName; 367 } 368 369 public Collection<UserNote> getNotes() { 370 if (notes == null) 371 notes = new ArrayList<UserNote>(); 372 return notes; 373 } 374 375 public int getOutOfDateReporterId() { 376 return outOfDateReporterId; 377 } 378 379 public String getPreferredName() { 380 return preferredName; 381 } 382 383 public UserPrefix getPrefix() { 384 return prefix; 385 } 386 387 public UserSuffix getSuffix() { 388 return suffix; 389 } 390 391 public TimeZone getTimezone() { 392 return timezone; 393 } 394 395 public Set<UserType> getTypes() { 396 if (types == null) 397 types = new HashSet<UserType>(); 398 return types; 399 } 400 401 public AddressCountry getUnknownAffiliationCountry() { 402 return unknownAffiliationCountry; 403 } 404 405 public String getUnknownAffiliationName() { 406 return unknownAffiliationName; 407 } 408 409 public String getUserName() { 410 return getFormalName() + " (" + getAccountName() + ")"; 411 } 412 413 public String getUserNameLastNameFirst() { 414 return getFormalNameLastNameFirst() + " (" + getAccountName() + ")"; 415 } 416 417 private String headerXML() { 418 StringBuffer result = new StringBuffer(); 419 int domestic = isDomestic(); 420 421 /* 422 result 423 .append("<user xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"); 424 result.append("xsi:noNamespaceSchemaLocation='" + XML_VERSION + "'\n"); 425 */ 426 427 result.append("<user "); 428 result.append("id=\"" + getId() + "\"\n"); 429 result.append("domestic=\""); 430 if (domestic == 1) 431 result.append("true\">\n"); 432 else 433 result.append("false\">\n"); 434 return result.toString(); 435 } 436 437 public boolean isAffiliatedWith(Institution inst) { 438 if (inst == null) 439 return false; 440 for (Institution i : getAffiliations()) 441 if (inst.equals(i)) 442 return true; 443 return false; 444 } 445 446 public int isDomestic() { 447 if (defaultInstitution != null) 448 return defaultInstitution.isDomestic() ? 1 : 0; 449 if (unknownAffiliationCountry != null) 450 return unknownAffiliationCountry.isDomestic() ? 1 : 0; 451 return -1; 452 } 453 454 public boolean isRememberLogin() { 455 return rememberLogin; 456 } 457 458 public boolean isType(UserType userType) { 459 if (userType == null) 460 return false; 461 for (UserType uT : getTypes()) 462 if (uT.equals(userType)) 463 return true; 464 return false; 465 } 466 467 public boolean isUserInGroup(UserGroup userGroup) { 468 if (userGroup == null || getGroups().isEmpty()) 469 return false; 470 for (Iterator<UserGroup> iter = getGroups().iterator(); iter.hasNext();) { 471 if (iter.next().equals(userGroup)) 472 return true; 473 } 474 return false; 475 } 476 477 private String miscInfoXML(boolean showAll) { 478 StringBuffer result = new StringBuffer(); 479 result.append("<misc-info>\n"); 480 481 if (showAll && getGender() != null) { 482 if (getGender().charValue() == 'm' 483 || getGender().charValue() == 'M') 484 result.append("<gender>male</gender>\n"); 485 else if (getGender().charValue() == 'f' 486 || getGender().charValue() == 'F') 487 result.append("<gender>female</gender>\n"); 488 } 489 if (showAll && getAipsNumber() > 0) 490 result.append("<aips-number>" + getAipsNumber() 491 + "</aips-number>\n"); 492 if (getGraduationYear() > 0) 493 result.append("<graduation-year>" + getGraduationYear() 494 + "</graduation-year>\n"); 495 for (UserType uT : getTypes()) { 496 result.append("<user-type>" + XMLTransform.encode(uT.getUserType()) 497 + "</user-type>\n"); 498 } 499 if (showAll) 500 for (UserGroup uG : getGroups()) 501 result.append(uG.toXML()); 502 503 if (showAll) 504 for (UserNote uN : getNotes()) 505 result.append(uN.toXML()); 506 507 result.append("</misc-info>\n"); 508 return result.toString(); 509 } 510 511 private String nameInfoXML(boolean showAll) { 512 StringBuffer result = new StringBuffer(); 513 result.append("<name>\n"); 514 if (showAll && getPrefix() != null) 515 result.append("<prefix>" 516 + XMLTransform.encode(getPrefix().getUserPrefix()) 517 + "</prefix>\n"); 518 if (getFirstName() != null && getFirstName().trim().length() > 0) 519 result.append("<first-name>" + XMLTransform.encode(getFirstName()) 520 + "</first-name>\n"); 521 if (showAll && getMiddleName() != null 522 && getMiddleName().trim().length() > 1) 523 result 524 .append("<middle-name>" 525 + XMLTransform.encode(getMiddleName()) 526 + "</middle-name>\n"); 527 if (getLastName() != null && getLastName().trim().length() > 0) 528 result.append("<last-name>" + XMLTransform.encode(getLastName()) 529 + "</last-name>\n"); 530 if (showAll && getSuffix() != null) 531 result.append("<suffix>" 532 + XMLTransform.encode(getSuffix().getUserSuffix()) 533 + "</suffix>\n"); 534 if (getPreferredName() != null 535 && getPreferredName().trim().length() > 0) 536 result.append("<preferred-name>" 537 + XMLTransform.encode(getPreferredName()) 538 + "</preferred-name>\n"); 539 result.append("</name>\n"); 540 return result.toString(); 541 } 542 543 public boolean passwordEquals(String password) 544 throws InfrastructureException { 545 return (encryptPassword(password).equals(encryptedPassword)) ? true 546 : false; 547 } 548 549 private String randomPassword() throws InfrastructureException { 550 Random generator = new Random(); 551 return randomPassword(generator 552 .nextInt((RAND_PW_MAX_SIZE - RAND_PW_MIN_SIZE) + 1) 553 + RAND_PW_MIN_SIZE); 554 } 555 556 private String randomPassword(int size) throws InfrastructureException { 557 StringBuffer result = new StringBuffer(); 558 SecureRandom sr = null; 559 try { 560 sr = SecureRandom.getInstance("SHA1PRNG"); 561 } catch (NoSuchAlgorithmException ex) { 562 throw new InfrastructureException(ex); 563 } 564 for (int i = 0; i < size; i++) { 565 result 566 .append(RAND_PW_ALPHABET[sr 567 .nextInt(RAND_PW_ALPHABET.length)]); 568 } 569 return result.toString(); 570 } 571 572 public void removeFromTypes(UserType userType) { 573 if (userType == null) 574 return; 575 if (isType(userType)) 576 getTypes().remove(userType); 577 } 578 579 private void set(User user) throws InfrastructureException { 580 this.setAccountName(user.getAccountName()); 581 this.setAuthenticationToken(user.getAuthenticationToken()); 582 this.setLastLogin(user.getLastLogin()); 583 this.setEncryptedPassword(user.getEncryptedPassword()); 584 this.setEntryStatus(user.getEntryStatus()); 585 586 this.setPrefix(user.getPrefix()); 587 this.setSuffix(user.getSuffix()); 588 this.setFirstName(user.getFirstName()); 589 this.setLastName(user.getLastName()); 590 this.setMiddleName(user.getMiddleName()); 591 this.setPreferredName(user.getPreferredName()); 592 593 this.setDefaultInstitution(user.getDefaultInstitution()); 594 this.setLastObservation(user.getLastObservation()); 595 this.setAipsNumber(user.getAipsNumber()); 596 this.setGraduationYear(user.getGraduationYear()); 597 this.setGender(user.getGender()); 598 this.setRememberLogin(user.isRememberLogin()); 599 this.setOutOfDateReporterId(user.getOutOfDateReporterId()); 600 this.setTimezone(user.getTimezone()); 601 602 groups = new HashSet<UserGroup>(); 603 for (Iterator<UserGroup> iter = user.getGroups().iterator(); iter 604 .hasNext();) { 605 addToGroups(iter.next()); 606 } 607 types = new HashSet<UserType>(); 608 for (Iterator<UserType> iter = user.getTypes().iterator(); iter 609 .hasNext();) { 610 addToTypes(iter.next()); 611 } 612 affiliations = new HashSet<Institution>(); 613 for (Iterator<Institution> iter = user.getAffiliations().iterator(); iter 614 .hasNext();) { 615 addToAffiliations(iter.next()); 616 } 617 } 618 619 public void setAccountName(String accountName) { 620 this.accountName = accountName; 621 } 622 623 public void setAffiliations(Set<Institution> affiliations) { 624 this.affiliations = affiliations; 625 } 626 627 public void setAipsNumber(short aipsNumber) { 628 this.aipsNumber = aipsNumber; 629 } 630 631 public void setAuthenticationToken(String authenticationToken) { 632 this.authenticationToken = authenticationToken; 633 } 634 635 public void setContactLevel(UserContactLevel contactLevel) { 636 this.contactLevel = contactLevel; 637 } 638 639 public void setDefaultInstitution(Institution defaultInstitution) { 640 this.defaultInstitution = defaultInstitution; 641 } 642 643 public void setEncryptedPassword(String encryptedPassword) { 644 this.encryptedPassword = encryptedPassword; 645 } 646 647 public void setEntryStatus(EntryStatus entryStatus) { 648 this.entryStatus = entryStatus; 649 } 650 651 public void setFirstName(String firstName) { 652 this.firstName = firstName; 653 } 654 655 public void setGender(Character gender) { 656 this.gender = gender; 657 } 658 659 public void setGraduationYear(short graduationYear) { 660 this.graduationYear = graduationYear; 661 } 662 663 public void setGroups(Set<UserGroup> groups) { 664 this.groups = groups; 665 } 666 667 public void setLastLogin(Date lastLogin) { 668 this.lastLogin = lastLogin; 669 } 670 671 public void setLastName(String lastName) { 672 this.lastName = lastName; 673 } 674 675 public void setLastObservation(Date lastObservation) { 676 this.lastObservation = lastObservation; 677 } 678 679 public void setMiddleName(String middleName) { 680 this.middleName = middleName; 681 } 682 683 public void setNewPassword(String plainPassword) 684 throws InfrastructureException { 685 setEncryptedPassword(encryptPassword(plainPassword)); 686 } 687 688 public String setNewRandomPassword() throws InfrastructureException { 689 String newPass = randomPassword(); 690 String encPass = encryptPassword(newPass); 691 setEncryptedPassword(encPass); 692 return newPass; 693 } 694 695 public void setNotes(Collection<UserNote> notes) { 696 this.notes = notes; 697 } 698 699 public void setOutOfDateReporterId(int outOfDateReporterId) { 700 this.outOfDateReporterId = outOfDateReporterId; 701 } 702 703 public void setPreferredName(String preferredName) { 704 this.preferredName = preferredName; 705 } 706 707 public void setPrefix(UserPrefix prefix) { 708 this.prefix = prefix; 709 } 710 711 public void setRememberLogin(boolean rememberLogin) { 712 this.rememberLogin = rememberLogin; 713 } 714 715 public void setSuffix(UserSuffix suffix) { 716 this.suffix = suffix; 717 } 718 719 public void setTimezone(TimeZone timezone) { 720 this.timezone = timezone; 721 } 722 723 public void setTypes(Set<UserType> types) { 724 this.types = types; 725 } 726 727 public void setUnknownAffiliationCountry( 728 AddressCountry unknownAffiliationCountry) { 729 this.unknownAffiliationCountry = unknownAffiliationCountry; 730 } 731 732 public void setUnknownAffiliationName(String unknownAffiliationName) { 733 this.unknownAffiliationName = unknownAffiliationName; 734 } 735 736 public String toXML() { 737 return toXML(true); 738 } 739 740 public String toXML(boolean showAll) { 741 StringBuffer result = new StringBuffer(); 742 result.append(headerXML()); 743 result.append(nameInfoXML(showAll)); 744 result.append(contactInfoXML(showAll)); 745 result.append(affiliationInfoXML(showAll)); 746 result.append(miscInfoXML(showAll)); 747 result.append(accountInfoXML(showAll)); 748 result.append(footerXML()); 749 return result.toString(); 750 } 751 }