All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.passay.PasswordData Maven / Gradle / Ivy

There is a newer version: 1.6.6
Show newest version
/* See LICENSE for licensing and NOTICE for copyright. */
package org.passay;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Contains password related information used by rules to perform password validation.
 *
 * @author  Middleware Services
 */
public class PasswordData
{

  /** Enum to define the origin of a password. */
  public enum Origin {

    /** a password which was generated by a typical human user. */
    User,

    /** a password which was generated by a sufficient random source. */
    Generated
  }

  /** Stores the password. */
  private String password;

  /** Stores the username. */
  private String username;

  /** Password references. */
  private List passwordReferences = new ArrayList<>();

  /** Origin of this password. */
  private Origin origin = Origin.User;


  /** Default constructor. */
  public PasswordData() {}


  /**
   * Creates a new password data. The origin of this data is assumed to be {@link Origin#User} by default.
   *
   * @param  p  password
   */
  public PasswordData(final String p)
  {
    setPassword(p);
  }


  /**
   * Creates a new password data. The origin of this data is assumed to be {@link Origin#User} by default.
   *
   * @param  u  username
   * @param  p  password
   */
  public PasswordData(final String u, final String p)
  {
    setUsername(u);
    setPassword(p);
  }


  /**
   * Creates a new password data.
   *
   * @param  p  password
   * @param  o  origin
   */
  public PasswordData(final String p, final Origin o)
  {
    setPassword(p);
    setOrigin(o);
  }


  /**
   * Creates a new password data.
   *
   * @param  u  username
   * @param  p  password
   * @param  o  origin
   */
  public PasswordData(final String u, final String p, final Origin o)
  {
    setUsername(u);
    setPassword(p);
    setOrigin(o);
  }


  /**
   * Creates a new password data.
   *
   * @param  u  username
   * @param  p  password
   * @param  r  references
   */
  public PasswordData(final String u, final String p, final List r)
  {
    setUsername(u);
    setPassword(p);
    setPasswordReferences(r);
  }


  /**
   * Sets the password.
   *
   * @param  p  password
   */
  public void setPassword(final String p)
  {
    if (p == null) {
      throw new NullPointerException("Password cannot be null");
    }
    password = p;
  }


  /**
   * Returns the password.
   *
   * @return  password
   */
  public String getPassword()
  {
    return password;
  }


  /**
   * Sets the origin.
   *
   * @param  o  origin
   */
  public void setOrigin(final Origin o)
  {
    if (o == null) {
      throw new NullPointerException("Origin cannot be null");
    }
    origin = o;
  }


  /**
   * Returns the origin.
   *
   * @return  origin
   */
  public Origin getOrigin()
  {
    return origin;
  }


  /**
   * Sets the username.
   *
   * @param  s  username
   */
  public void setUsername(final String s)
  {
    if (s == null) {
      throw new NullPointerException("Username cannot be null");
    }
    username = s;
  }


  /**
   * Returns the username.
   *
   * @return  username
   */
  public String getUsername()
  {
    return username;
  }


  /**
   * Returns the password references.
   *
   * @return  password references
   */
  public List getPasswordReferences()
  {
    return passwordReferences;
  }


  /**
   * Returns the password references that match the supplied reference type.
   *
   * @param    type of password reference
   * @param  type  of reference to match
   *
   * @return  unmodifiable list of password references
   */
  @SuppressWarnings("unchecked")
  public  List getPasswordReferences(final Class type)
  {
    final List l = new ArrayList<>();
    if (passwordReferences != null) {
      l.addAll(passwordReferences.stream().filter(
        type::isInstance).map(r -> (T) r).collect(Collectors.toList()));
    }
    return Collections.unmodifiableList(l);
  }


  /**
   * Sets the password references.
   *
   * @param  r  password references
   */
  public void setPasswordReferences(final Reference... r)
  {
    setPasswordReferences(Arrays.asList(r));
  }


  /**
   * Sets the password references.
   *
   * @param  l  password references
   */
  public void setPasswordReferences(final List l)
  {
    passwordReferences = l;
  }


  /**
   * Returns a password data initialized with the supplied data.
   *
   * @param  data  password data to read properties from
   *
   * @return  password data
   */
  public static PasswordData newPasswordData(final PasswordData data)
  {
    final PasswordData pd = new PasswordData();
    pd.setUsername(data.getUsername());
    pd.setPassword(data.getPassword());
    pd.setPasswordReferences(data.getPasswordReferences());
    pd.setOrigin(data.getOrigin());
    return pd;
  }


