Package org.projectforge.user

Source Code of org.projectforge.user.PFUserDO

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.user;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Store;
import org.joda.time.DateTimeZone;
import org.projectforge.common.ReflectionToString;
import org.projectforge.common.TimeNotation;
import org.projectforge.core.AbstractBaseDO;
import org.projectforge.core.AbstractHistorizableBaseDO;
import org.projectforge.core.BaseDO;
import org.projectforge.core.Configuration;
import org.projectforge.core.DefaultBaseDO;
import org.projectforge.core.ModificationStatus;
import org.projectforge.core.ShortDisplayNameCapable;

/**
*
* @author Kai Reinhard (k.reinhard@micromata.de)
*
*/
@Entity
@Indexed
@Table(name = "T_PF_USER", uniqueConstraints = { @UniqueConstraint(columnNames = { "username"})})
public class PFUserDO extends DefaultBaseDO implements ShortDisplayNameCapable
{
  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(PFUserDO.class);

  private static final long serialVersionUID = 6680346054753032534L;

  private static final String NOPASSWORD = "--- none ---";

  static {
    AbstractHistorizableBaseDO.putNonHistorizableProperty(PFUserDO.class, "loginFailures", "lastLogin", "stayLoggedInKey", "passwordSalt",
        "password");
  }

  private transient Map<String, Object> attributeMap;

  @Field(index = Index.TOKENIZED, store = Store.NO)
  private String username;

  @Field(index = Index.TOKENIZED, store = Store.NO)
  private String jiraUsername;

  private String password;

  private Date lastPasswordChange;

  private boolean localUser;

  private boolean restrictedUser;

  private boolean deactivated;

  @Field(index = Index.TOKENIZED, store = Store.NO)
  private String firstname;

  @Field(index = Index.TOKENIZED, store = Store.NO)
  private String lastname;

  @Field(index = Index.TOKENIZED, store = Store.NO)
  private String description;

  @Field(index = Index.TOKENIZED, store = Store.NO)
  private String email;

  private String stayLoggedInKey;

  private String authenticationToken;

  private String passwordSalt;

  private Timestamp lastLogin;

  private int loginFailures;

  private Locale locale;

  private TimeZone timeZone;

  private Locale clientLocale;

  private String dateFormat;

  private String excelDateFormat;

  private Integer firstDayOfWeek;

  private TimeNotation timeNotation;

  @Field(index = Index.TOKENIZED, store = Store.NO)
  private String organization;

  @Field(index = Index.TOKENIZED, store = Store.NO)
  private String personalPhoneIdentifiers;

  @Field(index = Index.TOKENIZED, store = Store.NO)
  private String personalMebMobileNumbers;

  private Set<UserRightDO> rights = new HashSet<UserRightDO>();

  private boolean hrPlanning = true;

  @Field(index = Index.TOKENIZED, store = Store.NO)
  private String ldapValues;

  @Field(index = Index.TOKENIZED, store = Store.NO)
  private String sshPublicKey;

  @Transient
  public String getShortDisplayName()
  {
    return getUsername();
  }

  @Column(length = 255)
  public String getOrganization()
  {
    return organization;
  }

  public PFUserDO setOrganization(final String organization)
  {
    this.organization = organization;
    return this;
  }

  /**
   * @return For example "Europe/Berlin" if time zone is given otherwise empty string.
   */
  @Transient
  public String getTimeZoneDisplayName()
  {
    if (timeZone == null) {
      return "";
    }
    return timeZone.getDisplayName();
  }

  /**
   * @return For example "Europe/Berlin" if time zone is given otherwise empty string.
   */
  @Column(name = "time_zone")
  public String getTimeZone()
  {
    if (timeZone == null) {
      return "";
    }
    return timeZone.getID();
  }

  public void setTimeZone(final String timeZoneId)
  {
    if (StringUtils.isNotBlank(timeZoneId) == true) {
      setTimeZone(TimeZone.getTimeZone(timeZoneId));
    }
  }

  /**
   * @param timeZone
   * @return this for chaining.
   */
  public PFUserDO setTimeZone(final TimeZone timeZone)
  {
    this.timeZone = timeZone;
    return this;
  }

  @Transient
  public TimeZone getTimeZoneObject()
  {
    if (timeZone != null) {
      return this.timeZone;
    } else {
      return Configuration.getInstance().getDefaultTimeZone();
    }
  }

