[geeklog-cvs] geeklog-2/public_html/server/A_and_A AACommandFactory.class.php,NONE,1.1 AAProviderFactory.class.php,NONE,1.1 AAProviderProperties.class.php,NONE,1.1 AAServiceHandler.class.php,NONE,1.1 AAServiceUser.class.php,NONE,1.1 AAUtil.class.php,NONE,1.1 config.php,NONE,1.1 index.php,NONE,1.1

tony at geeklog.net tony at geeklog.net
Sat Jan 11 00:58:40 EST 2003


Update of /usr/cvs/geeklog/geeklog-2/public_html/server/A_and_A
In directory internal.geeklog.net:/tmp/cvs-serv32190/A_and_A

Added Files:
	AACommandFactory.class.php AAProviderFactory.class.php 
	AAProviderProperties.class.php AAServiceHandler.class.php 
	AAServiceUser.class.php AAUtil.class.php config.php index.php 
Log Message:
Initial load into Geeklog


--- NEW FILE: AACommandFactory.class.php ---
<?php

require_once('commands/AABaseCommand.class.php');

/**
* This is the Command Factory for the authentication and authorization
* service.  In all likelihood, you will not need to ever edit this file
* directly.  This page simply create commands of different types that
* do specific actions.  This code assumes you are fimiliar with the 
* factory design pattern.
*
* @author Tony Bibbs <tony AT geeklog DOT net>
* @package net.geeklog.enterprise.aa.server
*
*/
class AACommandFactory {

    /**
    * Constructor
    *
    * @access public
    *
    */
    function AACommandFactory()
    {
    }

    /**
    * At run time this determines the right command to build and returns it
    *
    * @author Tony Bibbs <tony AT geeklog DOT net>
    * @access public
    * @return object Some child of AABaseCommand
    *  
    */
    function &getCommand()
    {
        $requestXML = $_POST['xmlInParam'];
        $requestXML = stripslashes($_POST['xmlInParam']);

        /*
        $requestXML = '<?xml version="1.0"?><AAService><Authenticate><AppId value="A_AND_A"></AppId><UserName value="root at localhost"></UserName><Password value="foo"></Password></Authenticate></AAService>';
        $requestXML = '<?xml version="1.0"?><AAService><ListAppPrivileges><AppId value="A_AND_A"></AppId><AdminUserId value="root at localhost"></AdminUserId><AdminPassword value="foo"></AdminPassword></ListAppPrivileges></AAService>';
        */
        $xmlParser = xml_parser_create();
        xml_parse_into_struct($xmlParser,$requestXML,$vals,$index) or trigger_error(xml_error_string(xml_get_error_code($xmlParser)));
        xml_parser_free($xmlParser);
        $XMLKeys = array_keys($index);
        $cmdName = $vals[$index[$XMLKeys[1]][0]]['tag'];

        $cmdDir = dirname(__FILE__) . '/commands/';
        if (!is_dir($cmdDir)) {
            trigger_error('Command Factory has invalid command directory');
        }

        if (!require_once($cmdDir . strtolower($cmdName) . '.class.php')) {
            trigger_error('Command Factory unable to open ' . $cmdDir . strtolower($cmdName) . '.class.php');
        }
        trigger_error('Command Factory about to build this command: ' . $cmdName);
        $cmd = new $cmdName($cmdName);
        $cmd->setParameters($index,$vals);

        return $cmd;
    }
}

?>

--- NEW FILE: AAProviderFactory.class.php ---
<?php

/**
* A&A Provider Factory
*
* @access public
* @author Tony Bibbs <tony AT geeklog DOT net>
* @package net.geeklog.enterprise.aa.server
*
*/
class AAProviderFactory {
    /**
    * Gets a A&A provider for the specified application
    *
    * @param    string      $appId      Application Id
    * @return   object      $provider   Some sort of provider
    *
    */
    function &getProvider($appId)
    {
        $confFile = new AAProviderProperties($appId);
        
        // See if app has explicitly selected a provider
        $providerName = $confFile->getValue('APPLICATION_SETTINGS', $appId);
        if (empty($providerName)) {
            // App has no provider, give it the default provider
            $providerName = $confFile->getValue('A_AND_A', 'DEFAULT_AA_PROVIDER');
        }
        $providerName = 'SQLProvider';
        $providerDir = dirname(__FILE__) . '/providers/';

        // Ensure provider directory is valid
        if (!is_dir($providerDir)) {
            trigger_error('Provider Factory unable to open provider directory: ' . $providerDir);
        }
        // Try and include the right provider file 
        require_once($providerDir . $providerName . '.class.php');

        $provider = new $providerName();

        return $provider;
    }
}

