[geeklog-cvs] Auth_Enterprise/Enterprise/Server DB.php,NONE,1.1 PasswordGenerator.php,NONE,1.1 PasswordRules.php,NONE,1.1 ServiceUser.php,NONE,1.1 XMLRPCHandler.php,NONE,1.1

jellybob at iowaoutdoors.org jellybob at iowaoutdoors.org
Thu Jul 8 10:36:19 EDT 2004


Update of /var/cvs/Auth_Enterprise/Enterprise/Server
In directory www:/tmp/cvs-serv31121/Enterprise/Server

Added Files:
	DB.php PasswordGenerator.php PasswordRules.php ServiceUser.php 
	XMLRPCHandler.php 
Log Message:
Major changes to the API everywhere.

The README is currently out of date, to find out how to use the new API
please check doc/examples/

Some features are currently untested, and may not work.


--- NEW FILE: PasswordGenerator.php ---
<?php

/**
* Auth_Enterprise
*
* This source file is subject to version 2.02 of the PHP license, that is bundled with this package
* in the file LICENSE, and is available at through the world-wide-web at
* http://www.php.net/license/2_02.txt. If you did not receive a copy of the PHP license and are
* unable to obtain it through the world-wide-web, please send a note to license at php.net so we can
* mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @author Vincent Furia <vinny01 at users.sf.net>
* @copyright 2004
* @version $Id: PasswordGenerator.php,v 1.1 2004/07/08 14:36:16 jellybob Exp $
*
*/

/**
* The Auth_Enterprise server configuration file
*/
//require_once 'Auth/Enterprise/Server/ServerConfig.php';

/**
* Pull in Auth_Enterprise Exceptions
*/
require_once 'Auth/Enterprise/Exceptions.php';

/**
* Class that validates and generates passwords
*
* @author Vincent Furia <vinny01 at users.sf.net>
* @package net.geeklog.auth_enterprise.server
*
*/
class Auth_Enterprise_PasswordGenerator {

    /**
    * Generates a random password
    *
    * @author Vincent Furia <vinny01 at users.sf.net>
    * @access public
    * @return string Radomnly generated passsword
    *
    */
    public static function generatePassword()
    {
        global $gConf;

        $password = '';
        $len = 0;

        if ($gConf['pw_min_length'] >= 6) {
            $len = $gConf['pw_min_length'];
        } else {
            $len = 6;
        }

        for ($i = 0; $i < $len; $i++) {
            $password .= $gConf['randompasswordchars'][rand(0,count($gConf['randompasswordchars'])-1)];
        }

        return $password;
    }

    /**
    * Determines if a password is valid by the configured rules
    *
    * You can set rules for what constitutes a good password via the
    * server configuration
    * 
    * @author Vincent Furia <vinny01 at users.sf.net>
    * @access public
    * @param string $password Password to validate
    * @return boolean
    *
    */
    public static function isValidPassword($password)
    {
        global $gConf;
        
        if (is_array($gConf['pw_rule'])) {
            foreach ($gConf['pw_rule'] as $rule) {
                if ($rule['enabled']) {
                    if (!preg_match($rule['regex'], $password)) {
                        throw new AEPasswordInvalid("The supplied password does not meet the "
                                                  . "rule \"{$rule['description']}\"");
                    }
                }
            }
        }

        // Check for dictionary words
        if ($gConf['pw_spell'] && function_exists('pspell_check')) {
            // open dictionary
            if ( !($pspell_link = pspell_new("en")) ) {
                throw new AEUnableToConnect('Cannot open pspell dictionary');
            }

            // check spelling
            if (pspell_check($pspell_link, $password)) {
                throw new AEPasswordInvalid("The supplied password is a dictionary word");
            }
        }

        // Use cracklib to determine if password is strong
        if ($gConf['pw_crack'] && function_exists('crack_check')) {
            // Open CrackLib Dictionary
            if ( !($dictionary = crack_opendict($gConf['crack_dict'])) ) {
                throw new AEUnableToConnect('Cannot open libcrack dictionary');
            }

            // Perform password check
            if (!crack_check($dictionary, $password)) {
                // Retrieve messages
                $diag = crack_getlastmessage();

                // Close dictionary
                crack_closedict($dictionary);

                throw new AEPasswordInvalid("The supplied password is too easy to crack, $diag");
            }

            // Close dictionary
            crack_closedict($dictionary);
        }

        return true;
    }
}