  public void setTimeZoneObject(final TimeZone timeZone)
  {
    this.timeZone = timeZone;
  }

  @Transient
  public DateTimeZone getDateTimeZone()
  {
    final TimeZone timeZone = getTimeZoneObject();
    return DateTimeZone.forID(timeZone.getID());
  }

  @Column
  public Locale getLocale()
  {
    return locale;
  }

  /**
   * @param locale
   * @return this for chaining.
   */
  public PFUserDO setLocale(final Locale locale)
  {
    this.locale = locale;
    return this;
  }

  /**
   * Default date format for the user. Examples:
   * <ul>
   * <li>yyyy-MM-dd: 2011-02-21, ISO format.</li>
   * <li>dd.MM.yyyy: 21.02.2011, German format (day of month first)</li>
   * <li>dd/MM/yyyy: 21/02/2011, British and French format (day of month first)</li>
   * <li>MM/dd/yyyy: 02/21/2011, American format (month first)</li>
   * </ul>
   * @return
   */
  @Column(name = "date_format", length = 20)
  public String getDateFormat()
  {
    return dateFormat;
  }

  public void setDateFormat(final String dateFormat)
  {
    this.dateFormat = dateFormat;
  }

  /**
   * Default excel date format for the user. Examples:
   * <ul>
   * <li>DD.MM.YYYY: 21.02.2011, German format (day of month first)</li>
   * <li>DD/MM/YYYY: 21/02/2011, British and French format (day of month first)</li>
   * <li>MM/DD/YYYY: 02/21/2011, American format (month first)</li>
   * </ul>
   * @return
   */
  @Column(name = "excel_date_format", length = 20)
  public String getExcelDateFormat()
  {
    return excelDateFormat;
  }

  public void setExcelDateFormat(final String excelDateFormat)
  {
    this.excelDateFormat = excelDateFormat;
  }

  @Enumerated(EnumType.STRING)
  @Column(name = "time_notation", length = 6)
  public TimeNotation getTimeNotation()
  {
    return timeNotation;
  }

  /**
   * 0 - sunday, 1 - monday etc.
   * @return the firstDayOfWeek
   */
  @Column(name = "first_day_of_week")
  public Integer getFirstDayOfWeek()
  {
    return firstDayOfWeek;
  }

  /**
   * @param firstDayOfWeek the firstDayOfWeek to set
   * @return this for chaining.
   */
  public PFUserDO setFirstDayOfWeek(final Integer firstDayOfWeek)
  {
    this.firstDayOfWeek = firstDayOfWeek;
    return this;
  }

  public void setTimeNotation(final TimeNotation timeNotation)
  {
    this.timeNotation = timeNotation;
  }

  /**
   * Eine kommaseparierte Liste mit den Kennungen des/der Telefon(e) des Mitarbeiters an der unterstützten Telefonanlage, &zB; zur
   * Direktwahl aus ProjectForge heraus.
   */
  @Column(name = "personal_phone_identifiers", length = 255)
  public String getPersonalPhoneIdentifiers()
  {
    return personalPhoneIdentifiers;
  }

  public void setPersonalPhoneIdentifiers(final String personalPhoneIdentifiers)
  {
    this.personalPhoneIdentifiers = personalPhoneIdentifiers;
  }

  /**
   * A comma separated list of all personal mobile numbers from which SMS can be send. Those SMS will be assigned to this user. <br/>
   * This is a feature from the Mobile Enterprise Blogging.
   */
  @Column(name = "personal_meb_identifiers", length = 255)
  public String getPersonalMebMobileNumbers()
  {
    return personalMebMobileNumbers;
  }

  public void setPersonalMebMobileNumbers(final String personalMebMobileNumbers)
  {
    this.personalMebMobileNumbers = personalMebMobileNumbers;
  }

  /**
   * Returns string containing all fields (except the password) of given user object (via ReflectionToStringBuilder).
   * @param user
   * @return
   */
  @Override
  public String toString()
  {
    return (new ReflectionToString(this) {
      @Override
      protected boolean accept(final java.lang.reflect.Field f)
      {
        return super.accept(f)
            && !"password".equals(f.getName())
            && !"stayLoggedInKey".equals(f.getName())
            && !"passwordSalt".equals(f.getName())
            && !"authenticationToken".equals(f.getName());
      }
    }).toString();
  }

