[geeklog-cvs] geeklog-2/public_html/server/A_and_A/providers SQLProvider.class.php,NONE,1.1

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


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

Added Files:
	SQLProvider.class.php 
Log Message:
Initial load into Geeklog


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

require_once('../config.php');

/**
* PEAR's database abstraction library
*/
require_once('DB.php');

/**
* A&A properties class
*/
//require_once('../AAProviderProperties.class.php');

/**
* A&A Exception class
*/
require_once($_CONF['PATH_COMMON'] . 'AAException.class.php');
require_once($_CONF['PATH_COMMON'] . 'AAPrivilege.class.php');
require_once($_CONF['PATH_COMMON'] . 'AAGroup.class.php');
/**
* This is the SQL provider for the A&A system. 
*
* This implemented a SQL provider for the A&A Service. You
* must provide database paramters in the AAService.ini and
* configure your application(s) to use the correct provider.
* There is a corresponding SQL file in the sql dir for
* the various supported databases
*
* @author Tony Bibbs <tony AT geeklog DOT net>
* @package net.geeklog.enterprise.aa.server.provider
*
*/
class SQLProvider {

    var $_db;
    var $_fetchMode  = DB_FETCHMODE_ASSOC;
    var $_isAuthenticated = false;

    /**
    * Connects to the database
    *
    * @access private
    * @return   object      returns a valid database connection
    * 
    */
    function _dbConnect()
    {
        // Only connect if we don't have a connection already
        if (empty($this->_db)) {
            $dbHost = $confFile->getValue('SQL','AA_DB_HOST');
            $dbDbms = $confFile->getValue('SQL','AA_DB_DBMS');
            $dbName = $confFile->getValue('SQL','AA_DB_NAME');
            $dbUser = $confFile->getValue('SQL','AA_DB_USER');
            $dbPass = $confFile->getValue('SQL','AA_DB_PASS');
            
            $this->_fetchMode = DB_FETCHMODE_ASSOC;

            $this->_db =  DB::connect($_CONF['AA_DB_DBMS'] . '://' . $_CONF['AA_DB_USER'] . ':' . $_CONF['AA_DB_PASS'] . '@' . $_CONF['AA_DB_HOST']. '/' . $_CONF['AA_DB_NAME']);
        }
    }

    /**
    * Authenticates a user to the database
    *
    * @param    string      $appId      Application ID
    * @param    string      $userId     User ID
    * @param    string      $password   Password
    * @return   object      AAServiceUser or AAException
    *
    */
    function &authenticate($appId, $userName, $password)
    {
        $this->_dbConnect();

        // We store user id and app id in uppercase as usernames are case insensitive
        $userName = strtoupper($userName);
        $appId = strtoupper($appId);

        //$encryptedPass = MD5($password);
        $encryptedPass = $password;
        $result = $this->_db->query("SELECT * FROM user WHERE username = '$userName' AND password = '$encryptedPass'");
        
        if (DB::isError($result)) {
            trigger_error('Database error encountered in authenticate method of SQLProvider.class.php: ' . $result->getMessage());
            $exception = new AAException(UNEXPECTED_FATAL_EXCEPTION);
            $exception->setMessage('An unexpected error occured while authenticating.  Please contact the server administrator');

            return $exception;
        }
        
        if ($result->numRows() > 0) {
            $user = new AAServiceUser();
            $user = &$this->_mapResultToUserObject($result);
            $user->setAppId($appId);

            // Ensure the account hasn't been locked
            if ($user->isAccountLocked()) {
                // return an exception
                $exception = new AAException(ACCOUNT_LOCKED_EXCEPTION);
                $exception->setMessage('Account for ' . $userName . ' is locked');

                return $exception;
            }
            
            // Check to see if password has expired.
            if ($user->isPasswordExpired()) {
                //return an exception
                $exception = new AAException(PASSWORD_EXPIRED_EXCEPTION);
                $exception->setMessage('Password for ' . $userName . ' has expired');
        
                return $exception;
            }
            
            // We get the groups as those will be sent back in user object
            $groupArray = $this->getGroups($appId, $user->getUserName());
            $user->setGroups($groupArray);
            $user->setPrivileges($this->getPrivileges($appId, $user->getUserName(), $groupArray));
            
            $this->_isAuthenticated = true;
            
            return $user; 
        } else {
            // Invalid user
            $exception = new AAException(INVALID_USER_EXCEPTION);
            $exception->setMessage('No accounts match the credentials given');

            return $exception;
        }
    }

