package org.apache.turbine.services.security.ldap;

/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *    "Apache Turbine" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache Turbine", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import java.util.List;
import java.util.Hashtable;
import java.util.Vector;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import org.apache.commons.configuration.Configuration;

import org.apache.torque.util.Criteria;

import org.apache.turbine.om.security.User;
import org.apache.turbine.services.security.TurbineSecurity;
import org.apache.turbine.services.security.UserManager;
import org.apache.turbine.util.security.DataBackendException;
import org.apache.turbine.util.security.EntityExistsException;
import org.apache.turbine.util.security.PasswordMismatchException;
import org.apache.turbine.util.security.UnknownEntityException;

/**
 * A UserManager performs {@link org.apache.turbine.om.security.User}
 * object related tasks on behalf of the
 * {@link org.apache.turbine.services.security.SecurityService}.
 *
 * This implementation uses ldap for retrieving user data. It
 * expects that the User interface implementation will be castable to
 * {@link org.apache.turbine.om.BaseObject}.
 *
 * @author <a href="mailto:jon@collab.net">Jon S. Stevens</a>
 * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a>
 * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
 * @author <a href="mailto:cberry@gluecode.com">Craig D. Berry</a>
 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
 * @author <a href="mailto:tadewunmi@gluecode.com">Tracy M. Adewunmi</a>
 * @author <a href="mailto:lflournoy@gluecode.com">Leonard J. Flournoy</a>
 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
 * @author <a href="mailto:hhernandez@itweb.com.mx">Humberto Hernandez</a>
 * @version $Id$
 */
public class LDAPUserManager implements UserManager
{
    /**
     * Initializes the UserManager
     *
     * @param conf A Configuration object to init this Manager
     */
    public void init(Configuration conf)
    {
        // GNDN
    }

    /**
     * Check wether a specified user's account exists.
     *
     * The login name is used for looking up the account.
     *
     * @param user The user to be checked.
     * @return true if the specified account exists
     * @throws DataBackendException Error accessing the data backend.
     */
    public boolean accountExists(User user) throws DataBackendException
    {
        return accountExists(user.getName());
    }

    /**
     *
     * Check wether a specified user's account exists.
     * The login name is used for looking up the account.
     *
     * @param username The name of the user to be checked.
     * @return true if the specified account exists
     * @throws DataBackendException Error accessing the data backend.
     */
    public boolean accountExists(String username)
            throws DataBackendException
    {
        try
        {
            User ldapUser = retrieve(username);
        }
        catch (UnknownEntityException ex)
        {
            return false;
        }

        return true;
    }

    /**
     * Retrieve a user from persistent storage using username as the
     * key.
     *
     * @param username the name of the user.
     * @return an User object.
     * @exception UnknownEntityException if the user's account does not
     *            exist in the database.
     * @exception DataBackendException Error accessing the data backend.
     */
    public User retrieve(String username)
            throws UnknownEntityException, DataBackendException
    {
        try
        {
            DirContext ctx = bindAsAdmin();

            /*
             * Define the search.
             */
            String userBaseSearch = LDAPSecurityConstants.getBaseSearch();
            String filter = LDAPSecurityConstants.getNameAttribute();

            filter = "(" + filter + "=" + username + ")";

            /*
             * Create the default search controls.
             */
            SearchControls ctls = new SearchControls();

            NamingEnumeration answer =
                    ctx.search(userBaseSearch, filter, ctls);

            if (answer.hasMore())
            {
                SearchResult sr = (SearchResult) answer.next();
                Attributes attribs = sr.getAttributes();
                LDAPUser ldapUser = createLDAPUser();

                ldapUser.setLDAPAttributes(attribs);
                ldapUser.setTemp("turbine.user", ldapUser);

                return ldapUser;
            }
            else
            {
                throw new UnknownEntityException("The given user: "
                        + username + "\n does not exist.");
            }
        }
        catch (NamingException ex)
        {
            throw new DataBackendException(
                    "The LDAP server specified is unavailable", ex);
        }
    }

    /**
     * This is currently not implemented to behave as expected.  It
     * ignores the Criteria argument and returns all the users.
     *
     * Retrieve a set of users that meet the specified criteria.
     *
     * As the keys for the criteria, you should use the constants that
     * are defined in {@link User} interface, plus the the names
     * of the custom attributes you added to your user representation
     * in the data storage. Use verbatim names of the attributes -
     * without table name prefix in case of DB implementation.
     *
     * @param criteria The criteria of selection.
     * @return a List of users meeting the criteria.
     * @throws DataBackendException Error accessing the data backend.
     * @deprecated Use <a href="#retrieveList">retrieveList</a> instead.
     */
    public User[] retrieve(Criteria criteria)
            throws DataBackendException
    {
        return (User []) retrieveList(criteria).toArray(new User[0]);
    }