  @Transient
  public String getUserDisplayname()
  {
    final String str = getFullname();
    if (StringUtils.isNotBlank(str) == true) {
      return str + " (" + getUsername() + ")";
    }
    return getUsername();
  }

  @Override
  public boolean equals(final Object o)
  {
    if (o instanceof PFUserDO) {
      final PFUserDO other = (PFUserDO) o;
      if (ObjectUtils.equals(this.getUsername(), other.getUsername()) == false)
        return false;
      return true;
    }
    return false;
  }

  @Override
  public int hashCode()
  {
    return getUsername() == null ? 0 : getUsername().hashCode();
  }

  @Override
  public ModificationStatus copyValuesFrom(final BaseDO< ? extends Serializable> src, String... ignoreFields)
  {
    ignoreFields = (String[]) ArrayUtils.add(ignoreFields, "password"); // NPE save considering ignoreFields
    final PFUserDO user = (PFUserDO) src;
    ModificationStatus modificationStatus = AbstractBaseDO.copyValues(user, this, ignoreFields);
    if (user.getPassword() != null) {
      if (user.getPassword().equals(getPassword()) == false) {
        modificationStatus = ModificationStatus.MAJOR;
      }
      setPassword(user.getPassword());
      checkAndFixPassword();
    }
    return modificationStatus;
  }

  /**
   * If password is not given as "SHA{..." then it will be set to null due to security reasons.
   */
  protected void checkAndFixPassword()
  {
    if (StringUtils.isNotEmpty(getPassword()) == true
        && getPassword().startsWith("SHA{") == false
        && getPassword().equals(NOPASSWORD) == false) {
      setPassword(null);
      log.error("Password for user '" + getUsername() + "' is not given SHA encrypted. Ignoring it.");
    }
  }

  /**
   * The locale given from the client (e. g. from the browser by the http request). This locale is needed by PFUserContext for getting the
   * browser locale if the user's locale is null and the request's locale is not available.
   * @return
   */
  @Transient
  public Locale getClientLocale()
  {
    return clientLocale;
  }

  public PFUserDO setClientLocale(final Locale clientLocale)
  {
    this.clientLocale = clientLocale;
    return this;
  }

  /**
   * Do nothing.
   * @see org.projectforge.core.ExtendedBaseDO#recalculate()
   */
  @Override
  public void recalculate()
  {
  }

  @Override
  public Object getAttribute(final String key)
  {
    if (attributeMap == null) {
      return null;
    }
    return attributeMap.get(key);
  }

  @Override
  public void setAttribute(final String key, final Object value)
  {
    synchronized (this) {
      if (attributeMap == null) {
        attributeMap = new HashMap<String, Object>();
      }
      attributeMap.put(key, value);
    }
  }

  public void removeAttribute(final String key)
  {
    if (attributeMap == null) {
      return;
    }
    attributeMap.remove(key);
  }

  /**
   * @return Returns the username.
   */
  @Column(length = 255, nullable = false)
  public String getUsername()
  {
    return username;
  }

  /**
   * @param username The username to set.
   * @return this for chaining.
   */
  public PFUserDO setUsername(final String username)
  {
    this.username = username;
    return this;
  }

  /**
   * Die E-Mail Adresse des Benutzers, falls vorhanden.
   * @return Returns the email.
   */
  @Column(length = 255)
  public String getEmail()
  {
    return email;
  }

  /**
   * @param email The email to set.
   * @return this for chaining.
   */
  public PFUserDO setEmail(final String email)
  {
    Validate.isTrue(email == null || email.length() <= 255, email);
    this.email = email;
    return this;
  }

  /**
   * Key stored in the cookies for the functionality of stay logged in.
   */
  @Column(name = "stay_logged_in_key", length = 255)
  public String getStayLoggedInKey()
  {
    return stayLoggedInKey;
  }

  public void setStayLoggedInKey(final String stayLoggedInKey)
  {
    this.stayLoggedInKey = stayLoggedInKey;
  }

  /**
   * @return the saltString for giving salt to hashed password.
   */
  @Column(name = "password_salt", length = 40)
  public String getPasswordSalt()
  {
    return passwordSalt;
  }

  /**
   * @param passwordSalt the saltString to set
   * @return this for chaining.
   */
  public PFUserDO setPasswordSalt(final String passwordSalt)
  {
    this.passwordSalt = passwordSalt;
    return this;
  }