    /**
    * Changes the user's password
    *
    * @access public
    * @param string $appId Application ID
    * @param string $userId User's ID
    * @param string $password User's password
    * @param string $newPassword User's new password
    * @return object|boolean either an exception object or nothing
    *
    */
    function changePassword($appId, $userName, $password, $newPassword)
    {
        $this->_dbConnect();

        // We store user id and app id in uppercase as usernames are case insensitive
        $userName = strtoupper($userName);
        $appId = strtoupper($appId);

        // Validate the password
        if (!AAUtil::validatePassword($appId, $newPassword)) {
            $exception = new AAException(INVALID_NEW_PASSWORD_EXCEPTION);
            $exception->setMessage('The new password given was rejected.  Please follow guidelines for choosing acceptable passwords');
            return $exception;
        }

        //$newPassword = MD5($newPassword);

        if (!$this->_isAuthenticated) {
            $authResult = $this->authenticate($appId, $userName, $password);
        }

        if (get_class($authResult) == 'aaexception') {
            // Bad credentials
            return $authResult;
        }    

        // Actually change hte password now
        $pwdLastSet = time();
        $sql = "UPDATE user SET password = '$newPassword', pwd_last_set = '$pwdLastSet' WHERE username = '$userName'";
        $result = $this->_db->query($sql);

        // Handle any errors
        if (DB::isError($result)) {
            trigger_error('Unable to set new password, got this error: ' . $result->getMessage());
            $exception = new AAException(UNEXPECTED_FATAL_EXCEPTION);
            $exception->setMessage('Unable to set new password because of a database error, please contact the administrator');
            return $exception;
        } else {
            trigger_error('successfully changed password for user: ' . $userName);
        }

        return false; 
         
    }

    /**
    * Allows an admin to change a password for a user
    *
    * @access public
    * @param string $appId Application ID
    * @param string $adminUserId Administrator's ID
    * @param string $adminPassword Administrator's password
    * @param string $userId ID of user to change password for
    * @param string $newPassword New password to give to user
    *
    */
    function changePasswordByAdmin($appId, $adminUserName, $adminPassword, $userName, $newPassword)
    {
        $this->_dbConnect();

        $appId = strtoupper($appId);
        $adminUserName = strtoupper($adminUserName);
        $userName = strtoupper($userName);

        if (!AAUtil::validatePassword($newPassword)) {
            $exception = new AAException(INVALID_NEW_PASSWORD_EXCEPTION);
            $exception->setMessage('The new password given was rejected.  Please follow guidelines for choosing acceptable passwords');
            return $exception;
        }

        //$newPassword = MD5($newPassword);
        
        if (!$this->_isAuthenticated) {
            $adminUser = $this->authenticate($appId, $adminUserName, $adminPassword);
        } else {
            $adminUser = new AAServiceUser();
            $adminUser->setUserName($adminUserName);
            $adminUser->setPassword($adminPassword);
            $adminUser->setAppId($appId);
            //$adminUser->_privileges = $this->getUserPrivileges($appId, $adminUserName, $adminPassword, $userName);
            $adminUser->_privileges = $this->getPrivileges($appId, $adminUserName);
        }

        if (get_class($adminUser) == 'aaexception') {
            // Bad credentials
            return $adminUser;
        }

        if (!$adminUser->authorize(AA_ADMIN_PRIV)) {
            $exception = new AAException(INVALID_PRIVILEGE_EXCEPTION);
            $exception->setMessage("User $adminUserName does not have sufficient privileges to change paswords for other users");
            return $exception;
        }

        // Actually change hte password now
        $pwdLastSet = time();
        $sql = "UPDATE user SET password = '$newPassword', pwd_last_set = '$pwdLastSet' WHERE username = '$userName'";
        $result = $this->_db->query($sql);

        // Handle any errors
        if (DB::isError($result)) {
            trigger_error('Unable to set new password, got this error: ' . $result->getMessage());
            $exception = new AAException(UNEXPECTED_FATAL_EXCEPTION);
            $exception->setMessage('Unable to set new password because of a database error, please contact the administrator');
            return $exception;
        } else {
            if ($this->_db->affectedRows() == 0) {
                trigger_error('No record was changed in ' . __FILE__ .' for user '. $userName . ' in changePasswordByAdmin()');
                $exception = new AAException(UNEXPECTED_FATAL_EXCEPTION);
                $exception->setMessage('Unable to set new password for user ' . $userName . '. Please contact the administrator');
                return $exception;
            } else {
                trigger_error($adminUserName . ' successfully changed password for user: ' . $userName);
            }
        }

        return false;
    }

