1   package com.atlassian.user.security.password;
2   
3   /**
4    * Represents a user's password. Allows the same methods to take both encrypted and unencrypted credentials.
5    *
6    * @since 2.2
7    */
8   public final class Credential
9   {
10      /**
11       * The null or empty credential, which is encrypted and has an invalid hash so it can never be authenticated against.
12       */
13      public static final Credential NONE = Credential.encrypted("x");
14  
15      private final boolean encrypted;
16      private final String value;
17  
18      public static Credential encrypted(String hash)
19      {
20          return new Credential(true, hash);
21      }
22  
23      public static Credential unencrypted(String password)
24      {
25          return new Credential(false, password);
26      }
27  
28      private Credential(boolean encrypted, String value)
29      {
30          if (value == null) throw new IllegalArgumentException("Credential value cannot be null. Use Credential.NONE instead.");
31          this.encrypted = encrypted;
32          this.value = value;
33      }
34  
35      /**
36       * Returns {@code true} if the string returned by {@link #getValue()} is an encrypted hash of the password,
37       * rather than the plaintext password itself.
38       */
39      public boolean isEncrypted()
40      {
41          return encrypted;
42      }
43  
44      /**
45       * Returns the password, either in plain text if {@link #isEncrypted()} returns false, or as a SHA1-512
46       * hash if {@link #isEncrypted()} returns true.
47       */
48      public String getValue()
49      {
50          return value;
51      }
52  
53      @Override
54      public boolean equals(Object o)
55      {
56          if (this == o) return true;
57          if (o == null || getClass() != o.getClass()) return false;
58  
59          Credential that = (Credential) o;
60          return encrypted == that.encrypted && value.equals(that.value);
61      }
62  
63      @Override
64      public int hashCode()
65      {
66          return 31 * (encrypted ? 1 : 0) + value.hashCode();
67      }
68  }