/*
 * $Id: VKCAuthenticationManager.java,v 1.5 2007/07/20 14:18:05 marbobo Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 * 
 * Created on 06.07.2004
 *
 * $Log: VKCAuthenticationManager.java,v $
 * Revision 1.5  2007/07/20 14:18:05  marbobo
 * + Max. Anzahl von Benutzern die im System gleichzeitig angemeldet sein dürfen ist jetzt konfiguriebar
 *
 * Revision 1.4  2005/11/24 19:33:38  marbobo
 * + Methoden-Signatur angepasst
 *
 * Revision 1.3  2004/11/10 15:02:51  koppy
 * Projektweite Überarbeitung von Error-Logs, Stacktraces,..
 *
 * Revision 1.2  2004/09/20 10:26:14  koppy
 * +javadoc Dokumentation
 *
 * Revision 1.1  2004/08/30 14:49:58  koppy
 * Initiale Version der Workflow-Komponente
 *
 */
package vkc.workflow.shark;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.enhydra.shark.api.RootException;
import org.enhydra.shark.api.UserTransaction;
import org.enhydra.shark.api.internal.authentication.AuthenticationManager;
import org.enhydra.shark.api.internal.working.CallbackUtilities;

import vkc.db.helper.UserHelper;
import vkc.exception.DBException;
import vkc.exception.DisabledUserAccountException;
import vkc.exception.MaxAllowedUsersExceededException;
import vkc.exception.PasswordMismatchException;
import vkc.exception.UnknownUserException;
import vkc.exception.UserAccountNotEnabledException;
import vkc.workflow.util.SharkUtils;

/**
 * This class represents a custom VKC
 * authentication manager used in the shark environment.
 * 
 * @author Andreas Koop
 */
public class VKCAuthenticationManager 
	implements AuthenticationManager{

    public static final String INTERNAL_USER 	= "~#$internal.user$#~";
    public static final String INTERNAL_PWD		= "~#$internal.pwd$#~";
    
    private Map logins = new HashMap();
    private int cacheMillis = 1000*30; // 30''
    
    protected CallbackUtilities cus;

	/**
	 * Method configure is called at Shark start up, to configure
	 * implementation of VKC UserGroupManager.
	 *
	 * @param cus an instance of CallbackUtilities used to get
	 *            properties for configuring usergroup manager in Shark.
	 *
	 * @exception RootException thrown if configuring doesn't succeed.
	 */
	public void configure(CallbackUtilities cus) throws RootException {
		this.cus = cus;
		SharkUtils.initVKC(cus);
	}
	
    /**
     * Validates user.
     *
     * @param    t user transaction.
     * @param    username user name.
     * @param    pwd user password.
     *
     * @return   true if user is validated, otherwise false.
     *
     * @exception   RootException If something unexpected happens.
     */
    public boolean validateUser (UserTransaction t,String username,String pwd) throws RootException {
        
        if(VKCAuthenticationManager.INTERNAL_PWD.equals(pwd))
            return true;
        
            try {
                Date lastLoginDate = (Date)logins.get( username );
                if(lastLoginDate != null 
                   && System.currentTimeMillis()-lastLoginDate.getTime() < cacheMillis){
                    return true;
                }
                UserHelper.authenticate( username, pwd, null );
                logins.put( username, new Date());
                
                return true;
            } catch (DBException e ){
                cus.info( "DBException occured! ", new RootException(e));
            } catch (UnsupportedEncodingException e) {
                cus.info( "UnsupportedEncoding! ", new RootException(e));
                throw new RootException(e);
            } catch (NoSuchAlgorithmException e) {
                cus.info( "NoSuchAlgorithm! ", new RootException(e));
                throw new RootException(e);
            } catch (UserAccountNotEnabledException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (UnknownUserException e) {
                cus.info( "UnknownUser! ", new RootException(e));
            } catch (DisabledUserAccountException e) {
                cus.info( "Account disabled! ", new RootException(e));
            } catch (PasswordMismatchException e) {
                cus.info( "PasswordMismatch! ", new RootException(e));
            } catch (MaxAllowedUsersExceededException e) {
                cus.info( "MaxAllowedUsers exceeded!! ", new RootException(e));
            }
            
            cus.info( "Authentication of user " + username + " failed!");
            
            return false;
        
    }

}