    /**
    * Resets a user's password
    *
    * @access public
    * @param string $appId Application ID
    * @param string $adminUserId Admin's user ID    
    * @param string $adminPassword Admin's Password
    * @param string $userId ID of user to reset password for
    * @return boolean True on success, otherwise false
    *
    */
    function resetPassword($appId, $adminUserName, $adminPassword, $userName)
    {
        $adminUserName = strtoupper($adminUserName);
        $appId = strtoupper($appId);
        $userName = strtoupper($userName);

        if (!$this->_isAuthenticated) {
            $adminUser = $this->authenticate($appId, $adminUserName, $adminPassword);
        }

        if (get_class($adminUser) == 'aaexception') {
            // Bad credentials
            return $adminUser;
        }

        if (!$adminUser->authorize(AA_ADMIN_PRIV)) {
            $exception = new AAException(INVALID_PRIVILEGE_EXCEPTION);
            $exception->setMessage('User, ' . $adminUser->getuserName() . ', does not have sufficient privileges to reset paswords for other users');
            return $exception;
        }
        $newPassword = AAUtil::generatePassword();

        $this->changePasswordByAdmin($appId, $adminUserName, $adminPassword, $userName, $newPassword);
        
        return $newPassword;
    }

    /**
    * Sets the privileges a user has for the given application
    *
    * @access public
    * @param string $appId Application ID
    * @param string $adminUserId Admin's User ID
    * @param string $adminPassword Admin's Password
    * @param string $userId ID of user to get privileges for
    *
    */
    function getUserPrivileges($appId, $adminUserName, $adminPassword, $userName)
    {
        $adminUserName = strtoupper($adminUserName);
        $appId = strtoupper($appId);
        $userName = strtoupper($userName);

        if (!$this->_isAuthenticated) {
            $adminUser = $this->authenticate($appId, $adminUserName, $adminPassword);
        } else {
            $adminUser = new AAServiceUser();
            $adminUser->setUserName($adminUserName);
            $adminUser->setPassword($adminPassword);
            $adminUser->setAppId($appId);
            $adminUser->_privileges = $this->getPrivileges($appId, $adminUserName);
        }

        if (get_class($adminUser) == 'aaexception') {
            // Bad credentials
            return $adminUser;
        }

        if (!$adminUser->authorize(AA_ADMIN_PRIV)) {
            $exception = new AAException(INVALID_PRIVILEGE_EXCEPTION);
            $exception->setMessage('User, ' . $adminUser->getUserid() . ', does not have sufficient privileges to get privileges for other users');
            return $exception;
        }
        return $this->getPrivileges($appId, $userName);
    }
    
    function getUserGroups($appId, $adminUserId, $adminPassword, $userId)
    {
        $adminUserId = strtoupper($adminUserId);
        $appId = strtoupper($appId);
        $userId = strtoupper($userId);
        
        if (!$this->_isAuthenticated) {
            $adminUser = $this->authenticate($appId, $adminUserId, $adminPassword);
        }

        if (get_class($adminUser) == 'aaexception') {
            // Bad credentials
            return $adminUser;
        }

        if (!$adminUser->authorize(AA_ADMIN_PRIV)) {
            $exception = new AAException(INVALID_PRIVILEGE_EXCEPTION);
            $exception->setMessage('User, ' . $adminUser->getUserid() . ', does not have sufficient privileges to get groups for other users');
            return $exception;
        }
        
        return $this->getGroups($appId, $userId);
    }