?>

--- NEW FILE: AAProviderProperties.class.php ---
<?php

/**
* PEAR Config package for config file I/O
*/
require_once('Config.php');

/**
* This class access the provider config file (which is in XML)
*
* @author Tony Bibbs <tony AT geeklog DOT net>
* @package net.geeklog.enterprise.aa.server
*
*/
class AAProviderProperties {
    /**
    * @access private
    */
    var $_appId = '';

    /**
    * Constructor
    *
    * @param    string  $appId      Application Id
    *
    */
    function AAProviderProperties($appId='')
    {
        $this->_appId = $appId;
    }

    /**
    * Gets a config file property value
    *
    * @param    string      $key    field to get value for from INI file
    * @return   string      Value of field
    *
    */ 
    function getValue($section,$key)
    {
        $confParser = new Config('IniFile');
        $parsedData = $confParser->parseConfig('AAService.ini');
        $requestedSection = $parsedData->getItem('section', $section);
        
        if (!empty($requestedSection)) {
            return $requestedSection[$section][$key];
        } else {
            return false;
        }
    }
}

?>

--- NEW FILE: AAServiceHandler.class.php ---
<?php

/**
* A&A Command Factory
*/
include('AACommandFactory.class.php');

/**
* A&A Server
*
* This is the controller class that initiates any work that needs to be done. Odds are
* you will not need to touch any of this code
*
* @access public
* @author Tony Bibbbs <tony AT geeklog DOT net>
* @package net.geeklog.enterprise.aa.server
*
*/
class AAServiceHandler {

    /**
    * Handles any HTTP GET requests (unsupported for now)
    *
    * @access public
    * @return   boolean     False (this is in supported)
    *
    */
    function doGet()
    {
        //print 'A&A Service does not process GET requests';
        return false;
    }

    /**
    * Handles in HTTP POST requests and produces responses
    *
    * @access public
    * @return   boolean     True if command execution works otherwise false
    *
    */
    function doPost()
    {
        // Create command now
        $command = &AACommandFactory::getCommand();
        $responseXML = $command->processRequest();
        echo $responseXML;

        return true;
    }
}

?>

--- NEW FILE: AAServiceUser.class.php ---
<?php

//require_once(dirname(__FILE__) . '/../common/AAException.class.php');
require_once('/home/tony/geeklog2_main/lib/A_and_A/common/AAException.class.php');
//require_once(dirname(__FILE__) . '/../server/AAProviderFactory.class.php');
require_once('AAProviderFactory.class.php');

/**
* This is the A&A service user object.  You may be wondering
* why is this object important?  Well, if we ever do single-sign on
* then you'll want to load this object into memory on the A&A Server
* for accessiblity.  Yes, this would take a lot of RAM but, hey,
* that's how Yahoo does it ;-)
*
* @author Tony Bibbs <tony at tonybibbs.com>
* @package net.geeklog.enterprise.aa.server
*
*/
class AAServiceUser {
    var $exception = '';
    var $_userId;
    var $_userName = '';
    var $_appId = '';
    var $_empId = '';
    var $_password = '';
    var $_lastPWChange;
    var $_accountLocked = true;
    var $_privileges;
    var $_groups;

    /**
    * Constructor
    *
    */
    function AAServiceUser()
    {
    }