?>

--- NEW FILE: DB.php ---
<?php

/**
* Auth_Enterprise
*
* This source file is subject to version 2.02 of the PHP license, that is bundled with this package
* in the file LICENSE, and is available at through the world-wide-web at
* http://www.php.net/license/2_02.txt. If you did not receive a copy of the PHP license and are
* unable to obtain it through the world-wide-web, please send a note to license at php.net so we can
* mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright 2004
* @version $Id: DB.php,v 1.1 2004/07/08 14:36:16 jellybob Exp $
*
*/

/**
* Service user object
[...1037 lines suppressed...]
        $row = $sqlResult->fetchRow();
        
        // Set user attributes
        $user->setUserName($row[0]);
        $user->setPassword($row[1]);

        if ($row[2] == 1) {
            $user->setAccountLocked(true);
        } else {
            $user->setAccountLocked(false);
        }
        $user->setFailedAttempts($row[3]);
        $user->setLastPWChange($row[4]);
        
        return $user;
    }

}

?>

--- NEW FILE: PasswordRules.php ---
<?php

/**
* Auth_Enterprise
*
* This source file is subject to version 2.02 of the PHP license, that is bundled with this package
* in the file LICENSE, and is available at through the world-wide-web at
* http://www.php.net/license/2_02.txt. If you did not receive a copy of the PHP license and are
* unable to obtain it through the world-wide-web, please send a note to license at php.net so we can
* mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright 2004
* @version $Id: PasswordRules.php,v 1.1 2004/07/08 14:36:16 jellybob Exp $
*
*/

// Default Password Rules.  Add any custom password rules to the bottom of this file
$gConf['pw_rule']['length']['description'] = sprintf('require %s-%s characters (inclusive)',
                                                     $gConf['pw_min_length'], $gConf['pw_max_length']);
$gConf['pw_rule']['length']['enabled']     = true;
$gConf['pw_rule']['length']['regex']       = '/^.{' . $gConf['pw_min_length'] . ','
                                           . $gConf['pw_max_length'] . '}$/'; 

$gConf['pw_rule']['chars']['description'] = 'limit characters to (A-Z,a-z,0-9,!,@,#,$,%,^,&,*,(,),-,_ only)';
$gConf['pw_rule']['chars']['enabled']     = true; 
$gConf['pw_rule']['chars']['regex']       = '/^[A-Za-z0-9$!@#&^()_-]*$/'; 

// Upper case Rule
if ($gConf['pw_require_upper']) {
    $gConf['pw_rule']['upper']['enabled']     = true;
} else {
    $gConf['pw_rule']['upper']['enabled']     = false;
}
$gConf['pw_rule']['upper']['description'] = 'require at least one upper case character (A-Z)';
$gConf['pw_rule']['upper']['enabled']     = true; 
$gConf['pw_rule']['upper']['regex']       = '/.*[A-Z].*/';

// Lower case Rule
if ($gConf['pw_require_lower']) {
    $gConf['pw_rule']['lower']['enabled']     = true;
} else {
    $gConf['pw_rule']['lower']['enabled']     = false;
}
$gConf['pw_rule']['lower']['description'] = 'require at least one lower case character (a-z)';
$gConf['pw_rule']['lower']['regex']       = '/.*[a-z].*/';

// Number Rule
if ($gConf['pw_require_number']) {
    $gConf['pw_rule']['number']['enabled']     = true; 
} else {
    $gConf['pw_rule']['number']['enabled']     = false;
}
$gConf['pw_rule']['number']['description'] = 'require at least one number (0-9)';
$gConf['pw_rule']['number']['regex']       = '/.*[0-9].*/';