    /**
    * Sets the privileges a user has for the given application
    *
    * @access public
    * @param string $appId Application ID
    * @param string $adminUserId Admin's User ID
    * @param string $adminPassword Admin's Password
    * @param string $userId ID of user to set privileges for
    * @param AAPrivilege[] Array of privleges
    *
    */
    function setUserPrivileges($appId, $adminUserId, $adminPassword, $userId, $privArray)
    {
        // Convert params to upper case
        $adminUserId = strtoupper($adminUserId);
        $appId = strtoupper($appId);
        $userId = strtoupper($userId);

        // Authenticate the administrator
        if (!$this->_isAuthenticated) {
            $adminUser = $this->authenticate($appId, $adminUserId, $adminPassword);
        }

        if (get_class($adminUser) == 'aaexception') {
            // Bad credentials
            return $adminUser;
        }

        // Make sure user is, in fact, an dministrator
        if (!$adminUser->authorize(AA_ADMIN_PRIV)) {
            $exception = new AAException(INVALID_PRIVILEGE_EXCEPTION);
            $exception->setMessage('User, ' . $adminUser->getUserid() . ', does not have sufficient privileges to set privileges for other users');
            return $exception;
        }
    
        // Now get list of all available privileges for this application
        $appPrivArray = $this->listAppPrivileges($appId, $adminUserId, $adminPassword, false);

        // Verify each privilege we are trying to assign is found in list of application
        // privileges
        foreach ($privArray as $curPriv) {
            $found = false;
            foreach ($appPrivArray as $curAppPriv) {
                if ($curPriv->getPrivilegeCode() == $cuAppPriv->getPrivilegeCode()) {
                    $found = true;
                    break;
                }
            }
            if (!$found) {
                $exception = new AAException(INVALID_PRIVILEGE_EXCEPTION);
                $exception->setMessage('Privilege, ' . $curPriv->getPrivilegeCode() . ', does not exist for ' . $appId);
                return $exception;
            }
        }

        // Ok, now delete all privileges for the user
        // NOTE: need to add begin transaction
        $this->_dbConnect();
        if ($this->_db->provides('transactions')) {
            $this->_db->autoCommit(false);
        }
        $sql = "DELETE FROM user_privileges WHERE user_id = $userId AND app_id = $appId";
        $result = $this->_db->query($sql);
        if (DB::isError($result)) {
            trigger_error("Unable to delete privileges for $userId...got this error: " . $result->getMessage());
            $exception = new AAException(UNEXPECTED_FATAL_EXCEPTION);
            $exception->setMessage("Unable to set the user's privileges because of a database error, please contact the administrator");
            return $exception;
        }

        // Now assign new privileges
        foreach ($privArray as $curPriv) {
            $sql = "INSERT INTO user_privileges (user_id, app_id, privilege_cd) VALUES ('$userId','$appId','" . $curPriv->getPrivilegeCode() . "'";
            trigger_error($sql);
            $result = $this->_db->query($sql);
            if (DB::isError($result)) {
                trigger_error("Unable to insert privilege for $userId...got this error: " . $result->getMessage());
                $exception = new AAException(UNEXPECTED_FATAL_EXCEPTION);
                $exception->setMessage("Unable to add a privilege for the user because of a database error, please contact the administrator");
                return $exception;
            }
        }
        // NOTE: need to add end transaction
    }