    /**
     * Retrieve a list of users that meet the specified criteria.
     *
     * As the keys for the criteria, you should use the constants that
     * are defined in {@link User} interface, plus the names
     * of the custom attributes you added to your user representation
     * in the data storage. Use verbatim names of the attributes -
     * without table name prefix in case of Torque implementation.
     *
     * @param criteria The criteria of selection.
     * @return a List of users meeting the criteria.
     * @throws DataBackendException if there is a problem accessing the
     *         storage.
     */
    public List retrieveList(Criteria criteria)
            throws DataBackendException
    {
        List users = new Vector(0);

        try
        {
            DirContext ctx = bindAsAdmin();

            String userBaseSearch = LDAPSecurityConstants.getBaseSearch();
            String filter = LDAPSecurityConstants.getNameAttribute();

            filter = "(" + filter + "=*)";

            /*
             * Create the default search controls.
             */
            SearchControls ctls = new SearchControls();

            NamingEnumeration answer =
                    ctx.search(userBaseSearch, filter, ctls);

            while (answer.hasMore())
            {
                SearchResult sr = (SearchResult) answer.next();
                Attributes attribs = sr.getAttributes();
                LDAPUser ldapUser = createLDAPUser();

                ldapUser.setLDAPAttributes(attribs);
                ldapUser.setTemp("turbine.user", ldapUser);
                users.add(ldapUser);
            }
        }
        catch (NamingException ex)
        {
            throw new DataBackendException(
                    "The LDAP server specified is unavailable", ex);
        }
        return users;
    }

    /**
     * Retrieve a user from persistent storage using username as the
     * key, and authenticate the user. The implementation may chose
     * to authenticate to the server as the user whose data is being
     * retrieved.
     *
     * @param username the name of the user.
     * @param password the user supplied password.
     * @return an User object.
     * @exception PasswordMismatchException if the supplied password was
     *            incorrect.
     * @exception UnknownEntityException if the user's account does not
     *            exist in the database.
     * @exception DataBackendException Error accessing the data backend.
     */
    public User retrieve(String username, String password)
            throws PasswordMismatchException,
            UnknownEntityException, DataBackendException
    {
        User user = retrieve(username);

        authenticate(user, password);
        return user;
    }

    /**
     * Save a User object to persistent storage. User's account is
     * required to exist in the storage.
     *
     * @param user an User object to store.
     * @throws UnknownEntityException if the user's account does not
     *            exist in the database.
     * @throws DataBackendException if there is an LDAP error
     *
     */
    public void store(User user)
            throws UnknownEntityException, DataBackendException
    {
        if (!accountExists(user))
        {
            throw new UnknownEntityException("The account '"
                    + user.getName() + "' does not exist");
        }

        try
        {
            LDAPUser ldapUser = (LDAPUser) user;
            Attributes attrs = ldapUser.getLDAPAttributes();
            String name = ldapUser.getDN();

            DirContext ctx = bindAsAdmin();

            ctx.modifyAttributes(name, DirContext.REPLACE_ATTRIBUTE, attrs);
        }
        catch (NamingException ex)
        {
            throw new DataBackendException("NamingException caught", ex);
        }
    }

    /**
     * This method is not yet implemented.
     * Saves User data when the session is unbound. The user account is required
     * to exist in the storage.
     *
     * LastLogin, AccessCounter, persistent pull tools, and any data stored
     * in the permData hashtable that is not mapped to a column will be saved.
     *
     * @exception UnknownEntityException if the user's account does not
     *            exist in the database.
     * @exception DataBackendException if there is a problem accessing the
     *            storage.
     */
    public void saveOnSessionUnbind(User user)
            throws UnknownEntityException, DataBackendException
    {
        if (!accountExists(user))
        {
            throw new UnknownEntityException("The account '" +
                    user.getName() + "' does not exist");
        }
    }

    /**
     * Authenticate a User with the specified password. If authentication
     * is successful the method returns nothing. If there are any problems,
     * exception was thrown.
     *
     * @param user a User object to authenticate.
     * @param password the user supplied password.
     * @exception PasswordMismatchException if the supplied password was
     *            incorrect.
     * @exception UnknownEntityException if the user's account does not
     *            exist in the database.
     * @exception DataBackendException Error accessing the data backend.
     */
    public void authenticate(User user, String password)
            throws PasswordMismatchException,
            UnknownEntityException,
            DataBackendException
    {
        LDAPUser ldapUser = (LDAPUser) user;

        try
        {
            bind(ldapUser.getDN(), password);
        }
        catch (AuthenticationException ex)
        {
            throw new PasswordMismatchException(
                    "The given password for: "
                    + ldapUser.getDN() + " is invalid\n");
        }
        catch (NamingException ex)
        {
            throw new DataBackendException(
                    "NamingException caught:", ex);
        }
    }