  /**
   * The authentication token is usable for download links of the user (without further login). This is used e. g. for ics download links of
   * the team calendars.
   * @return the authenticationToken
   */
  @Column(name = "authentication_token", length = 100)
  public String getAuthenticationToken()
  {
    return authenticationToken;
  }

  /**
   * @param authenticationToken the authenticationToken to set
   * @return this for chaining.
   */
  public PFUserDO setAuthenticationToken(final String authenticationToken)
  {
    this.authenticationToken = authenticationToken;
    return this;
  }

  /**
   * Der Vorname des Benutzer.
   * @return Returns the firstname.
   */
  @Column(length = 255)
  public String getFirstname()
  {
    return firstname;
  }

  /**
   * @param firstname The firstname to set.
   * @return this for chaining.
   */
  public PFUserDO setFirstname(final String firstname)
  {
    Validate.isTrue(firstname == null || firstname.length() <= 255, firstname);
    this.firstname = firstname;
    return this;
  }

  /**
   * Gibt den Vor- und Nachnamen zurück, falls gegeben. Vor- und Nachname sind durch ein Leerzeichen getrennt.
   * @return String
   */
  @Transient
  public String getFullname()
  {
    final StringBuffer name = new StringBuffer();
    if (this.firstname != null) {
      name.append(this.firstname);
      name.append(" ");
    }
    if (this.lastname != null) {
      name.append(this.lastname);
    }

    return name.toString();
  }

  /**
   * Zeitstempel des letzten erfolgreichen Logins.
   * @return Returns the lastLogin.
   */
  @Column
  public Timestamp getLastLogin()
  {
    return lastLogin;
  }

  /**
   * @return Returns the lastname.
   */
  @Column(length = 255)
  public String getLastname()
  {
    return lastname;
  }

  /**
   * @return Returns the description.
   */
  @Column(length = 255)
  public String getDescription()
  {
    return description;
  }

  /**
   * @param description The description to set.
   * @return this for chaining.
   */
  public PFUserDO setDescription(final String description)
  {
    Validate.isTrue(description == null || description.length() <= 255, description);
    this.description = description;
    return this;
  }

  /**
   * Die Anzahl der erfolglosen Logins. Dieser Wert wird bei dem nächsten erfolgreichen Login auf 0 zurück gesetzt.
   * @return Returns the loginFailures.
   */
  @Column
  public int getLoginFailures()
  {
    return loginFailures;
  }

  /**
   * JIRA user name (if differ from the ProjectForge's user name) is used e. g. in MEB for creating new issues.
   */
  @Column(name = "jira_username", length = 100)
  public String getJiraUsername()
  {
    return jiraUsername;
  }

  public void setJiraUsername(final String jiraUsername)
  {
    this.jiraUsername = jiraUsername;
  }

  /**
   * @return The JIRA user name or if not given the user name (assuming that the JIRA user name is same as ProjectForge user name).
   */
  @Transient
  public String getJiraUsernameOrUsername()
  {
    if (StringUtils.isNotEmpty(jiraUsername) == true) {
      return this.jiraUsername;
    } else {
      return this.username;
    }
  }

  /**
   * Encoded password of the user (SHA-1).
   * @return Returns the password.
   */
  @Column(length = 50)
  public String getPassword()
  {
    return password;
  }

  /**
   * @param password The password to set.
   * @return this for chaining.
   */
  public PFUserDO setPassword(final String password)
  {
    this.password = password;
    return this;
  }

  /**
   * @param password The password to set.
   * @return this for chaining.
   */
  public PFUserDO setNoPassword()
  {
    this.password = NOPASSWORD;
    return this;
  }

  /**
   * @return the lastPasswordChange.
   */
  @Column(name = "last_password_change")
  public Date getLastPasswordChange()
  {
    return lastPasswordChange;
  }

  /**
   * @param lastPasswordChange the lastPasswordChange to set
   * @return this for chaining.
   */
  public PFUserDO setLastPasswordChange(final Date lastPasswordChange)
  {
    this.lastPasswordChange = lastPasswordChange;
    return this;
  }

  /**
   * @param lastLogin The lastLogin to set.
   */
  public void setLastLogin(final Timestamp lastLogin)
  {
    this.lastLogin = lastLogin;
  }

  /**
   * @param lastname The lastname to set.
   * @return this for chaining.
   */
  public PFUserDO setLastname(final String lastname)
  {
    this.lastname = lastname;
    return this;
  }