    /**
    * Lists the privileges for the given application
    *
    * @access public
    * @param string  $appId            Application ID
    * @param string  $adminUserName      Admin's User ID
    * @param string  $adminPassword    Admin's Password
    * @param boolean $doAuthentication Indicates whether or not to authenticate
    *
    */
    function listAppPrivileges($appId, $adminUserName, $adminPassword, $doAuthentication = true)
    {
        // They may have already been authenticated by another method such as
        // setUserPrivileges.  If so, don't go through the trouble of authenticating again
        if ($doAuthentication) {
            $adminUserName = strtoupper($adminUserName);
            $appId = strtoupper($appId);
            
            $adminUser = $this->authenticate($appId, $adminUserName, $adminPassword);
            
            if (get_class($adminUser) == 'aaexception') {
                // Bad credentials
                return $adminUser;
            }

            // Make sure user is, in fact, an administrator
            if (!$adminUser->authorize(AA_ADMIN_PRIV)) {
                $exception = new AAException(INVALID_PRIVILEGE_EXCEPTION);
                $exception->setMessage('User, ' . $adminUser->getUserName() . ', does not have sufficient privileges to list privileges for application.');
                return $exception;
            }
        }

        // Get all the privileges for the application
        $this->_dbConnect();
        $sql = "SELECT privilege_cd, privilege_desc FROM app_privileges WHERE app_id = '$appId'";
        $result = $this->_db->query($sql);

        // Handle any errors
        if (DB::isError($result)) {
            trigger_error("Unable to get privileges for application $appId...got this error: " . $result->getMessage());
            $exception = new AAException(UNEXPECTED_FATAL_EXCEPTION);
            $exception->setMessage("Unable to get the application privileges because of a database error, please contact the administrator");
            return $exception;
        }

        // Create privilege array
        $privilege = new AAPrivilege();
        $appPrivileges = array();
        while ($row = $result->fetchRow($this->_fetchMode)) {
            $privilege->setPrivilegeCode($row['privilege_cd']);
            $privilege->setPrivilegeDesc($row['privilege_desc']);
            $appPrivileges[] = $privilege;
        }

        // Return privilege array
        return $appPrivileges;
    }

    function listAppGroups($appId, $adminUserName, $adminPassword)
    {
        $adminUserName = strtoupper($adminUserName);
        $appId = strtoupper($appId);
        
        $adminUser = $this->authenticate($appId, $adminUserName, $adminPassword);
        
        if (get_class($adminUser) == 'aaexception') {
            // Bad credentials
            return $adminUser;
        }

        // Make sure user is, in fact, an administrator
        if (!$adminUser->authorize(AA_ADMIN_PRIV)) {
            $exception = new AAException(INVALID_PRIVILEGE_EXCEPTION);
            $exception->setMessage('User, ' . $adminUser->getUserid() . ', does not have sufficient privileges to list privileges for application.');
            return $exception;
        }
        
        // Get all the privileges for the application
        $this->_dbConnect();
        $sql = "SELECT group_id, group_logical_name, group_display_name, group_descr FROM groups WHERE app_id = '$appId' ORDER BY group_display_name";
        $result = $this->_db->query($sql);

        // Handle any errors
        if (DB::isError($result)) {
            //trigger_error("Unable to get groups for application $appId...got this error: " . $result->getMessage());
            $exception = new AAException(UNEXPECTED_FATAL_EXCEPTION);
            $exception->setMessage("Unable to get the application groups because of a database error, please contact the administrator");
            return $exception;
        }

        // Create group array
        $group = new AAGroup();
        $appGroups = array();
        while ($row = $result->fetchRow($this->_fetchMode)) {
            $group->setGroupId($row['group_id']);
            $group->setGroupLogicalName($row['group_logical_name']);
            $group->setGroupDisplayName($row['group_display_name']);
            $group->setGroupDesc($row['group_descr']);
            $group->setGroupPrivileges($this->getPrivileges($appId,'',array($group)));
            $appGroups[] = $group;
        }

        // Return group array
        return $appGroups;
    }
    
    /**
    * Builds AAServiceUser object from SQL result from authenticate
    *
    * @access private
    * @param    object      $sqlResult      Valid database resource object
    * @return   AAServiceUser   User object
    *
    */
    function &_mapResultToUserObject($sqlResult)
    {
        // Pull data into array
        $user = new AAServiceUser();
        $row = $sqlResult->fetchRow($this->_fetchMode);

        // Set user attributes
        $user->setEmpId($row['employee_id']);
        $user->setUserId($row['user_id']);
        $user->setUserName($row['username']);
        $user->setLastPWChange($row['pwd_last_set']);
        if ($row['account_locked'] == 1) {
            $user->setAccountLocked(true);
        } else {
            $user->setAccountLocked(false);
        }

        return $user;
    }