// Special Characters Rule
if ($gConf['pw_require_special_char']) {
    $gConf['pw_rule']['special']['enabled']     = true;
} else {
    $gConf['pw_rule']['special']['enabled']     = false;
}
$gConf['pw_rule']['special']['chars'] = '!@#$%^&*()-_';
$gConf['pw_rule']['special']['description'] = 'require at least one of the following special characters '
    . $gConf['pw_rule']['special']['chars'];
$gConf['pw_rule']['special']['enabled']     = true; 
$gConf['pw_rule']['special']['regex']       = '/.*[$' . $gConf['pw_rule']['special']['chars'] . '].*/';

$gConf['pw_rule']['special']['description'] = 'require at least one letter X';
$gConf['pw_rule']['special']['enabled']     = false; 
$gConf['pw_rule']['special']['regex']       = '/.*[X].*/';

// Add any custom password rules here

?>

--- NEW FILE: ServiceUser.php ---
<?php

/**
* Auth_Enterprise
*
* This source file is subject to version 2.02 of the PHP license, that is bundled with this package
* in the file LICENSE, and is available at through the world-wide-web at
* http://www.php.net/license/2_02.txt. If you did not receive a copy of the PHP license and are
* unable to obtain it through the world-wide-web, please send a note to license at php.net so we can
* mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright 2004
* @version $Id: ServiceUser.php,v 1.1 2004/07/08 14:36:16 jellybob Exp $
*
*/

/**
* The service interface
*/
require_once 'Auth/Enterprise/ServiceInterface.php';

/**
* Auth Enterprise's Group class
*/
require_once 'Auth/Enterprise/Group.php';

/**
* Auth Enterprise's Privilege class
*/
require_once 'Auth/Enterprise/Privilege.php';

/**
* Auth_Enteprise Service User Class.  This services as a proxy to the
* various providers that are supported.
*
* NOTE: some may wonder why this layer exists.  The main reason is for future support of
* single signon.  We would be able to serialize this object to a session on the Auth_Enteprise
* server level for later use.
*
* @author Tony Bibbs <tony at geeklog.net>
* @package Auth_Enterprise
*
*/
class Auth_Enterprise_ServiceUser implements Auth_Enterprise_ServiceInterface {
    const AE_YEAR = 'YEAR';
    const AE_MONTH = 'MONTH';
    const AE_WEEK = 'WEEK';
    const AE_DAY = 'DAY';
    const AE_HOUR = 'HOUR';
    const AE_MINUTE = 'MINUTE';
    const AE_SECOND = 'SECOND';
    
    private $userName = null;
    private $appId = null;
    private $password = null;
    private $accountLocked = null;
    private $failedAttempts = null;
    private $lastPWChange = null;
    private $privileges = null;
    private $groups = null;
    
    /**
    * Converts an instance of this class into an array
    *
    * This class is needed because PEAR::XMLRPC is unable to encode PHP5 objects.  Until this is
    * addressed we will have to use this method before sending a user object back to the calling
    * XMLRPC client application
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return array Array representing this object
    *
    */
    public function toArray()
    {
        $tmpArray = array();
        $tmpArray['userName'] = $this->userName;
        $tmpArray['appId'] = $this->appId;
        $tmpArray['password'] = $this->password;
        $tmpArray['accountLocked'] = $this->accountLocked;
        $tmpArray['failedAttemtps'] = $this->failedAttempts;
        $tmpArray['lastPWChange'] = $this->lastPWChange;
        $privArray = array();
        foreach ($this->privileges as $curPriv) {
            $privArray[] = $curPriv->toArray();
        }
        $tmpArray['privileges'] = $privArray;
        
        $groupArray = array();
        foreach ($this->groups as $curGroup) {
            $groupArray[] = $curGroup->toArray();
        }
        $tmpArray['groups'] = $groupArray;
        return $tmpArray;
    }
    
    /**
    * Constructor
    *
    * Sets the application ID
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $appId Application ID given by Auth_Enterprise server
    *
    */
    public function __construct()
    {
    }
    