    /**
    * This will authenticate the user
    *
    * @param    string      $appId      Application ID
    * @param    string      $userId     User ID
    * @param    string      $password   Password
    * @return   AAServiceUser|AAException   User object or an exception
    *
    */
    function &authenticate($appId, $userName, $password)
    {
        // make sure we got all the arguments
        if (empty($appId) OR empty($userName) OR empty($password)) {
            $exception = new AAException(INSUFFICIENT_DATA_EXCEPTION);
            $exception->setMessage('appId, userName or password was empty in authenticate()');

            return $exception;
        }
  
        // get authentication provider 
        $authProvider = &AAProviderFactory::getProvider($appId);

        // try authenticating to the provider
        $user = &$authProvider->authenticate($appId, $userName, $password);

        return $user;
    }

    /**
    * Checks to see if a user has a particular privilege
    *
    * @access public
    * @param string $authCode Privilege to check on
    * @return boolean true if user has privilege otherwise false
    *
    */
    function authorize($authCode)
    {
        foreach ($this->_privileges as $curPriv) {
            if ($curPriv->getPrivilegeCode() == $authCode) {
                return true;
            }
        }
        return false;
    }

    function changePassword($newPassword)
    {
        // Ok, because PHP can't include() packages, we need to
        // include all PHP files in the provider directory
        if (empty($newPassword)) {
            $exception = new AAException(INSUFFICIENT_DATA_EXCEPTION);
            $exception->setMessage('no new password supplied to changePassword()');
            return $exception;
        }
        
            // get authentication provider 
        $authProvider = &AAProviderFactory::getProvider($this->_appId);

        return $authProvider->changePassword($this->getAppId(), $this->getUserName(), $this->getPassword(),$newPassword);
    }

    function changePasswordByAdmin($userName, $newPassword)
    {
        // Ok, because PHP can't include() packages, we need to
        // include all PHP files in the provider directory
        if (empty($newPassword) OR empty($userName)) {
            $exception = new AAException(INSUFFICIENT_DATA_EXCEPTION);
            $exception->setMessage('either the user ID or new password was not supplied to changePasswordByAdmin()');
            return $exception;
        }
        
            // get authentication provider 
        $authProvider = &AAProviderFactory::getProvider($this->_appId);

        return $authProvider->changePasswordByAdmin($this->getAppId(), $this->getUserName(), $this->getPassword(), $userName, $newPassword);
    }

    /**
    * Resets a user's password
    *
    * Calls on the appriopriate provider to reset the password for the given user
    *
    * @access public
    * @param string $userId ID of user to reset password for
    * @return object|boolean returns exception object on failure otherwise nothing
    *
    */
    function resetPassword($userName)
    {
        $adminUserName = $this->getUserName();
        $adminPassword = $this->getPassword();
        $appId = $this->getAppId();

        if (empty($userName) OR empty($adminUserName) OR empty($adminPassword) OR empty($appId))  {
            $exception = new AAException(INSUFFICIENT_DATA_EXCEPTION);
            $exception->setMessage('User ID was not supplied to resetPassword()');
            return $exception;
        }
        $authProvider = &AAProviderFactory::getProvider($this->_appId);
        return $authProvider->resetPassword($this->getAppId(), $adminUserName, $adminPassword, $userName);
    }

    /**
    * Gets the privileges a user has for a specific application
    *
    * Calls on the appriopriate provider to get the privileges for the given app and user
    *
    * @access public
    * @param string $userId ID of user to get privileges for for
    * @return  AAPrivilege[] returns exception object on failure otherwise nothing
    *
    */
    function getUserPrivileges($userName)
    {
        $adminUserName = $this->getUserName();
        $adminPassword = $this->getPassword();
        $appId = $this->getAppId();

        if (empty($userName) OR empty($adminUserName) OR empty($adminPassword) OR empty($appId))  {
            $exception = new AAException(INSUFFICIENT_DATA_EXCEPTION);
            $exception->setMessage('User ID was not supplied to getUserPrivileges()');
            return $exception;
        }
        $authProvider = &AAProviderFactory::getProvider($this->_appId);
        return $authProvider->getUserPrivileges($this->getAppId(), $this->getUserName(), $this->getPassword(), $userName);
    }

