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    }