    /**
    * Authenticates a user to an application
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    *
    */
    public function authenticate($userName, $password)
    {
        $provider = Enterprise_ProviderFactory::getProvider($this->appId);
        try {
            $user = $provider->authenticate($userName, $password);
        } catch (Exception $e) {
            throw $e;
        }
        return $user;
    }
    
    
    /**
    * Registers a new account with the service
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    *
    */
    public function createAccountByAdmin($adminUserName, $adminPassword, $userName, $userPassword)
    {
    }
    
    /**
    * Changes a user's password
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    *
    */
    public function changePassword($userName, $newPassword)
    {
    }
    
    /**
    * Allows an application level admin to change a
    * user's password
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    *
    */
    public function changePasswordByAdmin($adminUserName, $adminPassword, $userName, $newPassword)
    {
    }
    
    /**
    * Reset a user's password to one randomly generated
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    *
    */
    public function resetPassword($userName)
    {
    }
    
    /**
    * Gets the application privileges for a given user
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    *
    */
    public function getUserPrivilegesByAdmin($adminUserName, $adminPassword, $userName)
    {
    }
    
    /**
    * Sets the application privileges for a given user
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    *
    */
    public function setUserPrivilegesByAdmin($adminUserName, $adminPassword, $userName, $privArray)
    {
    }
    
    /**
    * Lists all available privileges for a given application
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    *
    */
    public function listAppPrivilegesByAdmin($adminUserName, $adminPassword)
    {
    }
    
    /**
    * Allows an administrator to get the groups a user belongs to within the application
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $adminUserName Administrator's username
    * @param string $adminPassword Administrator's password
    * @param string $username user to set groups for
    * @return array Array of group objects, one for each group user belongs to
    *
    */
    public function getUserGroupsByAdmin($adminUserName, $adminPassword, $userName)
    {
    }
    
    /**
    * Allows an administrator to set the groups a user belongs to within the application
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $adminUserName Administrator's username
    * @param string $adminPassword Administrator's password
    * @param string $username user to set groups for
    * @param array $groupArray Array of group object, one for each group to assign user to
    *
    */
    public function setUserGroupsByAdmin($adminUserName, $adminPassword, $userName, $groupArray)
    {
    }
    
    /**
    * Sets the application ID
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $appId Application ID
    *
    */
    public function setAppId($appId)
    {
        $this->appId = $appId;
    }
    
    /**
    * Returns current app ID
    *
    * @author Tony Bibbs <tony at geeklog.net
    * @access public
    * @return string Application ID
    *
    */
    public function getAppId()
    {
        return $this->appId;
    }
    
    /**
    * Sets the Username
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $userName User ID
    *
    */
    public function setUserName($userName)
    {
        $this->userName = $userName;
    }
    
    /**
    * Returns the current username
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return string Username
    *
    */
    public function getUserName()
    {
        return $this->userName;
    }
    
    /**
    * Sets the password for the user
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $password User's password
    *
    */
    public function setPassword($password)
    {
        $this->password = $password;
    }
    
    /**
    * Gets the current password
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return string User's password
    *
    */
    public function getPassword()
    {
        return $this->password;
    }
    
    /**
    * Setter for failed authentication attempts
    *
    * @author Tony Bibbs <tony at geeklog.net
    * @access public
    * @param int $failedAttempts Number of failed authentication attempts
    *
    */
    public function setFailedAttempts($failedAttempts)
    {
        $this->failedAttempts = $failedAttempts;
    }
    
    /**
    * Gets the number of failed authentication attempts for a user
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return int Number of failed attempts
    * 
    */
    public function getFailedAttempts()
    {
        return $this->failedAttempts;
    }
    
    /**
    * Sets unix timestamp when user changed their password last
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $lastPWChagneTimeStamp Unix timestamp
    *
    */
    public function setLastPWChange($lastPWChangeTimeStamp)
    {
        $this->lastPWChange = $lastPWChangeTimeStamp;
    }
    
    /**
    * Returns last time password was changed
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return string Unix timestamp
    *
    */
    public function getLastPWChange()
    {
        $this->lastPWChange;
    }
    