    function getUserGroups($userName)
    {
        $adminUserName = $this->getUserName();
        $adminPassword = $this->getPassword();
        $appId = $this->getAppId();

        if (empty($userName) OR empty($adminUserName) OR empty($adminPassword) OR empty($appId))  {
            $exception = new AAException(INSUFFICIENT_DATA_EXCEPTION);
            $exception->setMessage('User ID was not supplied to getUserGroups()');
            return $exception;
        }
        $authProvider = &AAProviderFactory::getProvider($this->_appId);
        return $authProvider->getUserGroups($this->getAppId(), $this->getUserName(), $this->getPassword(), $userName);
    }
        
    function setUserPrivileges($userName, $privArray)
    {
        $adminUserName = $this->getUserName();
        $adminPassword = $this->getPassword();
        $appId = $this->getAppId();

        if (empty($userName) OR empty($adminUserName) OR empty($adminPassword) OR empty($appId) OR !is_array($privArray))  {
            $exception = new AAException(INSUFFICIENT_DATA_EXCEPTION);
            $exception->setMessage('Not all parameters were passed to setUserPrivileges');
            return $exception;
        }
        $authProvider = &AAProviderFactory::getProvider($this->_appId);
        return $authProvider->setUserPrivileges($this->getAppId(), $this->getUserName(), $this->getPassword(), $userName, $privArray);
    }

    /**
    * Sets the application ID
    *
    * @param    string      $appId      Application ID
    *
    */
    function setAppId($appId)
    {
        $this->_appId = $appId;
    }

    /**
    * Returns current app ID
    *
    * @return   string      Application ID
    *
    */
    function getAppId()
    {
        return $this->_appId;
    }
   
    /**
    * Sets the employee ID
    *
    * @param    string      $empId      Employee ID 
    *
    */
    function setEmpId($empId)
    {
        $this->_empId = $empId;
    }

    /**
    * Returns current employee ID
    *
    * @return   string      Employee ID
    *
    */
    function getEmpId()
    {
        return $this->_empId;
    } 

    /**
    * Sets the User ID
    *
    * @param    string      $empId      User ID 
    *
    */
    function setUserId($userId)
    {
        $this->_userId = $userId;
    }

    /**
    * Returns the current user ID
    *
    * @return   string      User ID
    *
    */
    function getUserID()
    {
        return $this->_userId;
    }
    
    function setUserName($userName)
    {
        $this->_userName = $userName;
    }
    
    function getUserName()
    {
        return $this->_userName;
    }

    /**
    * Sets the password for the user
    *   
    * @param    string      $password       User's password
    *
    */
    function setPassword($password)
    {
        $this->_password = $password;
    }

    /**
    * Gets the current password
    *
    * @return   string      User's password
    *
    */
    function getPassword()
    {
        return $this->_password;
    }

    /**
    * Sets unix timestamp when user changed their password last
    *
    * @param    string      $lastPWChagneTimeStamp  Unix timestamp
    *
    */
    function setLastPWChange($lastPWChangeTimeStamp)
    {
        $this->_lastPWChange;
    }

    /**
    * Returns last time password was changed
    *
    * @return   string      Unix timestamp
    *
    */
    function getLastPWChange()
    {
        $this->_lastPWChange;
    }

    /**
    * Sets if the password requires change
    *
    * @return   boolean     True of false
    *
    */
    function setPWChangeRequired($switch)
    {
        $this->_pwChangeRequired = $switch;
    }

    /**
    * Returns if the password has expired or not
    *
    * @return   boolean     True of false
    *
    */
    function isPasswordExpired()
    {
        return false;
    }

    /**
    * Set whether or no the account is locked
    *
    * @param    boolean     $switch     True or false
    *
    */
    function setAccountLocked($switch)
    {
        $this->_accountLocked = $switch;
    }

    /**
    * Returns whether or not the account is locked
    *
    * @return   boolean     True of false
    *
    */
    function isAccountLocked()
    {
        return $this->_accountLocked;
    }

    /**
    * Returns the privilges a user has
    *
    * @return   AAPrivilege[]   Array of privileges
    *
    */
    function getPrivileges()
    {
        return $this->_privileges;
    }

