[geeklog-cvs] Auth_Enterprise/Server/providers BasePearDBProvider.php,NONE,1.1 BaseServerProvider.php,NONE,1.1 LDAPProvider.php,NONE,1.1 PearDBProvider.php,NONE,1.1
tony at iowaoutdoors.org
tony at iowaoutdoors.org
Sun Jul 4 11:28:17 EDT 2004
- Previous message (by thread): [geeklog-cvs] Auth_Enterprise/Server AEPasswordGenerator.class.php,1.4,NONE AEPasswordRules.php,1.1,NONE AEServerConfig.php,1.6,NONE AEServerProviderFactory.class.php,1.5,NONE AEServiceUser.class.php,1.4,NONE AEXMLRPCHandler.class.php,1.4,NONE
- Next message (by thread): [geeklog-cvs] Auth_Enterprise/Server/providers AEBasePearDBProvider.class.php,1.8,NONE AEBaseServerProvider.class.php,1.4,NONE AELDAPProvider.class.php,1.2,NONE AEPearDBProvider.class.php,1.9,NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /var/cvs/Auth_Enterprise/Server/providers
In directory www:/tmp/cvs-serv25047
Added Files:
BasePearDBProvider.php BaseServerProvider.php LDAPProvider.php
PearDBProvider.php
Log Message:
Had to rename classes and files to adhere to PEAR coding standards
--- NEW FILE: BasePearDBProvider.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: BasePearDBProvider.php,v 1.1 2004/07/04 15:28:15 tony Exp $
*
*/
/**
* Service user object
*/
require_once 'Auth/Enterprise/Server/ServiceUser.php';
/**
* Bring in the base Auth_Enterprise provider
*/
require_once 'Auth/Enterprise/Server/providers/BaseServerProvider.php';
/**
* The Auth_Enterprise group domain object
*/
require_once 'Auth/Enterprise/Common/Group.php';
/**
* The Auth_Enterprise privilege domain object
*/
require_once 'Auth/Enterprise/Common/Privilege.php';
/**
* Include the password generator
*/
require_once 'Auth/Enterprise/Server/PasswordGenerator.php';
/**
* Bring in PEAR's database abstraction layer
*/
require_once 'DB.php';
/**
* Auth_Enteprise PEAR database provider
*
* This is the abstract PEAR::DB provider. It implements all of the methods in the
* AEServiceInterface except for the authenticate() and createAccount methods. By doing this you
* can quickly add descendants who have custom authentication behavior (e.g. LDAP) but use the
* PEAR::DB datastore for all authorization needs.
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.auth_enterprise.common
*
*/
abstract class Enterprise_BasePearDBProvider extends Enterprise_BaseServerProvider {
/**
* Instance of PEAR::DB Object
* @access protected
* @var object
*/
protected $db = null;
/**
* Constructor
*
* Build PEAR DB database connection. NOTE: we have turned on PEAR::DB's
* portability feature as Auth_Enterprise should run in literally any
* DBMS environment
*
* @author Tony Bibbs <tony at geeklog.net>
* @access public
*
*/
public function __construct($appId)
{
global $gConf;
parent::__construct($appId);
$dsn = sprintf("%s://%s:%s@%s/%s"
, $gConf[AE_PROVIDER_PEAR_DB]['dbms']
, $gConf[AE_PROVIDER_PEAR_DB]['dbuser']
, $gConf[AE_PROVIDER_PEAR_DB]['dbpassword']
, $gConf[AE_PROVIDER_PEAR_DB]['dbhost']
, $gConf[AE_PROVIDER_PEAR_DB]['dbname']);
$options = array('portability' => DB_PORTABILITY_ALL);
$this->db = DB::connect($dsn, $options);
if (DB::isError($this->db)) {
throw new AEUnableToConnect('Unable to connect to Auth_Enterprise PEAR::DB datasource');
}
}
/**
* Gets the application privileges for a given user
*
* @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 get privileges for
* @return array AEPrivilege array
*
*/
public function getUserPrivilegesByAdmin($adminUserName, $adminPassword, $userName)
{
// Make sure admin is authenticated
if (!$this->isAuthenticated) {
try {
$userObj = $this->authenticate($adminUserName, $adminPassword);
} catch (AESQLException $e) {
throw $e;
} catch (AEAccountLocked $e) {
throw new AEAccountLocked('Administrator\'s account is locked');
} catch (AEPasswordExpired $e) {
throw new AEPasswordExpired('Administrator\'s password has expired');
}
}
try {
return $this->getPrivileges($userName);
} catch (AESQLException $e) {
throw $e;
}
}
/**
* Sets the application privileges for a given user
*
* @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 privilege for
* @param array $privArray Array of AEPrivilege objects
*
*/
public function setUserPrivilegesByAdmin($adminUserName, $adminPassword, $userName, $privArray)
{
// Make sure admin is authenticated
if (!$this->isAuthenticated) {
try {
$userObj = $this->authenticate($adminUserName, $adminPassword);
} catch (AESQLException $e) {
throw $e;
} catch (AEAccountLocked $e) {
throw new AEAccountLocked('Administrator\'s account is locked');
} catch (AEPasswordExpired $e) {
throw new AEPasswordExpired('Administrator\'s password has expired');
}
}
// Verify privileges given even exist
foreach ($privArray as $curPriv) {
try {
if (!$this->privilegeExists($curPriv)) {
throw new AEInvalidPrivilege(sprintf('Privilege %s does not exist
for application %s', $curPriv->getPrivilegeCode(), $this->appId));
}
} catch (AESQLException $e) {
throw $e;
}
}
$userName = strtoupper($userName);
// First delete any privileges the user has (and start SQL transaction)
if ($this->db->provides('transactions')) {
$this->db->autoCommit(false);
}
$prepStmt = $this->db->prepare('DELETE FROM ae_privilege_access WHERE pa_user_name = ?');
$result = $this->db->execute($prepStmt, array($userName));
if (DB::isError($result)) {
$this->db->autoCommit(true);
throw new AESQLException($result->toString());
}
// Now add privileges for the user
$prepStmt = $this->db->prepare('INSERT INTO ae_privilege_access
(pa_priv_cd, pa_app_id, pa_user_name, pa_grp_id)
VALUES (?,?,?,NULL)');
foreach ($privArray as $curPriv) {
$result = $this->db->execute($prepStmt, array($curPriv->getPrivilegeCode(),
$this->appId, $userName));
if (DB::isError($result)) {
if ($this->db->provides('transactions')) {
$this->db->rollback();
$this->db->autoCommit(true);
}
throw new AESQLException($result->toString());
}
}
if ($this->db->provides('transactions')) {
$this->db->commit();
$this->db->autoCommit(true);
}
}
/**
* Lists all available privileges for a given application
*
* @author Tony Bibbs <tony at geeklog.net>
* @access public
*
*/
public function listAppPrivilegesByAdmin($adminUserName, $adminPassword)
{
// Make sure admin is authenticated
if (!$this->isAuthenticated) {
try {
$userObj = $this->authenticate($adminUserName, $adminPassword);
} catch (AESQLException $e) {
throw $e;
} catch (AEAccountLocked $e) {
throw new AEAccountLocked('Administrator\'s account is locked');
} catch (AEPasswordExpired $e) {
throw new AEPasswordExpired('Administrator\'s password has expired');
}
}
if (!$userObj->authorize('AE_ACCOUNT_MGR')) {
throw new AEUserNotAuthorized('This user is not an account manager and is unable to
list the privileges for this application');
}
// Get privileges
$prepStmt = $this->db->prepare('SELECT ap_priv_cd, ap_priv_desc
FROM ae_app_privileges
WHERE ap_app_id = ?');
$result = $this->db->execute($prepStmt, array($this->appId));
//print $result->numRows(); exit;
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
return $this->dbResultToPrivilege($result);
}
/**
* Gets the groups for a given user on behalf of an administrator
*
* @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 get groups for
* @return array Array of AEGroup objects
*
*/
public function getUserGroupsByAdmin($adminUserName, $adminPassword, $userName)
{
// Make sure admin is authenticated
if (!$this->isAuthenticated) {
try {
$userObj = $this->authenticate($adminUserName, $adminPassword);
} catch (AESQLException $e) {
throw $e;
} catch (AEAccountLocked $e) {
throw new AEAccountLocked('Administrator\'s account is locked');
} catch (AEPasswordExpired $e) {
throw new AEPasswordExpired('Administrator\'s password has expired');
}
}
$userName = strtoupper($userName);
if (!$userObj->authorize('AE_ACCOUNT_MGR')) {
throw new AEUserNotAuthorized('This user is not an account manager and is unable to
get the groups for the given user');
}
try {
return $this->getGroups($userName);
} catch (AESQLException $e) {
throw $e;
}
}
/**
* Gets the groups for a given user on behalf of an administrator
*
* @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 AEGroup objects
*
*/
public function setUserGroupsByAdmin($adminUserName, $adminPassword, $userName, $groupArray)
{
// Make sure admin is authenticated
if (!$this->isAuthenticated) {
try {
$userObj = $this->authenticate($adminUserName, $adminPassword);
} catch (AESQLException $e) {
throw $e;
} catch (AEAccountLocked $e) {
throw new AEAccountLocked('Administrator\'s account is locked');
} catch (AEPasswordExpired $e) {
throw new AEPasswordExpired('Administrator\'s password has expired');
}
}
// Verify privileges given even exist
foreach ($groupArray as $curGroup) {
try {
if (!$this->groupExists($curGroup)) {
throw new AEInvalidGroup(sprintf('Group %s does not exist
for application %s', $curGroup->getGroupLogicalName(), $this->appId));
}
} catch (AESQLException $e) {
throw $e;
}
}
$userName = strtoupper($userName);
// First delete any privileges the user has (and start SQL transaction)
if ($this->db->provides('transactions')) {
$this->db->autoCommit(false);
}
$prepStmt = $this->db->prepare('DELETE FROM ae_group_assignment
WHERE ga_assigned_user_name = ?');
$result = $this->db->execute($prepStmt, array($userName));
if (DB::isError($result)) {
$this->db->autoCommit(true);
throw new AESQLException($result->toString());
}
// Now add groups for the user
$prepStmt = $this->db->prepare('INSERT INTO ae_group_assignment
(ga_main_grp_id, ga_assigned_user_name, ga_assigned_grp_id)
VALUES (?,?,NULL)');
foreach ($groupArray as $curGroup) {
$result = $this->db->execute($prepStmt, array($curGroup->getGroupId(),$userName));
if (DB::isError($result)) {
if ($this->db->provides('transactions')) {
$this->db->rollback();
$this->db->autoCommit(true);
}
throw new AESQLException($result->toString());
}
}
if ($this->db->provides('transactions')) {
$this->db->commit();
$this->db->autoCommit(true);
}
}
/**
* Determines if a given group exists for the current application
*
* @author Tony Bibbs <tony at geeklog.net>
* @access private
* @param object $groupObj AEGroup instance
* @return boolean
*
*/
private function groupExists($groupObj)
{
$prepStmt = $this->db->prepare('SELECT count(*)
FROM ae_group
WHERE grp_app_id = ?
AND grp_id = ?');
$result = $this->db->execute($prepStmt, array($this->appId, $groupObj->getGroupId()));
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
$row = $result->fetchRow($this->fetchMode);
if ($row[0] == 1) {
return true;
}
return false;
}
/**
* Determines if a given privilege exists for the current application
*
* @author Tony Bibbs <tony at geeklog.net>
* @access private
* @param object $privObj AEPrivilege instance
* @return boolean
*
*/
private function privilegeExists($privObj)
{
$prepStmt = $this->db->prepare('SELECT count(*)
FROM ae_app_privileges
WHERE ap_app_id = ?
AND ap_priv_cd = ?');
$result = $this->db->execute($prepStmt, array($this->appId, $privObj->getPrivilegeCode()));
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
$row = $result->fetchRow($this->fetchMode);
if ($row[0] == 1) {
return true;
}
return false;
}
/**
* Gets the privileges in an application for the given user
*
* @author Tony Bibbs <tony at geeklog.net>
* @access protected
* @param string $userName User to get privileges for
* @return array Array of AEPrivilege objects
*
*/
protected function getPrivileges($userName)
{
$username = strtoupper($userName);
$prepStmt = $this->db->prepare('SELECT ap_priv_cd, ap_priv_desc
FROM ae_privilege_access, ae_app_privileges
WHERE ap_app_id = pa_app_id
AND pa_app_id = ?
AND pa_user_name = ?');
$result = $this->db->execute($prepStmt, array($this->appId, $userName));
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
return $this->dbResultToPrivilege($result);
}
/**
* Gets the groups a user belongs to
*
* @author Tony Bibbs <tony at geeklog.net>
* @access protected
* @param string $appId Application ID
* @param string $userName Username
* @param array $userGroups Groups collected for user
* @param int $currentGroupId The group ID we are currently working on
* @return array Array of groups user belongs to
*
*/
protected function getGroups($userName, $userGroups = '', $currentGroupId = '')
{
if (empty($userGroups)) {
$userGroups = array();
}
if (empty($currentGroupId)) {
$prepStmt = $this->db->prepare('SELECT ga_main_grp_id,grp_display_name,grp_logical_name,grp_descr
FROM ae_group_assignment,ae_group,ae_user
WHERE grp_app_id = ?
AND grp_id = ga_main_grp_id
AND user_name = ga_assigned_user_name
AND ga_assigned_user_name = ?');
$result = $this->db->execute($prepStmt, array($this->appId, $userName));
} else {
$prepStmt = $this->db->prepare('SELECT ga_main_grp_id,grp_display_name,grp_logical_name,grp_descr
FROM ae_group_assignment,ae_group
WHERE grp_id = ga_main_grp_id
AND ga_assigned_grp_id = ?');
$result = $this->db->execute($prepStmt, array($currentGroupId));
}
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
if (!$result->numRows()) {
return $userGroups;
}
$curGroup = new Enterprise_Group();
while ($row = $result->fetchRow($this->_fetchMode)) {
$curGroup->setGroupId($row[0]);
$curGroup->setGroupLogicalName($row[2]);
$curGroup->setGroupDisplayName($row[1]);
$curGroup->setGroupDesc($row[3]);
$userGroups[] = $curGroup;
$userGroups = $this->getGroups($userName,$userGroups,$row[0]);
}
if (is_array($userGroups)) {
ksort($userGroups);
}
return $userGroups;
}
/**
* Checks to see if the given password has been used recently
*
* @author Tony Bibbs <tony at geeklog.net>
* @access protected
* @param string $password Password to check against the history
* @return boolean
* @todo need to encrypte password once testing is over
*
*/
protected function passwordInHistory($userName, $password)
{
global $gConf;
//$encryptedPass = MD5($password);
$encryptedPass = $password;
$prepStmt = $this->db->prepare('SELECT COUNT(*)
FROM ae_user_old_password WHERE uop_password = ? AND uop_user_name = ?');
$result = $this->db->execute($prepStmt, array($encryptedPass, $userName));
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
$row = $result->fetchRow($this->fetchMode);
if ($row[0] > 0) {
return true;
} else {
return false;
}
}
/**
* Adds a password to a user's history
*
* @author Tony Bibbs <tony at geeklog.net
* @access protected
* @param string $userName User to add password to history for
* @param string $password unencrypted password (we encrypt it on behalf of caller)
* @todo Need to actually encrypte password
*
*/
protected function addPasswordToHistory($userName, $password)
{
global $gConf;
// I use this to test transactions
//throw new AESQLException('test');
$userName = strtoupper($userName);
//$encryptedPassword = MD5($password);
$encryptedPass = $password;
$prepStmt = $this->db->prepare('INSERT INTO ae_user_old_password
(uop_user_name, uop_password, uop_insert_date)
VALUES (?,?,?)');
$result = $this->db->execute($prepStmt, array($userName, $encryptedPass, time()));
// Check for SQL error
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
// Purge history for user if needed
$prepStmt = $this->db->prepare('SELECT uop_insert_date
FROM ae_user_old_password
WHERE uop_user_name = ? ORDER BY uop_insert_date');
$result = $this->db->execute($prepStmt, array($userName));
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
if ($result->numRows() > $gConf[AE_PROVIDER_PEAR_DB]['numoldpasswords']) {
// Note the hack to the starting value of $i. This is done this way so array_merge
// will work right
$prepFinish = '';
$rowsToDelete = array();
for ($i = 1; $i <= ($result->numRows() - $gConf[AE_PROVIDER_PEAR_DB]['numoldpasswords']); $i++) {
$row = $result->fetchRow($this->fetchMode);
$rowsToDelete[$i] = $row[0];
// Build ?-string to add to prepare statement
if ($i == ($result->numRows() - $gConf[AE_PROVIDER_PEAR_DB]['numoldpasswords'])) {
$prepFinish .= '?';
} else {
$prepFinish .= '?,';
}
}
$row = $result->fetchRow($this->fetchMode);
$prepStmt = $this->db->prepare("DELETE FROM ae_user_old_password
WHERE uop_user_name = ?
AND uop_insert_date IN ($prepFinish)");
$result = $this->db->execute($prepStmt,
array_merge(array(0 => $userName), $rowsToDelete));
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
}
}
/**
* Increments the number of failed authentication attempts for a user
*
* NOTE: if the username doesn't exist we simply return. If you get a SQL exception then some
* extraordinary error occured and you should handle it
*
* @author Tony Bibbs <tony at geeklog.net>
* @access protected
* @param string $userName User to update failed authentication attempts for
*
*/
protected function incrementFailedAttempts($userName)
{
global $gConf;
$userName = strtoupper($userName);
$prepStmt = $this->db->prepare('SELECT user_failed_attempts
FROM ae_user
WHERE user_name = ?');
$result = $this->db->execute($prepStmt, array($userName));
if (DB::isError($result)) {
// Just bail because the username could be invalid
return;
}
$row = $result->fetchRow($this->fetchMode);
// Auth_Enterpise sets a thresholed for failed authentication attempts. If we hit it we should
// lock the account
if (($row[0] + 1) >= $gConf[AE_PROVIDER_PEAR_DB]['maxauthattempts']) {
$prepStmt = $this->db->prepare('UPDATE ae_user
SET user_account_locked = 1 WHERE user_name = ?');
$result = $this->db->execute($prepStmt, array($userName));
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
}
$prepStmt = $this->db->prepare('UPDATE ae_user
SET user_failed_attempts = ?
WHERE user_name = ?');
$result = $this->db->execute($prepStmt, array($row[0] + 1, $userName));
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
}
/**
* Converts a PEAR::DB SQL result to privilege objects
*
* @author Tony Bibbs <tony at geeklog.net>
* @access public
* @param object $sqlResult PEAR::DB_Result object
* @return array Array of AEPrivilege objects
*
*/
protected function dbResultToPrivilege($sqlResult)
{
$numRows = $sqlResult->numRows();
$tmpPriv = new Enterprise_Privilege();
$privArray = array();
for ($i = 1; $i <= $numRows; $i++) {
$row = $sqlResult->fetchRow($this->fetchMode);
$tmpPriv = new Enterprise_Privilege();
$tmpPriv->setPrivilegeCode($row[0]);
$tmpPriv->setPrivilegeDesc($row[1]);
$privArray[] = $tmpPriv;
}
return $privArray;
}
/**
* Builds AAServiceUser object from SQL result from authenticate
*
* @author Tony Bibbs <tony at geeklog.net>
* @access private
* @param object $sqlResult Valid database resource object
* @return AAServiceUser User object
*
*/
protected function mapResultToUserObject($sqlResult)
{
// Pull data into array
$user = new Enterprise_ServiceUser();
$row = $sqlResult->fetchRow($this->fetchMode);
// 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: PearDBProvider.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: PearDBProvider.php,v 1.1 2004/07/04 15:28:15 tony Exp $
*
*/
/**
* Bring in the base Auth_Enterprise provider
*/
require_once 'Auth/Enterprise/Server/providers/BasePearDBProvider.php';
/**
* The Auth_Enterprise server configuration file
*/
require_once 'Auth/Enterprise/Server/ServerConfig.php';
/**
* Auth_Enteprise PEAR database provider
*
* This extends the base PEAR::DB server provider and simply implements the authenticate() and
* createAccount() methods against the PEAR::DB datasource. This one can be implemented directly
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.auth_enterprise.server
*
*/
class Enterprise_PearDBProvider extends Enterprise_BasePearDBProvider {
/**
* Constructor
*
* Has parent set the application ID
*
* @author Tony Bibbs <tony at geeklog.net>
* @access public
* @param string $appId Auth_Enterprise assigned application ID
*
*/
public function __construct($appId)
{
parent::__construct($appId);
}
/**
* Authenticates a user
*
* There is a long calling chain from the client end to this point but,
* finally, this is where the real work gets done. This method will authenticate
* a user against a DBMS that is supported by PEAR::DB
*
* @author Tony Bibbs <tony at geeklog.net>
* @access public
* @param string $appId App user is authenticating to
* @param string $userName ID of user trying to log in
* @param string $password Password to try logging in with
* @return object AEServiceUser Object *reference* or PEAR::Error
*
*/
public function authenticate($userName, $password)
{
//$encryptedPass = MD5($password);
$encryptedPass = $password;
$prepStmt = $this->db->prepare('SELECT user_name,user_password,user_account_locked,
user_failed_attempts,user_pwd_last_set FROM ae_user
WHERE user_name = ? AND user_password = ?');
$result = $this->db->execute($prepStmt, array($userName, $encryptedPass));
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
if ($result->numRows() > 0) {
$user = $this->mapResultToUserObject($result);
// Ensure the account hasn't been locked
if ($user->getAccountLocked()) {
throw new AEAccountLocked();
}
// Check to see if password has expired.
if ($user->isPasswordExpired()) {
throw new AEPasswordExpired();
}
$user->setAppId($appId);
try {
// We get the groups as those will be sent back in user object
$user->setGroups($this->getGroups($user->getUserName()));
$user->setPrivileges($this->getPrivileges($user->getUserName()));
} catch (AESQLException $e) {
throw $e;
} catch (Exception $e) {
throw $e;
}
$this->isAuthenticated = true;
return $user;
} else {
// Invalid credentials, try to update the failed attempts for the user. I say try
// because the username could be invalid
try {
$this->incrementFailedAttempts($userName);
} catch (AESQLException $e) {
throw $e;
}
throw new AEInvalidUserCredentials();
}
}
/**
* Creates a user account
*
* Allows calling applications to create a new user account. NOTE: username's are case
* insensitive. This is achieved by converting them all to uppercase. Passwords are case
* sensitive.
*
* @author Tony Bibbs <tony at geeklog.net>
* @access public
* @param string $appId App user is authenticating to
* @param string $userName Username of user trying to log in
* @param string $password Password for new user
*
*/
public function createAccountByAdmin($adminUserName, $adminUserPass, $userName, $password)
{
// Make sure admin is authenticated
if (!$this->isAuthenticated) {
try {
$userObj = $this->authenticate($adminUserName, $adminUserPass);
} catch (AESQLException $e) {
throw $e;
} catch (AEAccountLocked $e) {
throw new AEAccountLocked('Administrator\'s account is locked');
} catch (AEPasswordExpired $e) {
throw new AEPasswordExpired('Administrator\'s password has expired');
}
}
// Begin a SQL transaction if we can
if ($this->db->provides('transactions')) {
print 'starting transaction...<br>';
$this->db->autoCommit(false);
}
// Don't forget to encrypt the password at some point
//$encryptedPass = MD5($password);
$encryptedPass = $password;
$prepStmt = $this->db->prepare('INSERT INTO ae_user (user_name, user_password,
user_account_locked, user_failed_attempts, user_pwd_last_set, user_creation_date,
user_change_date, user_change_user_name)
VALUES (?,?,?,?,?,?,?,?)');
$curTime = time();
$result = $this->db->execute($prepStmt, array(strtoupper($userName), $encryptedPass, 0, 0
, $curTime, $curTime, $curTime, strtoupper($adminUserName)));
if (DB::isError($result)) {
// Rollback transaction
if ($this->db->provides('transactions')) {
$this->db->rollback();
$this->db->autoCommit(true);
}
throw new AESQLException($result->toString());
}
// Add password to history
try {
$this->addPasswordToHistory($userName, $password);
} catch (AESQLException $e) {
// Rollback transaction
if ($this->db->provides('transactions')) {
print 'rolling back transaction...<br>';
$this->db->rollback();
}
throw $e;
}
// Commit transaction
if ($this->db->provides('transactions')) {
$this->db->commit();
$this->db->autoCommit(true);
}
}
/**
* Changes a user's password
*
* NOTE: verification of the old password and confirmation of the new password should be taken
* care of by the calling application. This method will use a transaction if DBMS supports it.
*
* @author Tony Bibbs <tony at geeklog.net>
* @access public
* @param string $userName User for whom to change the password for
* @param string $newPassword The user's new password.
* @todo need to add ability to limit a certain number of password changes within 24 hours.
*
*/
public function changePassword($userName, $newPassword)
{
// Make sure new password is a valid format
if (!Enterprise_PasswordGenerator::isValidPassword($newPassword)) {
throw new AEPasswordInvalid();
}
// Verify the password isn't in our password history
if ($this->passwordInHistory($userName, $newPassword)) {
throw new AEPasswordInHistory();
}
// Begin a SQL transaction if we can
if ($this->db->provides('transactions')) {
$this->db->autoCommit(false);
}
// Change the password
try {
$this->doPasswordChange($userName, $newPassword, $userName);
} catch (AESQLException $e) {
// rollback transaction
if ($this->db->provides('transactions')) {
$this->db->rollback();
$this->db->autoCommit(true);
}
throw $e;
}
// Add password to history
try {
$this->addPasswordToHistory($userName, $newPassword);
} catch (AESQLException $e) {
// Rollback transaction
if ($this->db->provides('transactions')) {
$this->db->rollback();
$this->db->autoCommit(true);
}
// Throw exception
throw $e;
}
// Commit it all
if ($this->db->provides('transactions')) {
$this->db->commit();
$this->db->autoCommit(true);
}
}
/**
* Allows an application administrator to change a user's password
*
* @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 change password for
* @param string $newPassword Password to give to a user
*
*/
public function changePasswordByAdmin($adminUserName, $adminPassword, $userName, $newPassword)
{
// Make sure admin is authenticated
if (!$this->isAuthenticated) {
try {
$userObj = $this->authenticate($adminUserName, $adminPassword);
} catch (AESQLException $e) {
throw $e;
} catch (AEAccountLocked $e) {
throw new AEAccountLocked('Administrator\'s account is locked');
} catch (AEPasswordExpired $e) {
throw new AEPasswordExpired('Administrator\'s password has expired');
}
}
// Need to verify the they have right Auth_Enterprise privilege
if (!$userObj->authorize('AE_ACCOUNT_MGR')) {
throw new AEUserNotAuthorized("User $adminUserName does not have sufficient privileges
to change the password for $userName");
}
// Make sure password adhere's to our password rules
if (!AEPasswordGenerator::isValidPassword($newPassword)) {
throw new AEPasswordInvalid();
}
// Verify the password isn't in our password history
if ($this->passwordInHistory($userName, $newPassword)) {
throw new AEPasswordInHistory();
}
// Begin a SQL transaction if we can
if ($this->db->provides('transactions')) {
$this->db->autoCommit(false);
}
// Change the password
try {
$this->doPasswordChange($userName, $newPassword, $adminUserName);
} catch (AESQLException $e) {
// rollback transaction
if ($this->db->provides('transactions')) {
$this->db->rollback();
$this->db->autoCommit(true);
}
throw $e;
}
// Add password to history
try {
$this->addPasswordToHistory($userName, $newPassword);
} catch (AESQLException $e) {
// Rollback transaction
if ($this->db->provides('transactions')) {
$this->db->rollback();
$this->db->autoCommit(true);
}
// Throw exception
throw $e;
}
// Commit it all
if ($this->db->provides('transactions')) {
$this->db->commit();
$this->db->autoCommit(true);
}
}
/**
* Gives the user a randomly generator password
*
* @author Tony Bibbs <tony at geeklog.net>
* @access public
* @param string $userName User to reset password for
* @return string New password
*
*/
public function resetPassword($userName)
{
$newPassword = Enterprise_PasswordGenerator::generatePassword();
// Begin a SQL transaction if we can
if ($this->db->provides('transactions')) {
$this->db->autoCommit(false);
}
try {
$this->doPasswordChange($userName, $newPassword, $userName);
} catch (AESQLException $e) {
// rollback transaction
if ($this->db->provides('transactions')) {
$this->db->rollback();
$this->db->autoCommit(true);
}
throw $e;
}
try {
$this->addPasswordToHistory($userName, $newPassword);
} catch (AESQLException $e) {
// Rollback transaction
if ($this->db->provides('transactions')) {
$this->db->rollback();
$this->db->autoCommit(true);
}
// Throw exception
throw $e;
}
// Commit it all
if ($this->db->provides('transactions')) {
$this->db->commit();
$this->db->autoCommit(true);
}
return $newPassword;
}
/**
* Atomic function that only does password change
*
* @author Tony Bibbs <tony at geeklog.net>
* @access private
* @param string $userName User to change password for
* @param string $newPassword Password to give to the user
* @param string $changeUserName User that requested the password change
* @todo need to encrypt the password once we are done testing
*
*/
private function doPasswordChange($userName, $newPassword, $changeUserName)
{
//$encryptedPass = MD5($newPassword);
$encryptedPass = $newPassword;
$curTime = time();
$prepStmt = $this->db->prepare('UPDATE ae_user
SET user_password = ?, user_change_date = ?, user_change_user_name = ?,
user_pwd_last_set = ?
WHERE user_name = ?');
$result = $this->db->execute($prepStmt, array($encryptedPass, $curTime, $changeUserName, $curTime,
$userName));
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
}
}
?>
--- NEW FILE: LDAPProvider.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 Ozzyie Chen <ozzyie at doit.wisc.edu>
* @author Tony Bibbs <tony at geeklog.net>
* @copyright 2004
* @version $Id: LDAPProvider.php,v 1.1 2004/07/04 15:28:15 tony Exp $
*
*/
/**
* Bring in the base Auth_Enterprise provider
*/
require_once 'Auth/Enterprise/Server/providers/BasePearDBProvider.php';
/**
* The Auth_Enterprise server configuration file
*/
require_once 'Auth/Enterprise/Server/ServerConfig.php';
/**
* Auth_Enteprise LDAP database provider
*
* This extends the base PEAR::DB server provider and simply implements the authenticate() and
* createAccount() and change password methods against the LDAP datasource.
*
* @author Ozzyie Chen <ozzyie at doit.wisc.edu>
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.auth_enterprise.server
*
*/
class Enterprise_LDAPProvider extends Enterprise_BasePearDBProvider {
/**
* Handle to an LDAP connection
*/
protected $ldapConn = null;
/**
* Sets app ID and establish LDAP connection
*
* @author Ozzyie Chen <ozzyie at doit.wisc.edu>
* @param string $appId Application ID
*
*/
public function __construct($appId)
{
global $gConf;
// Call constructor on parent first
parent::__construct($appId);
// Try connecting to the LDAP server
$this->ldapConn = ldap_connect($gConf[AE_PROVIDER_LDAP]['ldapHost'],
$gConf[AE_PROVIDER_LDAP]['ldapPort']);
if (!$this->ldapConn) {
// Throw LDAP connection exception
throw new AEUnableToConnect('Unable to connect to LDAP server');
}
// Set LDAP protocol version
ldap_set_option($this->ldapConn, LDAP_OPT_PROTOCOL_VERSION, $gConf[AE_PROVIDER_LDAP]['ldapProtocolVersion']);
}
/**
* Binds to the LDAP server with a specific set of credentials
*
* @author Tony Bibbs <tony at geeklog.net>
* @access protected
* @param string $dn
* @param string $userPassword Password to bind with
*/
protected function doBind($dn, $userPassword)
{
if (empty($userPassword)) {
if (!ldap_bind($this->ldapConn, $dn)) {
// Throw LDAP bind exception
throw new AELDAPBindError('LDAP bind failed');
}
} else {
//print "$dn"; exit;
//print_r($this->ldapConn); exit;
if (!ldap_bind($this->ldapConn, $dn, $userPassword)) {
// Throw LDAP bind exception
throw new AELDAPBindError('LDAP bind failed');
}
}
}
/**
* Authenticates user against an LDAP repository
*
* @author Ozzyie Chen <ozzyie at doit.wisc.edu>
* @access protected
* @param string $userName User to authenticate
* @param string $password Password to authenticate with
*
*/
public function authenticate($userName, $password)
{
global $gConf;
try {
$this->doBind("cn=$userName,ou=people,{$gConf[AE_PROVIDER_LDAP]['ldapDC']}", $password);
} catch (AELDAPBindError $e) {
throw new AEInvalidUserCredentials($e->getMessage());
} catch (Exception $e) {
throw $e;
}
// OK, authentication worked, get data for the user
$prepStmt = $this->db->prepare('SELECT user_name,user_password,user_account_locked,
user_failed_attempts,user_pwd_last_set FROM ae_user
WHERE user_name = ?');
$result = $this->db->execute($prepStmt, array($userName));
if (DB::isError($result)) {
throw new AESQLException($result->toString());
}
$this->isAuthenticated = true;
if ($result->numRows() > 0) {
$user = $this->mapResultToUserObject($result);
// Ensure the account hasn't been locked
// Do we need to do this for LDAP or can LDAP
// report this?
if ($user->getAccountLocked()) {
throw new AEAccountLocked();
}
// Check to see if password has expired.
if ($user->isPasswordExpired()) {
throw new AEPasswordExpired();
}
$user->setAppId($appId);
try {
// We get the groups as those will be sent back in user object
$user->setGroups($this->getGroups($user->getUserName()));
$user->setPrivileges($this->getPrivileges($user->getUserName()));
} catch (AESQLException $e) {
throw $e;
} catch (Exception $e) {
throw $e;
}
return $user;
} else {
// Hrm no data for the user exists. This is an obvious error
throw new AEUnknownException('LDAP authenticated fine but the user is not in the database');
}
}
}
?>
--- NEW FILE: BaseServerProvider.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: BaseServerProvider.php,v 1.1 2004/07/04 15:28:15 tony Exp $
*
*/
/**
* The Auth_Enterprise service inteface
*/
require_once 'Auth/Enterprise/Common/ServiceInterface.php';
/**
* The base provider class.
*
* The base provider is an abstract class from which all
* Auth_Enterprise providers inherit from. A provider is
* instantiated by the service at run time. Which provider
* an application uses depends on what it wants to authenticate
* against. For example, you could have an LDAP provider, a
* an IMAP provider, a /etc/passwd provider, etc.
*
* @author Tony Bibbs <tony at geeklog.net>
* @package net.geeklog.auth_enterprise.server
*
*/
abstract class Enterprise_BaseServerProvider implements Enterprise_ServiceInterface {
/**
* Application ID
* @access protected
* @var string
*/
protected $appId = null;
/**
* User authentication can be fired multiple times for the same user which would be inefficient.
* This attribute indicates if the user has been authenticated to save on these extra calls
* @access protected
* @var boolean
*/
protected $isAuthenticated = false;
/**
* Constructor
*
* Sets the Application ID for the provider
*
* @author Tony Bibbs <tony at geeklog.net>
* @access public
* @param string $appId Application ID assigned by Auth_Enterprise server.
*
*/
public function __construct($appId)
{
$this->appId = $appId;
}
/**
* Authenticates a user to an application
*
* @author Tony Bibbs <tony at geeklog.net>
* @access public
*
*/
public function authenticate($userName, $password)
{
}
/**
* 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)
{
}
/**
* Resets a user's password
*
* @author Tony Bibbs <tony at geeklog.net>
* @access public
* @param string $userName User to reset password for
* @return string New password
*
*/
public function resetPassword($userName)
{
}
/**
* Gets the application privileges for a given user
*
* @author Tony Bibbs <tony at geeklog.net>
* @access public
*
*/
public function getUserPrivileges($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)
{
}
public function getUserGroupsByAdmin($adminUserName, $adminPassword, $userName)
{
}
public function setUsterGroupsByAdmin($adminUserName, $adminPassword, $userName, $groupArray)
{
}
}
?>
- Previous message (by thread): [geeklog-cvs] Auth_Enterprise/Server AEPasswordGenerator.class.php,1.4,NONE AEPasswordRules.php,1.1,NONE AEServerConfig.php,1.6,NONE AEServerProviderFactory.class.php,1.5,NONE AEServiceUser.class.php,1.4,NONE AEXMLRPCHandler.class.php,1.4,NONE
- Next message (by thread): [geeklog-cvs] Auth_Enterprise/Server/providers AEBasePearDBProvider.class.php,1.8,NONE AEBaseServerProvider.class.php,1.4,NONE AELDAPProvider.class.php,1.2,NONE AEPearDBProvider.class.php,1.9,NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the geeklog-cvs
mailing list