Coverage Report - org.apache.shiro.authc.SimpleAuthenticationInfo
 
Classes in this File Line Coverage Branch Coverage Complexity
SimpleAuthenticationInfo
67%
41/61
35%
12/34
2.467
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.shiro.authc;
 20  
 
 21  
 import org.apache.shiro.subject.MutablePrincipalCollection;
 22  
 import org.apache.shiro.subject.PrincipalCollection;
 23  
 import org.apache.shiro.subject.SimplePrincipalCollection;
 24  
 import org.apache.shiro.util.ByteSource;
 25  
 
 26  
 import java.util.Collection;
 27  
 import java.util.HashSet;
 28  
 import java.util.Set;
 29  
 
 30  
 
 31  
 /**
 32  
  * Simple implementation of the {@link org.apache.shiro.authc.MergableAuthenticationInfo} interface that holds the principals and
 33  
  * credentials.
 34  
  *
 35  
  * @see org.apache.shiro.realm.AuthenticatingRealm
 36  
  * @since 0.9
 37  
  */
 38  
 public class SimpleAuthenticationInfo implements MergableAuthenticationInfo, SaltedAuthenticationInfo {
 39  
 
 40  
     /**
 41  
      * The principals identifying the account associated with this AuthenticationInfo instance.
 42  
      */
 43  
     protected PrincipalCollection principals;
 44  
     /**
 45  
      * The credentials verifying the account principals.
 46  
      */
 47  
     protected Object credentials;
 48  
 
 49  
     /**
 50  
      * Any salt used in hashing the credentials.
 51  
      *
 52  
      * @since 1.1
 53  
      */
 54  
     protected ByteSource credentialsSalt;
 55  
 
 56  
     /**
 57  
      * Default no-argument constructor.
 58  
      */
 59  5
     public SimpleAuthenticationInfo() {
 60  5
     }
 61  
 
 62  
     /**
 63  
      * Constructor that takes in a single 'primary' principal of the account and its corresponding credentials,
 64  
      * associated with the specified realm.
 65  
      * <p/>
 66  
      * This is a convenience constructor and will construct a {@link PrincipalCollection PrincipalCollection} based
 67  
      * on the {@code principal} and {@code realmName} argument.
 68  
      *
 69  
      * @param principal   the 'primary' principal associated with the specified realm.
 70  
      * @param credentials the credentials that verify the given principal.
 71  
      * @param realmName   the realm from where the principal and credentials were acquired.
 72  
      */
 73  29
     public SimpleAuthenticationInfo(Object principal, Object credentials, String realmName) {
 74  29
         this.principals = new SimplePrincipalCollection(principal, realmName);
 75  29
         this.credentials = credentials;
 76  29
     }
 77  
 
 78  
     /**
 79  
      * Constructor that takes in a single 'primary' principal of the account, its corresponding hashed credentials,
 80  
      * the salt used to hash the credentials, and the name of the realm to associate with the principals.
 81  
      * <p/>
 82  
      * This is a convenience constructor and will construct a {@link PrincipalCollection PrincipalCollection} based
 83  
      * on the <code>principal</code> and <code>realmName</code> argument.
 84  
      *
 85  
      * @param principal         the 'primary' principal associated with the specified realm.
 86  
      * @param hashedCredentials the hashed credentials that verify the given principal.
 87  
      * @param credentialsSalt   the salt used when hashing the given hashedCredentials
 88  
      * @param realmName         the realm from where the principal and credentials were acquired.
 89  
      * @see org.apache.shiro.authc.credential.HashedCredentialsMatcher HashedCredentialsMatcher
 90  
      * @since 1.1
 91  
      */
 92  1
     public SimpleAuthenticationInfo(Object principal, Object hashedCredentials, ByteSource credentialsSalt, String realmName) {
 93  1
         this.principals = new SimplePrincipalCollection(principal, realmName);
 94  1
         this.credentials = hashedCredentials;
 95  1
         this.credentialsSalt = credentialsSalt;
 96  1
     }
 97  
 
 98  
     /**
 99  
      * Constructor that takes in an account's identifying principal(s) and its corresponding credentials that verify
 100  
      * the principals.
 101  
      *
 102  
      * @param principals  a Realm's account's identifying principal(s)
 103  
      * @param credentials the accounts corresponding principals that verify the principals.
 104  
      */
 105  40
     public SimpleAuthenticationInfo(PrincipalCollection principals, Object credentials) {
 106  40
         this.principals = new SimplePrincipalCollection(principals);
 107  40
         this.credentials = credentials;
 108  40
     }
 109  
 
 110  
     /**
 111  
      * Constructor that takes in an account's identifying principal(s), hashed credentials used to verify the
 112  
      * principals, and the salt used when hashing the credentials.
 113  
      *
 114  
      * @param principals        a Realm's account's identifying principal(s)
 115  
      * @param hashedCredentials the hashed credentials that verify the principals.
 116  
      * @param credentialsSalt   the salt used when hashing the hashedCredentials.
 117  
      * @see org.apache.shiro.authc.credential.HashedCredentialsMatcher HashedCredentialsMatcher
 118  
      * @since 1.1
 119  
      */
 120  0
     public SimpleAuthenticationInfo(PrincipalCollection principals, Object hashedCredentials, ByteSource credentialsSalt) {
 121  0
         this.principals = new SimplePrincipalCollection(principals);
 122  0
         this.credentials = hashedCredentials;
 123  0
         this.credentialsSalt = credentialsSalt;
 124  0
     }
 125  
 
 126  
 
 127  
     public PrincipalCollection getPrincipals() {
 128  173
         return principals;
 129  
     }
 130  
 
 131  
     /**
 132  
      * Sets the identifying principal(s) represented by this instance.
 133  
      *
 134  
      * @param principals the indentifying attributes of the corresponding Realm account.
 135  
      */
 136  
     public void setPrincipals(PrincipalCollection principals) {
 137  2
         this.principals = principals;
 138  2
     }
 139  
 
 140  
     public Object getCredentials() {
 141  31
         return credentials;
 142  
     }
 143  
 
 144  
     /**
 145  
      * Sets the credentials that verify the principals/identity of the associated Realm account.
 146  
      *
 147  
      * @param credentials attribute(s) that verify the account's identity/principals, such as a password or private key.
 148  
      */
 149  
     public void setCredentials(Object credentials) {
 150  37
         this.credentials = credentials;
 151  37
     }
 152  
 
 153  
     /**
 154  
      * Returns the salt used to hash the credentials, or {@code null} if no salt was used or credentials were not
 155  
      * hashed at all.
 156  
      * <p/>
 157  
      * Note that this attribute is <em>NOT</em> handled in the
 158  
      * {@link #merge(AuthenticationInfo) merge} method - a hash salt is only useful within a single realm (as each
 159  
      * realm will perform it's own Credentials Matching logic), and once finished in that realm, Shiro has no further
 160  
      * use for salts.  Therefore it doesn't make sense to 'merge' salts in a multi-realm scenario.
 161  
      *
 162  
      * @return the salt used to hash the credentials, or {@code null} if no salt was used or credentials were not
 163  
      *         hashed at all.
 164  
      * @since 1.1
 165  
      */
 166  
     public ByteSource getCredentialsSalt() {
 167  20
         return credentialsSalt;
 168  
     }
 169  
 
 170  
     /**
 171  
      * Sets the salt used to hash the credentials, or {@code null} if no salt was used or credentials were not
 172  
      * hashed at all.
 173  
      * <p/>
 174  
      * Note that this attribute is <em>NOT</em> handled in the
 175  
      * {@link #merge(AuthenticationInfo) merge} method - a hash salt is only useful within a single realm (as each
 176  
      * realm will perform it's own Credentials Matching logic), and once finished in that realm, Shiro has no further
 177  
      * use for salts.  Therefore it doesn't make sense to 'merge' salts in a multi-realm scenario.
 178  
      *
 179  
      * @param salt the salt used to hash the credentials, or {@code null} if no salt was used or credentials were not
 180  
      *             hashed at all.
 181  
      * @since 1.1
 182  
      */
 183  
     public void setCredentialsSalt(ByteSource salt) {
 184  4
         this.credentialsSalt = salt;
 185  4
     }
 186  
 
 187  
     /**
 188  
      * Takes the specified <code>info</code> argument and adds its principals and credentials into this instance.
 189  
      *
 190  
      * @param info the <code>AuthenticationInfo</code> to add into this instance.
 191  
      */
 192  
     @SuppressWarnings("unchecked")
 193  
     public void merge(AuthenticationInfo info) {
 194  3
         if (info == null || info.getPrincipals() == null || info.getPrincipals().isEmpty()) {
 195  1
             return;
 196  
         }
 197  
 
 198  2
         if (this.principals == null) {
 199  1
             this.principals = info.getPrincipals();
 200  
         } else {
 201  1
             if (!(this.principals instanceof MutablePrincipalCollection)) {
 202  1
                 this.principals = new SimplePrincipalCollection(this.principals);
 203  
             }
 204  1
             ((MutablePrincipalCollection) this.principals).addAll(info.getPrincipals());
 205  
         }
 206  
 
 207  
         //only mess with a salt value if we don't have one yet.  It doesn't make sense
 208  
         //to merge salt values from different realms because a salt is used only within
 209  
         //the realm's credential matching process.  But if the current instance's salt
 210  
         //is null, then it can't hurt to pull in a non-null value if one exists.
 211  
         //
 212  
         //since 1.1:
 213  2
         if (this.credentialsSalt == null && info instanceof SaltedAuthenticationInfo) {
 214  2
             this.credentialsSalt = ((SaltedAuthenticationInfo) info).getCredentialsSalt();
 215  
         }
 216  
 
 217  2
         Object thisCredentials = getCredentials();
 218  2
         Object otherCredentials = info.getCredentials();
 219  
 
 220  2
         if (otherCredentials == null) {
 221  0
             return;
 222  
         }
 223  
 
 224  2
         if (thisCredentials == null) {
 225  2
             this.credentials = otherCredentials;
 226  2
             return;
 227  
         }
 228  
 
 229  0
         if (!(thisCredentials instanceof Collection)) {
 230  0
             Set newSet = new HashSet();
 231  0
             newSet.add(thisCredentials);
 232  0
             setCredentials(newSet);
 233  
         }
 234  
 
 235  
         // At this point, the credentials should be a collection
 236  0
         Collection credentialCollection = (Collection) getCredentials();
 237  0
         if (otherCredentials instanceof Collection) {
 238  0
             credentialCollection.addAll((Collection) otherCredentials);
 239  
         } else {
 240  0
             credentialCollection.add(otherCredentials);
 241  
         }
 242  0
     }
 243  
 
 244  
     /**
 245  
      * Returns <code>true</code> if the Object argument is an <code>instanceof SimpleAuthenticationInfo</code> and
 246  
      * its {@link #getPrincipals() principals} are equal to this instance's principals, <code>false</code> otherwise.
 247  
      *
 248  
      * @param o the object to compare for equality.
 249  
      * @return <code>true</code> if the Object argument is an <code>instanceof SimpleAuthenticationInfo</code> and
 250  
      *         its {@link #getPrincipals() principals} are equal to this instance's principals, <code>false</code> otherwise.
 251  
      */
 252  
     public boolean equals(Object o) {
 253  1
         if (this == o) return true;
 254  0
         if (!(o instanceof SimpleAuthenticationInfo)) return false;
 255  
 
 256  0
         SimpleAuthenticationInfo that = (SimpleAuthenticationInfo) o;
 257  
 
 258  
         //noinspection RedundantIfStatement
 259  0
         if (principals != null ? !principals.equals(that.principals) : that.principals != null) return false;
 260  
 
 261  0
         return true;
 262  
     }
 263  
 
 264  
     /**
 265  
      * Returns the hashcode of the internal {@link #getPrincipals() principals} instance.
 266  
      *
 267  
      * @return the hashcode of the internal {@link #getPrincipals() principals} instance.
 268  
      */
 269  
     public int hashCode() {
 270  0
         return (principals != null ? principals.hashCode() : 0);
 271  
     }
 272  
 
 273  
     /**
 274  
      * Simple implementation that merely returns <code>{@link #getPrincipals() principals}.toString()</code>
 275  
      *
 276  
      * @return <code>{@link #getPrincipals() principals}.toString()</code>
 277  
      */
 278  
     public String toString() {
 279  42
         return principals.toString();
 280  
     }
 281  
 
 282  
 }