    /**
    * Sets the privileges a user has
    *
    * @prarm    array   $privArray  Array of AAPrivilege objects
    *
    */
    function setPrivileges($privArray)
    {
        $this->_privileges = $privArray;
    }

    function listAppPrivileges()
    {
        $adminUserName = $this->getUserName();
        $adminPassword = $this->getPassword();
        $appId = $this->getAppId();
        
        if (empty($adminUserName) OR empty($adminPassword) OR empty($appId))  {
            $exception = new AAException(INSUFFICIENT_DATA_EXCEPTION);
            $exception->setMessage('User Name, Password or Application was not supplied to listAppPrivileges()');
            return $exception;
        }
        $authProvider = &AAProviderFactory::getProvider($this->_appId);
        return $authProvider->listAppPrivileges($this->getAppId(), $this->getUserName(), $this->getPassword());
    }
    
    function listAppGroups()
    {
        $adminUserName = $this->getUserName();
        $adminPassword = $this->getPassword();
        $appId = $this->getAppId();
        
        if (empty($adminUserName) OR empty($adminPassword) OR empty($appId)) {
            $exception = new AAException(INSUFFICIENT_DATA_EXCEPTION);
            $exception->setMessage('User Name, Password or Application was not supplied to listAppGroups()');
            return $exception;
        }
        $authProvider = &AAProviderFactory::getProvider($appId);
        return $authProvider->listAppGroups($this->getAppId(), $this->getUserName(), $this->getPassword());
    }
    
    /**
    * Returns the groups a user belongs to
    *
    * @return   AAGroup[]   Array of groups
    *
    */
    function getGroups()
    {
        return $this->_groups;
    }

    /**
    * Sets the groups a user belongs to
    *
    * @prarm    array   $groupArray  Array of AAGroup objects
    *
    */
    function setGroups($groupArray)
    {
        $this->_groups = $groupArray;
    }
}

?>

--- NEW FILE: AAUtil.class.php ---
<?php

/**
* PEAR's log libarary
*/
require_once('Log.php');
require_once('Log/file.php');

/**
* PHP doesn't like class methods for error handlers so this gets
* around that
*/
function errorHandler($errNo, $errStr, $errFile, $errLine)
{
    AAUtil::errorHandler($errNo, $errStr, $errFile, $errLine);
}

set_error_handler('errorHandler');

/**
* Provide utility type functions that don't really fit in a class
* by themselves
*
* @access public 
* @author Tony Bibbs <tony AT geeklog DOT net>
* @package net.geeklog.enterprise.aa.server.util
*
*/
class AAUtil {

    /**
    * Logs a message, this libary logs stuff to logs/error_log.txt
    *
    * @access public
    * @message string $message Message to log
    * @priority integer $priority  Priority of message
    *
    */
    function logIt($message, $priority = PEAR_LOG_INFO)
    {
        $logFile = 'logs/error_log.txt';
        
        if (!is_writable($logFile)) {
            print "Log file, $logFile, is not writeable...exiting";
            exit;
        }

        $log = &Log::singleton('file', $logFile, 'A&A Log');
        $log->log($message, $priority);
    } 

    /**
    * Custom error handler
    * 
    * This method is used to override the default PHP error handling and
    * lets us intercept everything and log the way we want
    * 
    * @access public
    * @param string $errNo Error Number
    * @param string $errStr Error String
    * @param string $errFile File that error was encountered in
    * @param string $errLine line in file that caused error
    * @param array  $context Holds values of all variables at time of error
    *
    */
    function errorHandler($errNo, $errStr, $errFile, $errLine, $context=array())
    {
        error_reporting(E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING);
        
        switch ($errNo) {
            case E_USER_ERROR:
                $message = "\nError Type: FATAL ERROR\n";
                break;
            case E_USER_WARNING:
                $message = "\nError Type: WARNING\n";
                break;
            case E_USER_NOTICE:
                $message = "\nError Type: NOTICE\n";
                break;
        }
        $message .= "     Script: $errFile\n";
        $message .= "       Line: $errLine\n";
        $message .= "    Message: $errStr\n";
    
        AAUtil::logIt($message); 

    }

    /**
    * Validates if a password meets our requirements for a valid password
    *
    * @access public
    * @param string $password Password to validate
    * @return boolean true if we got a valid password, otherwise false
    *
    */
    function validatePassword($password)
    {
        global $_CONF;

        if (empty($password)) {
            return false;
        }

        // Make sure password meets minimum length requirement
        if (strlen($password) < $_CONF['PASSWORD_MIN_LENGTH']) {
            return false;
        }

        // Make sure password doesn't exceed DB field size
        if (strlen($password) > 20) {
            return false;
        }

        // Make sure password has at least one number if required.
        if ($_CONF['PASSWORD_REQUIRES_ONE_NUMBER']) {
            $hasNum = false;
            for ($i = 0; $i <= 9; $i++) {
                if (strstr((string)$password, (string)$i)) {
                    $hasNum = true;
                    break;
                }
            }
            if (!$hasNum) {
                return false;
            }
        }

        // Make sure password has at least one uppercase letter if required.
        if ($_CONF['PASSWORD_REQUIRES_ONE_UPPER']) {
            $hasUpper = false;
            for ($i = 65; $i <= 90; $i++) {
                if (strstr($password, chr($i))) {
                    $hasUpper = true;
                    break;
                }
            }
            if (!$hasUpper) {
                return false;
            }
        }
       
        return true;
    }

    function generatePassword()
    {
        global $_CONF;

        $isValid = false;
        $chars = array();

        while (!$isValid) {
            for ($i = 48; $i <= 57; $i++) {
                array_push($chars, chr($i));
            }

            for ($i = 97; $i <= 122; $i++) {
                array_push($chars, chr($i));
            }

            for ($i = 65; $i <= 90; $i++) {
                array_push($chars, chr($i));
            }

            // Radomly generate a valid lenth for the password
            mt_srand((double)microtime()*1000000);
            $passwordLength = mt_rand($_CONF['PASSWORD_MIN_LENGTH'],20);

            // Now randomly generate a password 
            $generatedPassword = '';
            for ($i = 1; $i <= $passwordLength; $i++) {
                mt_srand((double)microtime()*1000000);
                $generatedPassword .= $chars[mt_rand(0,count($chars) - 1)];
            }

            // Validate it
            $isValid = AAUtil::validatePassword($generatedPassword);
        }                
        return $generatedPassword;
    }
}

?>

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

/**
* Enterprise A&A Configuration File
*
* @author Tony Bibbs <tony AT geeklog DOT net>
*
*/
$_CONF['PATH_COMMON'] = '/path/to/common/AA/code';
$_CONF['DEFAULT_AA_PROVIDER']          = 'SQLProvider';
$_CONF['PASSWORD_RESET_METHOD']        = 'RANDOM';
$_CONF['PASSWORD_MIN_LENGTH']          = 6;
$_CONF['PASSWORD_REQUIRES_ONE_NUMBER'] = true; 
$_CONF['PASSWORD_REQUIRES_ONE_UPPER']  = true; 
$_CONF['PASSWORD_HISTORY_LENGTH']      = 3;

//---------------------------------------
// PROVIDER SETTINGS, ONLY MODIFY IF YOU
// HAVE ADDED OR CHANGED A PROVIDER
//---------------------------------------
$_CONF['AA_DB_HOST'] = 'localhost';
$_CONF['AA_DB_DBMS'] = 'mysql';
$_CONF['AA_DB_NAME'] = 'geeklog2';
$_CONF['AA_DB_USER'] = 'username';
$_CONF['AA_DB_PASS'] = 'password';

//---------------------------------------
// APPLICATION SETTINGS
//---------------------------------------
//NOTE: you need not specify the provider for your application 
//unless it is different from the DEFAULT_AA_PROVIDER above. If 
//different, you must the right application ID you set in your
//e.g.
//----
//$_CONF['app_name'] = '<providerName>';
//$_CONF['MY_APP'] = 'LDAP'

?>

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

require_once('AAProviderProperties.class.php');
require_once('AAServiceHandler.class.php');
require_once('AAUtil.class.php');

$handler = new AAServiceHandler();
$handler->doPost();

?>





More information about the geeklog-cvs mailing list