  @Override
  public String toString()
  {
    return
      String.format(
        "%s@%h::username=%s,password=%s,origin=%s,passwordReferences=%s",
        getClass().getName(),
        hashCode(),
        username,
        password,
        origin,
        passwordReferences);
  }


  /**
   * Combines salt (additional external data) with a password
   * before applying a digest algorithm to them.
   */
  public interface Salt
  {

    /**
     * Applies the salt to the password, returning the combined string to be digested.
     *
     * @param password the cleartext password to apply the salt to
     * @return the salted password
     */
    String applyTo(String password);
  }


  /**
   * A salt that is concatenated as a prefix to the password data.
   */
  public static class PrefixSalt implements Salt
  {

    /** The salt data. */
    private final String salt;

    /**
     * Creates a new salt with the given salt data.
     *
     * @param slt the salt data
     */
    public PrefixSalt(final String slt)
    {
      salt = slt;
    }

    @Override
    public String applyTo(final String password)
    {
      return salt + password;
    }
  }


  /**
   * A salt that is concatenated as a suffix to the password data.
   */
  public static class SuffixSalt implements Salt
  {

    /** The salt data. */
    private final String salt;

    /**
     * Creates a new salt with the given salt data.
     *
     * @param slt the salt data
     */
    public SuffixSalt(final String slt)
    {
      salt = slt;
    }

    @Override
    public String applyTo(final String password)
    {
      return password + salt;
    }
  }


  /** Reference to another password. */
  public interface Reference
  {

    /**
     * Returns the password associated with this reference.
     *
     * @return  password string
     */
    String getPassword();

    /**
     * Returns the salt that was applied to the reference password before digesting it.
     *
     * @return  salt  the salt that was applied to the password,
     *          or null if no salt was applied
     */
    default Salt getSalt()
    {
      return null;
    }
  }


  /** Reference to an historical password. */
  public static class HistoricalReference extends AbstractReference
  {


    /**
     * Creates a new historical reference.
     *
     * @param  pass  password string
     */
    public HistoricalReference(final String pass)
    {
      super(null, pass);
    }


    /**
     * Creates a new historical reference.
     *
     * @param  lbl  label for this password
     * @param  pass  password string
     */
    public HistoricalReference(final String lbl, final String pass)
    {
      super(lbl, pass);
    }


    /**
     * Creates a new historical reference.
     *
     * @param  lbl  label for this password
     * @param  pass  password string
     * @param  slt  salt that was applied to password
     */
    public HistoricalReference(final String lbl, final String pass, final Salt slt)
    {
      super(lbl, pass, slt);
    }
  }


  /** Reference to a source password. */
  public static class SourceReference extends AbstractReference
  {


    /**
     * Creates a new source reference.
     *
     * @param  pass  password string
     */
    public SourceReference(final String pass)
    {
      super(null, pass);
    }


    /**
     * Creates a new source reference.
     *
     * @param  lbl  label for this password
     * @param  pass  password string
     */
    public SourceReference(final String lbl, final String pass)
    {
      super(lbl, pass);
    }


    /**
     * Creates a new source reference.
     *
     * @param  lbl  label for this password
     * @param  pass  password string
     * @param  slt  salt that was applied to password
     */
    public SourceReference(final String lbl, final String pass, final Salt slt)
    {
      super(lbl, pass, slt);
    }
  }


  /** Common password reference implementation. */
  public abstract static class AbstractReference implements Reference
  {

    /** Label to identify this password. */
    private final String label;

    /** Reference password. */
    private final String password;

    /** Salt that was applied to reference password before digesting it. */
    private final Salt salt;


    /**
     * Creates a new abstract reference.
     *
     * @param  lbl  label for this password
     * @param  pass  password string
     * @param  slt  salt that was applied to password
     */
    public AbstractReference(final String lbl, final String pass, final Salt slt)
    {
      label = lbl;
      password = pass;
      salt = slt;
    }


    /**
     * Creates a new abstract reference.
     *
     * @param  lbl  label for this password
     * @param  pass  password string
     */
    public AbstractReference(final String lbl, final String pass)
    {
      this(lbl, pass, null);
    }


    /**
     * Returns the label.
     *
     * @return  reference label
     */
    public String getLabel()
    {
      return label;
    }


    @Override
    public String getPassword()
    {
      return password;
    }


    @Override
    public Salt getSalt()
    {
      return salt;
    }


    @Override
    public String toString()
    {
      return String.format("%s@%h::label=%s,password=%s", getClass().getName(), hashCode(), label, password);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy