<?php
/**
 * The Auth_application class provides a wrapper around
 * application-provided Horde authentication which fits inside the
 * Horde Auth:: API.
 *
 * Required parameters:
 * ====================
 *   'app'  --  The application which is providing authentication.
 *
 *
 * $Horde: horde/lib/Auth/application.php,v 1.14 2003/07/10 21:42:55 slusarz Exp $
 *
 * Copyright 2002-2003 Chuck Hagenbuch <chuck@horde.org>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @author  Chuck Hagenbuch <chuck@horde.org>
 * @version $Revision: 1.14 $
 * @since   Horde 3.0
 * @package horde.auth
 */
class Auth_application extends Auth {

    /**
     * An array of capabilities, so that the driver can report which
     * operations it supports and which it doesn't.
     *
     * @var array $capabilities
     */
    var $capabilities = array('add'         => false,
                              'update'      => false,
                              'remove'      => false,
                              'list'        => false,
                              'transparent' => false,
                              'loginscreen' => true);

    /**
     * Constructs a new Application authentication object.
     *
     * @access public
     *
     * @param optional array $params  A hash containing connection parameters.
     */
    function Auth_application($params = array())
    {
        $this->_setParams($params);
    }

    /**
     * Set connection parameters.
     *
     * @access private
     *
     * @param array $params  A hash containing connection parameters.
     */
    function _setParams($params)
    {
        global $registry;

        if (!is_array($params)) {
            Horde::fatal(PEAR::raiseError('No configuration information specified for Application authentication.'), __FILE__, __LINE__);
        }
        if (!array_key_exists('app', $params)) {
            Horde::fatal(PEAR::raiseError('Required "app" not specified in authentication configuration.'), __FILE__, __LINE__);
        }
        if (!array_key_exists($params['app'], $GLOBALS['registry']->applications)) {
            Horde::fatal(PEAR::raiseError($params['app'] . ' is not configured in the Horde Registry.'), __FILE__, __LINE__);
        }
        $this->capabilities['list']   = $registry->hasMethod('userlist', $params['app']);
        $this->capabilities['add']    = $registry->hasMethod('adduser', $params['app']);
        $this->capabilities['update'] = $registry->hasMethod('updateuser', $params['app']);
        $this->capabilities['remove'] = $registry->hasMethod('removeuser', $params['app']);

        $this->_params = $params;
    }

    /**
     * Find out if a set of login credentials are valid.
     *
     * @access private
     *
     * @param string $userID      The userID to check.
     * @param array $credentials  The credentials to use.
     *
     * @return boolean  Whether or not the credentials are valid.
     */
    function _authenticate($userID, $credentials)
    {
        global $registry;

        if (!$registry->hasMethod('authenticate', $this->_params['app'])) {
            Horde::fatal(PEAR::raiseError($this->_params['app'] . ' does not provide an authenticate() method.'), __FILE__, __LINE__);
        }
        return $registry->callByPackage($this->_params['app'], 'authenticate',
                                        array('userID' => $userID,
                                              'credentials' => $credentials,
                                              'params' => $this->_params));
    }

    /**
     * Return the URI of the login screen for this authentication
     * method.
     *
     * @access public
     *
     * @return string  The login screen URI.
     */
    function getLoginScreen()
    {
        return parent::getLoginScreen($this->_params['app']);
    }

    /**
     * List all users in the system.
     *
     * @access public
     *
     * @return mixed  The array of userIDs, or a PEAR_Error object on failure.
     */
    function listUsers()
    {
        if ($this->hasCapability('list')) {
            return $GLOBALS['registry']->callByPackage($this->_params['app'], 'userlist');
        } else {
            return PEAR::raiseError('unsupported');
        }
    }

    /**
     * Add a set of authentication credentials.
     *
     * @access public
     *
     * @param string $userID      The userID to add.
     * @param array $credentials  The credentials to use.
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function addUser($userID, $credentials)
    {
        if ($this->hasCapability('add')) {
            return $GLOBALS['registry']->callByPackage($this->_params['app'], 'adduser', array($userID, $credentials));
        } else {
            return PEAR::raiseError('unsupported');
        }
    }

    /**
     * Update a set of authentication credentials.
     *
     * @access public
     *
     * @param string $oldID       The old userID.
     * @param string $newID       The new userID.
     * @param array $credentials  The new credentials
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function updateUser($oldID, $newID, $credentials)
    {
        if ($this->hasCapability('update')) {
            return $GLOBALS['registry']->callByPackage($this->_params['app'], 'updateuser', array($oldID, $newID, $credentials));
        } else {
            return PEAR::raiseError('unsupported');
        }
    }

    /**
     * Delete a set of authentication credentials.
     *
     * @access public
     *
     * @param string $userID  The userID to delete.
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function removeUser($userID)
    {
        if ($this->hasCapability('remove')) {
            return $GLOBALS['registry']->callByPackage($this->_params['app'], 'removeuser', array($userID));
        } else {
            return PEAR::raiseError('unsupported');
        }
    }

}
