Coverage report

  %line %branch
org.apache.jetspeed.security.spi.impl.ldap.LdapUserCredentialDaoImpl
0% 
0% 

 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.jetspeed.security.spi.impl.ldap;
 18  
 
 19  
 import java.util.Hashtable;
 20  
 
 21  
 import javax.naming.AuthenticationException;
 22  
 import javax.naming.Context;
 23  
 import javax.naming.InitialContext;
 24  
 import javax.naming.NamingEnumeration;
 25  
 import javax.naming.NamingException;
 26  
 import javax.naming.directory.Attribute;
 27  
 import javax.naming.directory.Attributes;
 28  
 import javax.naming.directory.BasicAttributes;
 29  
 import javax.naming.directory.DirContext;
 30  
 import javax.naming.directory.SearchControls;
 31  
 import javax.naming.directory.SearchResult;
 32  
 
 33  
 import org.apache.commons.lang.StringUtils;
 34  
 import org.apache.commons.logging.Log;
 35  
 import org.apache.commons.logging.LogFactory;
 36  
 import org.apache.jetspeed.i18n.KeyedMessage;
 37  
 import org.apache.jetspeed.security.SecurityException;
 38  
 
 39  
 /**
 40  
  * @see org.apache.jetspeed.security.spi.impl.ldap.LdapUserCredentialDao
 41  
  * @author <a href="mailto:mike.long@dataline.com">Mike Long </a>, <a href="mailto:dlestrat@apache.org">David Le Strat</a>
 42  
  */
 43  
 public class LdapUserCredentialDaoImpl extends AbstractLdapDao implements LdapUserCredentialDao
 44  
 {
 45  
     /** The logger. */
 46  0
     private static final Log logger = LogFactory.getLog(LdapUserCredentialDaoImpl.class);
 47  
 
 48  
     /** The password attribute. */ 
 49  
     
 50  
     /**
 51  
      * <p>
 52  
      * Default constructor.
 53  
      * </p>
 54  
      *
 55  
      * @throws SecurityException A {@link SecurityException}.
 56  
      */
 57  
     public LdapUserCredentialDaoImpl() throws SecurityException
 58  
     {
 59  0
         super();
 60  0
     }
 61  
     
 62  
     /**
 63  
      * <p>
 64  
      * Initializes the dao.
 65  
      * </p>
 66  
      * 
 67  
      * @param ldapConfig Holds the ldap binding configuration.
 68  
      * 
 69  
      * @throws SecurityException A {@link SecurityException}.
 70  
      */
 71  
     public LdapUserCredentialDaoImpl(LdapBindingConfig ldapConfig) throws SecurityException
 72  
     {
 73  0
         super(ldapConfig);
 74  0
     }    
 75  
     
 76  
     /**
 77  
      * <p>
 78  
      * Updates the password for the specified user.
 79  
      * </p>
 80  
      */
 81  
     public void changePassword(final String uid, class="keyword">final String password) throws SecurityException
 82  
     {
 83  0
         validateUid(uid);
 84  0
         validatePassword(password);
 85  0
         logger.debug("changePassword for " + uid + " with " + password);
 86  0
         String userDn = lookupByUid(uid);
 87  0
         logger.debug("userDn = " + userDn);
 88  
         try
 89  
         {
 90  0
             setPassword(userDn, password);
 91  
         }
 92  0
         catch (NamingException e)
 93  
         {
 94  0
             throw new SecurityException(e);
 95  0
         }
 96  0
     }
 97  
 
 98  
     /**
 99  
      * <p>
 100  
      * Looks up the user by the UID attribute. If this lookup succeeds, this
 101  
      * method then attempts to authenticate the user using the password,
 102  
      * throwing an AuthenticationException if the password is incorrect or an
 103  
      * OperationNotSupportedException if the password is empty.
 104  
      * </p>
 105  
      * 
 106  
      * @param uid The uid.
 107  
      * @param password The password.
 108  
      * @throws SecurityException Throws a {@link SecurityException}.
 109  
      */	
 110  
     public boolean authenticate(final String uid, class="keyword">final String password) throws SecurityException
 111  
     {
 112  0
         validateUid(uid);
 113  0
         validatePassword(password);
 114  
         try
 115  
         {
 116  0
 			Hashtable env = this.ctx.getEnvironment();
 117  
 			//String savedPassword = String.valueOf(getPassword(uid));
 118  0
 			String oldCredential = (String)env.get(Context.SECURITY_CREDENTIALS);
 119  0
 			String oldUsername = (String)env.get(Context.SECURITY_PRINCIPAL);
 120  
 						
 121  0
 			String dn = lookupByUid(uid);
 122  0
             if ( dn == null )
 123  0
 				throw new SecurityException(class="keyword">new KeyedMessage("User " + uid + " not found"));
 124  
             
 125  
             // Build user dn using lookup value, just appending the user filter after the uid won't work when users
 126  
             // are/can be stored in a subtree (searchScope sub-tree)
 127  
             // The looked up dn though is/should always be correct, just need to append the root context.
 128  0
             if (!StringUtils.isEmpty(getRootContext()))
 129  0
                 dn +="," + getRootContext();
 130  
 			
 131  0
 			env.put(Context.SECURITY_PRINCIPAL,dn);
 132  0
 			env.put(Context.SECURITY_CREDENTIALS,password);
 133  0
 			new InitialContext(env);
 134  0
 			env.put(Context.SECURITY_PRINCIPAL,oldUsername);
 135  0
 			env.put(Context.SECURITY_CREDENTIALS,oldCredential);
 136  0
 			return true;
 137  
 		}
 138  0
 		catch (AuthenticationException e)
 139  
 		{
 140  0
 			return false;
 141  
 		}
 142  0
 		catch (NamingException e)
 143  
 		{
 144  0
 			throw new SecurityException(e);
 145  
 		}
 146  
     }
 147  
 
 148  
     /**
 149  
      * @see org.apache.jetspeed.security.spi.impl.ldap.LdapUserCredentialDao#getPassword(java.lang.String)
 150  
      */
 151  
     public char[] getPassword(final String uid) throws SecurityException
 152  
     {
 153  0
         validateUid(uid);
 154  
         try
 155  
         {
 156  0
             SearchControls cons = setSearchControls();
 157  0
             NamingEnumeration results = searchByWildcardedUid(uid, cons);
 158  
 
 159  0
             return getPassword(results, uid);
 160  
         }
 161  0
         catch (NamingException e)
 162  
         {
 163  0
             throw new SecurityException(e);
 164  
         }
 165  
     }
 166  
 
 167  
     /**
 168  
      * <p>
 169  
      * Set the user's password.
 170  
      * </p>
 171  
      * 
 172  
      * @param userDn The user.
 173  
      * @param password The password.
 174  
      * @throws NamingException Throws a {@link NamingException}.
 175  
      */
 176  
     private void setPassword(final String userDn, class="keyword">final String password) throws NamingException
 177  
     {
 178  0
     	logger.debug("setPassword userDn = " + userDn);
 179  0
         String rdn = getSubcontextName(userDn);
 180  
         //if (!StringUtils.isEmpty(getUserFilterBase()))
 181  
         //	rdn+="," + getUserFilterBase();
 182  0
         logger.debug("setPassword rdn = " + rdn);
 183  0
         Attributes attrs = new BasicAttributes(false);
 184  
 
 185  0
         attrs.put(getUserPasswordAttribute(), password);
 186  0
         ctx.modifyAttributes(rdn, DirContext.REPLACE_ATTRIBUTE, attrs);
 187  0
     }
 188  
 
 189  
     /**
 190  
      * <p>
 191  
      * Get the password.
 192  
      * </p>
 193  
      * 
 194  
      * @param results The {@link NamingEnumeration}.
 195  
      * @param uid The uid.
 196  
      * @return The password as an array of char.
 197  
      * @throws NamingException Throws a {@link NamingException}.
 198  
      */
 199  
     private char[] getPassword(final NamingEnumeration results, class="keyword">final String uid) throws NamingException
 200  
     {
 201  0
     	if (!results.hasMore())
 202  
         {
 203  0
             throw new NamingException("Could not find any user with uid[" + uid + "]");
 204  
         }
 205  
 
 206  0
         Attributes userAttributes = getFirstUser(results);
 207  
 
 208  0
         char[] rawPassword = convertRawPassword(getAttribute(getUserPasswordAttribute(), userAttributes));
 209  0
         return rawPassword;
 210  
     }
 211  
 
 212  
     /**
 213  
      * <p>
 214  
      * Get the attribute.
 215  
      * </p>
 216  
      * 
 217  
      * @param attributeName The attribute name.
 218  
      * @param userAttributes The user {@link Attributes}.
 219  
      * @return The {@link Attribute}
 220  
      * @throws NamingException Throws a {@link NamingException}.
 221  
      */
 222  
     private Attribute getAttribute(String attributeName, Attributes userAttributes) throws NamingException
 223  
     {
 224  0
         for (NamingEnumeration ae = userAttributes.getAll(); ae.hasMore();)
 225  
         {
 226  0
             Attribute attr = (Attribute) ae.next();
 227  
 
 228  0
             if (attr.getID().equalsIgnoreCase(attributeName))
 229  
             {
 230  0
                 return attr;
 231  
             }
 232  0
         }
 233  0
         return null;
 234  
     }
 235  
 
 236  
     /**
 237  
      * <p>
 238  
      * This method converts an ascii password to a char array. It needs to be
 239  
      * improved to do proper unicode conversion.
 240  
      * </p>
 241  
      * 
 242  
      * @param attr The {@link Attribute}.  
 243  
      */
 244  
     private char[] convertRawPassword(Attribute attr) throws NamingException
 245  
     {
 246  0
         char[] class="keyword">charPass = null;
 247  
         
 248  0
         if ( attr != null )
 249  
         {
 250  0
             byte[] rawPass = (byte[]) attr.getAll().next();
 251  0
             charPass = new char[rawPass.length];
 252  
 
 253  0
             for (int i = 0; i < rawPass.length; i++)
 254  
             {
 255  
                 // I know I lose the sign and this is only good for ascii text.
 256  0
                 charPass[i] = (char) rawPass[i];           
 257  
             }
 258  0
         }
 259  
         else
 260  
         {
 261  0
             charPass = new char[0];
 262  
         }
 263  0
         return charPass;
 264  
     }
 265  
 
 266  
     /**
 267  
      * <p>
 268  
      * Gets the first matching user.
 269  
      * </p>
 270  
      * 
 271  
      * @param results The results to find the user in.
 272  
      * @return The Attributes.
 273  
      * @throws NamingException Throws a {@link NamingException}.
 274  
      */
 275  
     private Attributes getFirstUser(NamingEnumeration results) throws NamingException
 276  
     {
 277  0
         SearchResult result = (SearchResult) results.next();
 278  0
         Attributes answer = result.getAttributes();
 279  
 
 280  0
         return answer;
 281  
     }
 282  
 
 283  
 	protected String getEntryPrefix() {
 284  0
 		return this.getUserIdAttribute();
 285  
 	}
 286  
 	
 287  
 	protected String getSearchSuffix() {
 288  0
 		return this.getUserFilter();
 289  
 	}
 290  
 
 291  
 	protected String getSearchDomain() {
 292  0
 		return this.getUserFilterBase();
 293  
 	}	
 294  
 	
 295  
 	protected String[] getObjectClasses() {
 296  0
 		return this.getUserObjectClasses();
 297  
 	}
 298  
 
 299  
 	protected String[] getAttributes() {
 300  0
 		return this.getUserAttributes();
 301  
 	}
 302  
 	
 303  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.