    /**
     * This method is not yet implemented
     * Change the password for an User.
     *
     * @param user an User to change password for.
     * @param newPass the new password.
     * @param oldPass the old password.
     * @exception PasswordMismatchException if the supplied password was
     *            incorrect.
     * @exception UnknownEntityException if the user's account does not
     *            exist in the database.
     * @exception DataBackendException Error accessing the data backend.
     */
    public void changePassword(User user, String oldPass, String newPass)
            throws PasswordMismatchException,
            UnknownEntityException, DataBackendException
    {
        throw new DataBackendException(
                "The method changePassword has no implementation.");
    }

    /**
     * This method is not yet implemented
     * Forcibly sets new password for an User.
     *
     * This is supposed to be used by the administrator to change the forgotten
     * or compromised passwords. Certain implementatations of this feature
     * would require adminstrative level access to the authenticating
     * server / program.
     *
     * @param user an User to change password for.
     * @param password the new password.
     * @exception UnknownEntityException if the user's record does not
     *            exist in the database.
     * @exception DataBackendException Error accessing the data backend.
     */
    public void forcePassword(User user, String password)
            throws UnknownEntityException, DataBackendException
    {
        throw new DataBackendException(
                "The method forcePassword has no implementation.");
    }

    /**
     * Creates new user account with specified attributes.
     *
     * @param user the object describing account to be created.
     * @param initialPassword Not used yet.
     * @throws DataBackendException Error accessing the data backend.
     * @throws EntityExistsException if the user account already exists.
     */
    public void createAccount(User user, String initialPassword)
            throws EntityExistsException, DataBackendException
    {
        if (accountExists(user))
        {
            throw new EntityExistsException("The account '"
                    + user.getName() + "' already exist");
        }

        try
        {
            LDAPUser ldapUser = (LDAPUser) user;
            Attributes attrs = ldapUser.getLDAPAttributes();
            String name = ldapUser.getDN();

            DirContext ctx = bindAsAdmin();

            ctx.bind(name, null, attrs);
        }
        catch (NamingException ex)
        {
            throw new DataBackendException("NamingException caught", ex);
        }
    }

    /**
     * Removes an user account from the system.
     *
     * @param user the object describing the account to be removed.
     * @throws DataBackendException Error accessing the data backend.
     * @throws UnknownEntityException if the user account is not present.
     */
    public void removeAccount(User user)
            throws UnknownEntityException, DataBackendException
    {
        if (!accountExists(user))
        {
            throw new UnknownEntityException("The account '"
                    + user.getName() + "' does not exist");
        }

        try
        {
            LDAPUser ldapUser = (LDAPUser) user;
            String name = ldapUser.getDN();

            DirContext ctx = bindAsAdmin();

            ctx.unbind(name);
        }
        catch (NamingException ex)
        {
            throw new DataBackendException("NamingException caught", ex);
        }
    }

    /**
     * Bind as the admin user.
     *
     * @throws NamingException when an error occurs with the named server.
     * @return a new DirContext.
     */
    public static DirContext bindAsAdmin()
            throws NamingException
    {
        String adminUser = LDAPSecurityConstants.getAdminUsername();
        String adminPassword = LDAPSecurityConstants.getAdminPassword();

        return bind(adminUser, adminPassword);
    }

    /**
     * Creates an initial context.
     *
     * @param username admin username supplied in TRP.
     * @param password admin password supplied in TRP
     * @throws NamingException when an error occurs with the named server.
     * @return a new DirContext.
     */
    public static DirContext bind(String username, String password)
            throws NamingException
    {
        String host = LDAPSecurityConstants.getLDAPHost();
        String port = LDAPSecurityConstants.getLDAPPort();
        String providerURL = new String("ldap://" + host + ":" + port);
        String ldapProvider = LDAPSecurityConstants.getLDAPProvider();
        String authentication = LDAPSecurityConstants.getLDAPAuthentication();

        /*
         * creating an initial context using Sun's client
         * LDAP Provider.
         */
        Hashtable env = new Hashtable();

        env.put(Context.INITIAL_CONTEXT_FACTORY, ldapProvider);
        env.put(Context.PROVIDER_URL, providerURL);
        env.put(Context.SECURITY_AUTHENTICATION, authentication);
        env.put(Context.SECURITY_PRINCIPAL, username);
        env.put(Context.SECURITY_CREDENTIALS, password);

        DirContext ctx = new javax.naming.directory.InitialDirContext(env);

        return ctx;
    }

    /**
     * Create a new instance of the LDAP User according to the value
     * configured in TurbineResources.properties.
     * @return a new instance of the LDAP User.
     * @throws DataBackendException if there is an error creating the
     */
    private LDAPUser createLDAPUser()
            throws DataBackendException
    {
        try
        {
            return (LDAPUser) TurbineSecurity.getUserInstance();
        }
        catch (ClassCastException ex)
        {
            throw new DataBackendException("ClassCastException:", ex);
        }
        catch (UnknownEntityException ex)
        {
            throw new DataBackendException("UnknownEntityException:", ex);
        }
    }

}
