/*
 * Copyright 2006-2008 The Kuali Foundation
 * 
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.osedu.org/licenses/ECL-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.kuali.cas.auth;

import java.security.GeneralSecurityException;

import org.apache.commons.lang.StringUtils;
import org.kuali.core.bo.user.AuthenticationUserId;
import org.kuali.core.bo.user.UniversalUser;
import org.kuali.core.exceptions.UserNotFoundException;
import org.kuali.core.service.EncryptionService;
import org.kuali.core.service.KualiConfigurationService;
import org.kuali.core.service.UniversalUserService;
import org.kuali.core.service.WebAuthenticationService;
import org.kuali.kra.bo.Person;
import org.kuali.kra.infrastructure.KraServiceLocator;
import org.kuali.kra.service.PersonService;
import org.kuali.rice.KNSServiceLocator;

import edu.yale.its.tp.cas.auth.provider.WatchfulPasswordHandler;

public class KraPasswordHandler extends WatchfulPasswordHandler {
    protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KraPasswordHandler.class);
    /**
     * Authenticates the given username/password pair, returning true on success
     * and false on failure.
     */
    public boolean authenticate(javax.servlet.ServletRequest request, String username, String password) {
        if (super.authenticate(request, username, password) != false) {
            try {
                if (username != null && !username.trim().equals( "" ) ) {
                    
                    username = username.trim();
                    
                    // check the username and password against the db
                    // return true if they are there and have a valid password
                    if ( LOG.isDebugEnabled() ) {
                        LOG.debug( "Attempting login for user id: " + username + " and password hash: " + KNSServiceLocator.getEncryptionService().hash( password.trim() ) );
                    }
                   
                    // obtain the universal user record
                    UniversalUserService uus = KraServiceLocator.getService(UniversalUserService.class);
                    UniversalUser user = uus.getUniversalUser( new AuthenticationUserId( username ) );
                    if ( LOG.isDebugEnabled() ) {
                        LOG.debug( "Found user " + user.getPersonName() + " with password hash: " + user.getFinancialSystemsEncryptedPasswordText() );
                    }
                    
                    PersonService personService = KraServiceLocator.getService(PersonService.class);
                    Person person = personService.getPersonByName(username);
                    if (person == null) {
                        LOG.info( "User " + username + " was not found in the Person table." );
                        return false; // fail if user does not exist
                    }
                    if (!person.getActive()) {
                        LOG.info( "User " + username + " is inactive." );
                        return false; // fail if user does not exist
                    }
                    
                    // check if the password needs to be checked (if in a production environment or password turned on explicitly)
                    // TODO turn this on
                    KualiConfigurationService kcs = KraServiceLocator.getService(KualiConfigurationService.class);
                    WebAuthenticationService was = KraServiceLocator.getService(WebAuthenticationService.class);
                    if ( kcs.isProductionEnvironment() || was.isValidatePassword() ) {
                    
                        // if so, hash the passed in password and compare to the hash retrieved from the database
                        String hashedPassword = user.getFinancialSystemsEncryptedPasswordText();
                        if ( hashedPassword == null ) {
                            hashedPassword = "";
                        }
                        
                        EncryptionService es = KraServiceLocator.getService(EncryptionService.class);
                        hashedPassword = StringUtils.stripEnd( hashedPassword, EncryptionService.HASH_POST_PREFIX );
                        if ( es.hash( password.trim() ).equals( hashedPassword ) ) {
                            return true; // password matched
                        }
                    } else {
                        LOG.warn( "WARNING: password checking is disabled - user " + username + " has been authenticated without a password." );
                        return true; // no need to check password - user's existence is enough 
                    }
                }
            } catch ( GeneralSecurityException ex ) {
                LOG.error( "Error validating password", ex );
                return false; // fail if the hash function fails
            } catch ( UserNotFoundException ex ) {
                LOG.info( "User " + username + " was not found in the Person table." );
                return false; // fail if user does not exist
            }
        }
        LOG.warn( "CAS base password handler failed authenication for " + username + " based on number of attempts." );
        return false; // fail if we get to this point
    }
}
@@ -2218,32 +2218,35 @@
                 
+   
 LOG.debug( %22Atte
@@ -2279,43 +2279,159 @@
 %22 + 
-username + %22 and password hash: %22 +
+%0A                                      username + %22 and password hash: %22 + %0A                                      (String) ((password==null) ? %22null%22 :
  KNS
@@ -2489,17 +2489,17 @@
 d.trim()
- 
+)
 ) );%0A   

Fix for KRACOEUS-1830.