  /**
   * @param loginFailures The loginFailures to set.
   */
  public void setLoginFailures(final int loginFailures)
  {
    this.loginFailures = loginFailures;
  }

  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true, mappedBy = "user")
  public Set<UserRightDO> getRights()
  {
    return this.rights;
  }

  public void setRights(final Set<UserRightDO> rights)
  {
    this.rights = rights;
  }

  public PFUserDO addRight(final UserRightDO right)
  {
    if (this.rights == null) {
      setRights(new HashSet<UserRightDO>());
    }
    this.rights.add(right);
    right.setUser(this);
    return this;
  }

  @Transient
  public UserRightDO getRight(final UserRightId rightId)
  {
    if (this.rights == null) {
      return null;
    }
    for (final UserRightDO right : this.rights) {
      if (right.getRightId().equals(rightId) == true) {
        return right;
      }
    }
    return null;
  }

  /**
   * If true (default) then the user is highlighted in the human resource planning page if not planned for the actual week.
   * @return the hrPlanning
   */
  @Column(name = "hr_planning", nullable = false)
  public boolean isHrPlanning()
  {
    return hrPlanning;
  }

  /**
   * @param hrPlanning the hrPlanning to set
   * @return this for chaining.
   */
  public PFUserDO setHrPlanning(final boolean hrPlanning)
  {
    this.hrPlanning = hrPlanning;
    return this;
  }

  /**
   * A local user will not be synchronized with any external user management system.
   * @return the localUser
   */
  @Column(name = "local_user", nullable = false)
  public boolean isLocalUser()
  {
    return localUser;
  }

  /**
   * @param localUser the localUser to set
   * @return this for chaining.
   */
  public PFUserDO setLocalUser(final boolean localUser)
  {
    this.localUser = localUser;
    return this;
  }

  /**
   * A restricted user has only the ability to log-in and to change his password. This is useful if ProjectForge runs in master mode for
   * managing an external LDAP system. Then this user is a LDAP user but has no other functionality than change password in the ProjectForge
   * system itself.
   * @return the restrictedUser
   */
  @Column(name = "restricted_user", nullable = false)
  public boolean isRestrictedUser()
  {
    return restrictedUser;
  }

  /**
   * @param restrictedUser the restrictedUser to set
   * @return this for chaining.
   */
  public PFUserDO setRestrictedUser(final boolean restrictedUser)
  {
    this.restrictedUser = restrictedUser;
    return this;
  }

  /**
   * A deactivated user has no more system access.
   * @return the deactivated
   */
  @Column(nullable = false)
  public boolean isDeactivated()
  {
    return deactivated;
  }

  /**
   * @param deactivated the deactivated to set
   * @return this for chaining.
   */
  public PFUserDO setDeactivated(final boolean deactivated)
  {
    this.deactivated = deactivated;
    return this;
  }

  /**
   * LDAP values as key-value-pairs, e. g. gidNumber=1000,uidNumber=1001,homeDirectory="/home/kai",shell="/bin/bash". For handling of string
   * values see {@link org.apache.commons.csv.writer.CSVWriter}. This field is handled by the ldap package and has no further effect in
   * ProjectForge's core package.
   * @return the ldapValues
   */
  @Column(name = "ldap_values", length = 4000)
  public String getLdapValues()
  {
    return ldapValues;
  }

  /**
   * @param ldapValues the ldapValues to set
   * @return this for chaining.
   */
  public PFUserDO setLdapValues(final String ldapValues)
  {
    this.ldapValues = ldapValues;
    return this;
  }

  /**
   * @return the sshPublicKey
   */
  @Column(name = "ssh_public_key", length = 1000)
  public String getSshPublicKey()
  {
    return sshPublicKey;
  }

  /**
   * @param sshPublicKey the sshPublicKey to set
   * @return this for chaining.
   */
  public PFUserDO setSshPublicKey(final String sshPublicKey)
  {
    this.sshPublicKey = sshPublicKey;
    return this;
  }

  /**
   * @return true only and only if the user isn't either deleted nor deactivated, otherwise false.
   */
  @Transient
  public boolean hasSystemAccess()
  {
    return isDeleted() == false && isDeactivated() == false;
  }

  @Transient
  public String getDisplayUsername()
  {
    return getShortDisplayName();
  }
}
TOP

Related Classes of org.projectforge.user.PFUserDO

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.