    /**
    * Sets if the password requires change
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param boolean $switch Indicator of whether or not a password change is required
    * @return boolean
    *
    */
    public function setPWChangeRequired($switch)
    {
        $this->pwChangeRequired = $switch;
    }
    
    /**
    * Returns if the password has expired or not
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return boolean 
    *
    */
    public function isPasswordExpired()
    {
        global $gConf;
        
        // Bail if this feature is disabled
        /*
        if ($gConf[AE_PROVIDER_PEAR_DB]['passwordexpiration'] == 0) {
            return false;
        }
        
        if ($this->dateDiff(AE_DAY, time(), $this->getLastPWChange()) > $gConf[AE_PROVIDER_PEAR_DB]['passwordexpiration']) {
            return true;
        }
        */
        return false;
    }
    
    /**
    * Set whether or no the account is locked
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param boolean $switch Whether not not account should be locked
    *
    */
    public function setAccountLocked($switch)
    {
        $this->accountLocked = $switch;
    }
    
    /**
    * Returns whether or not the account is locked
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return boolean
    *
    */
    public function getAccountLocked()
    {
        return $this->accountLocked;
    }
    
    /**
    * Returns the privilges a user has
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return array Array of privilege objects
    *
    */
    public function getPrivileges()
    {
        return $this->privileges;
    }
    
    /**
    * Sets the privileges a user has
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @prarm array $privArray Array of privilege objects
    *
    */
    public function setPrivileges($privArray)
    {
        $this->privileges = $privArray;
    }
    
    /**
    * Sets the groups this user object has access to
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param array $groupArray Array of group objects
    * 
    */
    public function setGroups($groupArray)
    {
        $this->groups = $groupArray;
    }
    
    /**
    * Gets the array of group objects the user belongs to
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @return array
    * 
    */
    public function getGroups()
    {
        return $this->groups;
    }
    
    /**
    * Determines if you user has access to a given privilege
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param string $privCode Privilege code
    * @return boolean
    * 
    */
    public function authorize($privCode)
    {
        foreach ($this->privileges as $curPrivilege) {
            if ($curPrivilege->getPrivilegeCode() == $privCode) {
                return true;
            }
        }
        return false;
    }
    
    /**
    * Gets the difference between two dates in the given interval
    *
    * NOTE: this makes use of PHP5's class-level constants.
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access private
    * @param string $interval Interval to get the difference in.  Must be AE_YEAR, AE_MONTH, AE_DAY
    * AE_HOUR, AE_MINUTE or AE_SECOND
    * @param string $date1 First date to compare, can be english string for date or unixtimestamp
    * @param string $date2 Second date to compare, can be english string for date or unixtimestamp
    * @return int Difference of the two dates in the requested interval
    *
    */
    private function dateDiff($interval, $date1, $date2) {
        if (!is_numeric($date1)) {
            $date1 = strtotime($date1);
        }
        
        if (!is_numeric($date2)) {
            $date2 = strtotime($date2);
        }
        
        if ($date2 > $date1) {
            $seconds = $date2 - $date1;
        } else {
            $seconds = $date1 - $date2;
        }
                                                                                                                                                                                             
        switch ($interval) {
            case AE_YEAR:
                list($year1, $month1, $day1) = split('-', date('Y-m-d', $date1));
                list($year2, $month2, $day2) = split('-', date('Y-m-d', $date2));
                $time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
                $time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
                $diff = $year2 - $year1;
                if($month1 > $month2) {
                    $diff -= 1;
                } elseif($month1 == $month2) {
                    if($day1 > $day2) {
                        $diff -= 1;
                    } elseif($day1 == $day2) {
                        if($time1 > $time2) {
                            $diff -= 1;
                        }
                    }
                }
                break;
            case AE_MONTH:
                list($year1, $month1, $day1) = split('-', date('Y-m-d', $date1));
                list($year2, $month2, $day2) = split('-', date('Y-m-d', $date2));
                $time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
                $time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
                $diff = ($year2 * 12 + $month2) - ($year1 * 12 + $month1);
                if($day1 > $day2) {
                    $diff -= 1;
                } elseif($day1 == $day2) {
                    if($time1 > $time2) {
                        $diff -= 1;
                    }
                }
                break;
            case AE_WEEK:
                // Only simple seconds calculation needed from here on
                $diff = floor($seconds / 604800);
                break;
             case AE_DAY:
                $diff = floor($seconds / 86400);
                break;
            case AE_HOUR:
                $diff = floor($seconds / 3600);
                break;
            case AE_MINUTE:
                $diff = floor($seconds / 60);
                break;
            case AE_SECOND:
                $diff = $seconds;
                break;
        }
        return $diff;
    }
}