    /**
    * Retrieves all the privileges a user has for a given application
    * from the database
    *
    * @param    string      $appId      Application in question
    * @param    string      $userId     User Id
    * @param    array       $groupARray Array of groups the user belongs to
    * @return   array       Array of AAPrivilege objects
    *
    */
    function getPrivileges($appId, $userName, $groupArray = array())
    {
        $this->_dbConnect();

        // User and appliction ID's are case insensitive
        $userName = strtoupper($userName);
        $appId = strtoupper($appId);

        // Get groups.  This assumes that if you pass a value to this function
        // for groupArray that we don't have to get the groups again and we can
        // just get the privileges in those groups.
        $groupCount = count($groupArray);
        if ($groupCount == 0) {
            $groupArray = $this->getGroups($appId,$userName);
        }
        
        $tmpArray = array();        
        foreach ($groupArray as $curGroup) {
            $tmpArray[] = $curGroup->getGroupId();
        }
        $groupList = '(' . implode(',',$tmpArray) . ')';
        
        // Get privileges
        // Get privileges
        if (count($groupArray) > 0) {
            $result = $this->_db->query("SELECT DISTINCT pa.privilege_cd as code, ap.privilege_desc as descr FROM privilege_access pa, app_privileges ap, user u WHERE pa.app_id = '$appId' AND (pa.group_id IN $groupList OR (u.user_id = pa.user_id AND u.username = '$userName'))");
        } else {
            $result = $this->_db->query("SELECT DISTINCT pa.privilege_cd as code, ap.privilege_desc as descr FROM privilege_access pa, app_privileges ap, user u WHERE pa.app_id = '$appId' AND u.user_id = pa.user_id AND u.username = '$userName'");
        }
        
        if (DB::isError($result)) {
            trigger_error('Database error encountered in getPrivileges method of SQLProvider.class.php: ' . $result->getMessage());
            $exception = new AAException(UNEXPECTED_FATAL_EXCEPTION);
            $exception->setMessage('An unexpected error encountered from the A&A Service.  Please contact the server administrator');

            return $exception;
        }

        // Loop through user's privileges and set array
        $privilege = new AAPrivilege();
        $privArray = array();
        while ($row = $result->fetchRow($this->_fetchMode)) {
            $privilege->setPrivilegeCode($row['code']);
            $privilege->setPrivilegeDesc($row['descr']);
            $privArray[] = $privilege;
        }

        return $privArray;
        
    }
    
    function getGroups($appId, $userName, $userGroups = '', $currentGroupId = '')
    {
        if (empty($userGroups)) {
            $userGroups = array();
        }
    
        if (empty($currentGroupId)) {
            $result = $this->_db->query("SELECT main_group_id,group_display_name,group_logical_name,group_descr FROM group_assignment,groups,user"
                . " WHERE app_id = '$appId' AND group_id = main_group_id AND user.user_id = assigned_user_id AND user.username = '$userName'");
        } else {
            
            $result = $this->_db->query("SELECT main_group_id,group_display_name,group_logical_name,group_descr FROM group_assignment,groups"
                . " WHERE group_id = main_group_id AND assigned_group_id = $currentGroupId");
        }
    
        if (DB::isError($result)) {
            trigger_error('Database error encountered in getGroups method of SQLProvider.class.php: ' . $result->getMessage());
            $exception = new AAException(UNEXPECTED_FATAL_EXCEPTION);
            $exception->setMessage('An unexpected error was encountered with A&A Service.  Please contact the server administrator');

            return $exception;
        }
        
        if ($result->numRows() == 0) {
            return $userGroups;
        }
    
        $curGroup = new AAGroup();
        while ($row = $result->fetchRow($this->_fetchMode)) {
            $curGroup->setGroupId($row['main_group_id']);
            $curGroup->setGroupLogicalName($row['group_logical_name']);
            $curGroup->setGroupDisplayName($row['group_display_name']);
            $curGroup->setGroupDesc($row['group_descr']);
            $userGroups[] = $curGroup;
            $userGroups = $this->getGroups($appId,$userName,$userGroups,$row['main_group_id']);
        }
    
        if (is_array($userGroups)) {
            ksort($userGroups);
        }
    
        return $userGroups;

    }
}

?>





More information about the geeklog-cvs mailing list