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

geeklog-cvs-admin at lists.geeklog.net geeklog-cvs-admin at lists.geeklog.net
Fri Jul 11 16:29:40 EDT 2003


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

Added Files:
	SQLProvider.class.php 
Log Message:
These directories/files have been moved here from the gl2 public_html directory in order to make it obvious where the A&A framework is so that individual classes can find other required classes for inclusion.  I've moved index.php to sample.index.php because that page will need to be moved to the gl2 webtree and not access from this directory.


--- 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