?>

--- NEW FILE: XMLRPCHandler.php ---
<?php

/**
* Auth_Enterprise
*
* This source file is subject to version 2.02 of the PHP license, that is bundled with this package
* in the file LICENSE, and is available at through the world-wide-web at
* http://www.php.net/license/2_02.txt. If you did not receive a copy of the PHP license and are
* unable to obtain it through the world-wide-web, please send a note to license at php.net so we can
* mail you a copy immediately.
*
* @author Tony Bibbs <tony at geeklog.net>
* @copyright 2004
* @version $Id: XMLRPCHandler.php,v 1.1 2004/07/08 14:36:16 jellybob Exp $
*
*/

/**
* The Auth_Enterprise Server Provider Factory 
*/
require_once 'Auth/Enterprise.php';

/**
* PEAR's XML RPC server implementation
*/
require_once 'XML/RPC/Server.php';

/**
* Auth_Enterprise Privilege class
*/
require_once 'Auth/Enterprise/Privilege.php';

/**
* Auth_Enterprise Group class
*/
require_once 'Auth/Enterprise/Group.php';

/**
* Auth_Enteprise's XMLRPC Handler
*
* This class is a simple proxy.  All it does is takes Auth_Enterprise request wrapped in XMLPRC and
* calls the method and returns a valid XMLRPC response to the calling application
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.auth_enterprise.server
*
*/
class Auth_Enterprise_XMLRPCHandler {
    /**
     * The provider to handle requests.
     * @access protected
     */
    protected $provider = null;
    
    /**
     * Sets up the handler.
     *
     * @author Jon Wood <jon at jellybob.co.uk>
     * @param $applications array An array of applications to support.
     * @return bool Success/failure
     */
    public function __construct($applications)
    {
        $GLOBALS['_Auth_Enterprise_XMLRPCHandler'] = $applications;
        $XMLRPCServer = new XML_RPC_Server(
                                array('Auth_Enterprise.processRequest' => array('function' => 'Auth_Enterprise_XMLRPCHandler::handleRequest'))
                            );
        return true;
    }
    
    /**
    * Handles all XMLRPC requests made to Auth_Enterprise
    *
    * @author Tony Bibbs <tony at geeklog.net>
    * @access public
    * @param array XMLRPC argument values
    * @return string valid XMLPRC response
    *
    */
    public static function handleRequest($params)
    {
        global $xmlrpcerruser;
        
        // Probably a hack, I don't know much about XML-RPC, Jon
        $appId = $params->params[1]->me['string'];
        
        $options = $GLOBALS['_Auth_Enterprise_XMLRPCHandler'][$appId]['options'];
        if (!isset($options['appId'])) {
            $options['appId'] = $appId;
        }
        
        $provider =& Auth_Enterprise::serverSingleton($GLOBALS['_Auth_Enterprise_XMLRPCHandler'][$appId]['provider'], $options);
        $methodArgumentMapping = array(
                                       'authenticate' => 2,
                                       'createAccountByAdmin' => 4,
                                       'changePassword' => 2,
                                       'changePasswordByAdmin' => 4,
                                       'resetPassword' => 1,
                                       'getUserPrivilegesByAdmin' => 3,
                                       'setUserPrivilegesByAdmin' => 4,
                                       'listAppPrivilegesByAdmin' => 2,
                                       'getUserGroupsByAdmin' => 3,
                                       'setUserGroupsByAdmin' => 4
                                      );
                                      
        $methodsWithObjectParams = array(
                                        'setUserPrivilegesByAdmin' => 6,
                                        'setUserGroupsByAdmin' => 6
                                        );
                                      
        // Convert parameters into an array to be sent to
        // the provider method
        foreach ($params->params as $curParam) {
            $fnParams[] = $curParam->scalarval();
        }
        
        // Get provider method to call
        $methodToCall = $fnParams[0];
        // This is a hack, yes a bad one, to convert group and privilege parameters to objects
        if (in_array($methodToCall, array_keys($methodsWithObjectParams))) {
            $fnParams[$methodsWithObjectParams[$methodToCall] - 1] = Enterprise_XMLRPCHandler::convertParamToObjects($fnParams[$methodsWithObjectParams[$methodToCall] - 1]);
        }
        
        // Get the number of arguments the method takes
        if (isset($methodArgumentMapping[$methodToCall])) {
            $numMethodArgs = $methodArgumentMapping[$methodToCall];
        }
        
        // Call the method.
        try {
            if (isset($numMethodArgs)) {    
                switch ($numMethodArgs) {
                    case 1:
                        $retVal = $provider->$methodToCall($fnParams[2]);
                        break;
                    case 2:
                        $retVal = $provider->$methodToCall($fnParams[2], $fnParams[3]);
                        break;
                    case 3:
                        $retVal = $provider->$methodToCall($fnParams[2], $fnParams[3], $fnParams[4]);
                        break;
                    case 4:
                        $retVal = $provider->$methodToCall($fnParams[2], $fnParams[3], $fnParams[4], $fnParams[5]);
                        break;
                    default:
                        throw new Exception("Method $methodToCall not defined in methodArgumentMapping");
                }
            } else {
                throw new Exception("Method ${methodToCall} not defined in methodArgumentMapping");
            }
        } catch (AEBaseException $e) {
            return new XML_RPC_Response(0, $xmlrpcerruser + $e->getXMLErrorOffset(), $e->getMessage()); 
        } catch (Exception $e) {
            // Handle unknown problems
            return new XML_RPC_Response(0, $xmlrpcerruser + 1, $e->getMessage());
        }
        
        // Because of a PHP5 incompatibility, we must convert any object to arrays before
        // encoding them
        if (is_object($retVal)) {
            $retVal = $retVal->toArray();
        } else {
            // We may have gotten an array of objects so handle that
            if (is_array($retVal)) {
                $newArray = array();
                foreach ($retVal as $curVal) {
                    if (is_object($curVal)) {
                        $newArray[] = $curVal->toArray();
                    } else {
                        $newArray[] = $curVal;
                    }
                }
            }
            $retVal = $newArray;
        }
        
        // Now return the response
        return new XML_RPC_Response(XML_RPC_encode($retVal));
    }
    
    public static function convertParamToObjects($param)
    {
        if (!is_array($param)) {
            return array();
        }

        $retval = array();
        foreach ($param as $curItem) {
            $curItem = $curItem->scalarval();
            if (in_array('privilegeCode', array_keys($curItem))) {
                $tmpObj = new Auth_Enterprise_Privilege();
                $tmpObj->setPrivilegeCode($curItem['privilegeCode']->scalarval());
                $tmpObj->setPrivilegeDesc($curItem['privilegeDesc']->scalarval());
            } else {
                if (in_array('groupId', array_keys($curItem))) {
                    $tmpObj = new Auth_Enterprise_Group();
                    $tmpObj->setGroupId($curItem['groupId']->scalarval());
                    $tmpObj->setGroupLogicalName($curItem['groupLogicalName']->scalarval());
                    $tmpObj->setGroupDisplayName($curItem['groupDisplayName']->scalarval());
                    $tmpObj->setGroupDesc($curItem['groupDesc']->scalarval());
                }
            }
            $retval[] = $tmpObj;
        }
        
        return $retval;
    }
    
}
?>




More information about the geeklog-cvs mailing list