reworked the accounts class, to be able to instanciate both backends (ldap&sql), as well as specify the config (account_repository, ldap_*)

This commit is contained in:
Ralf Becker 2007-12-13 02:32:44 +00:00
parent f750f112f3
commit 2aa096915c
3 changed files with 195 additions and 71 deletions

View File

@ -21,24 +21,10 @@
* @version $Id$
*/
// load the backend class, which this class extends
if (empty($GLOBALS['egw_info']['server']['account_repository']))
{
if (!empty($GLOBALS['egw_info']['server']['auth_type']))
{
$GLOBALS['egw_info']['server']['account_repository'] = $GLOBALS['egw_info']['server']['auth_type'];
}
else
{
$GLOBALS['egw_info']['server']['account_repository'] = 'sql';
}
}
include_once(EGW_API_INC . '/class.accounts_' . $GLOBALS['egw_info']['server']['account_repository'] . '.inc.php');
/**
* API - accounts
*
* This class extends a backend class (at them moment SQL or LDAP) and implements some
* This class uses a backend class (at them moment SQL or LDAP) and implements some
* caching on to top of the backend functions. The cache is share for all instances of
* the accounts class and for LDAP it is persistent through the whole session, for SQL
* it's only on a per request basis.
@ -59,7 +45,7 @@ include_once(EGW_API_INC . '/class.accounts_' . $GLOBALS['egw_info']['server']['
* @access public
* @version $Id$
*/
class accounts extends accounts_backend
class accounts
{
var $xmlrpc_methods = array(
array(
@ -97,7 +83,7 @@ class accounts extends accounts_backend
* Depricated: Account data of $this->account_id
*
* @deprecated dont use this in new code, store the data in your own code
* @var unknown_type
* @var array
*/
var $data;
@ -124,16 +110,80 @@ class accounts extends accounts_backend
'start' => 'start with',
'exact' => 'exact',
);
/**
* Backend to use
*
* @var accounts_sql|accounts_ldap
*/
var $backend;
/**
* total number of found entries
*
* @var int
*/
var $total;
/**
* Current configuration
*
* @var array
*/
var $config;
/**
* Constructor
*
* @param int $account_id=0 account to instanciate the class for (depricated)
* @param string|array $backend=null string with backend 'sql'|'ldap', or whole config array, default read from global egw_info
*/
function __construct($backend=null)
{
if (is_numeric($backend)) // depricated use with account_id
{
if ((int)$backend) $this->account_id = (int) $backend;
$backend = null;
}
if (is_array($backend))
{
$this->config = $backend;
$backend = null;
}
else
{
$this->config =& $GLOBALS['egw_info']['server'];
}
if (is_null($backend))
{
if (empty($this->config['account_repository']))
{
if (!empty($this->config['auth_type']))
{
$this->config['account_repository'] = $this->config['auth_type'];
}
else
{
$this->config['account_repository'] = 'sql';
}
}
$backend = $this->config['account_repository'];
}
$backend_class = 'accounts_'.$backend;
$this->backend = new $backend_class($this);
}
/**
* Old constructor name
*
* @param int $account_id=0 depricated param to instanciate for the given account_id
* @deprecated use __construct
*/
function accounts($account_id=0)
{
if($account_id && is_numeric($account_id)) $this->account_id = (int) $account_id;
$this->account_id = (int) $account_id;
$this->accounts_backend(); // call constructor of extended class
$this->__construct();
}
/**
@ -168,11 +218,11 @@ class accounts extends accounts_backend
{
$this->total = $account_search[$serial]['total'];
}
elseif ($GLOBALS['egw_info']['server']['account_repository'] == 'ldap')
elseif ($this->config['account_repository'] == 'ldap')
//not correct for php<5.1 elseif ((method_exists($this,'search')) // implements its on search function ==> use it
{
$account_search[$serial]['data'] = parent::search($param);
$account_search[$serial]['total'] = $this->total;
$account_search[$serial]['data'] = $this->backend->search($param);
$account_search[$serial]['total'] = $this->total = $this->backend->total;
}
else
{
@ -198,19 +248,19 @@ class accounts extends accounts_backend
if (!isset($account_search[$serial2])) // check if we already did this general search
{
$account_search[$serial2]['data'] = array();
$accounts = parent::get_list($param['type'],$param['start'],$param['sort'],$param['order'],$param['query'],$param['offset'],$param['query_type']);
$accounts = $this->backend->get_list($param['type'],$param['start'],$param['sort'],$param['order'],$param['query'],$param['offset'],$param['query_type']);
if (!$accounts) $accounts = array();
foreach($accounts as $data)
{
$account_search[$serial2]['data'][$data['account_id']] = $data;
}
$account_search[$serial2]['total'] = $this->total;
$account_search[$serial2]['total'] = $this->total = $this->backend->total;
}
else
{
$this->total = $account_search[$serial2]['total'];
}
//echo "parent::get_list($param[type],$param[start],$param[sort],$param[order],$param[query],$param[offset],$param[query_type]) returned<pre>".print_r($account_search[$serial2],True)."</pre>\n";
//echo "$this->backend->get_list($param[type],$param[start],$param[sort],$param[order],$param[query],$param[offset],$param[query_type]) returned<pre>".print_r($account_search[$serial2],True)."</pre>\n";
if ($app || $group) // limit the search on accounts with run-rights for app or a group
{
$valid = array();
@ -279,7 +329,7 @@ class accounts extends accounts_backend
if (!isset($account_data[$id]))
{
$account_data[$id] = parent::read($id);
$account_data[$id] = $this->backend->read($id);
}
if (!$account_data[$id] || !$set_depricated_names)
{
@ -314,11 +364,11 @@ class accounts extends accounts_backend
}
}
}
if (($id = parent::save($data)) && $data['account_type'] != 'g')
if (($id = $this->backend->save($data)) && $data['account_type'] != 'g')
{
// if we are not on a pure LDAP system, we have to write the account-date via the contacts class now
if (($GLOBALS['egw_info']['server']['account_repository'] != 'ldap' ||
$GLOBALS['egw_info']['server']['contact_repository'] == 'sql-ldap') &&
if (($this->config['account_repository'] != 'ldap' ||
$this->config['contact_repository'] == 'sql-ldap') &&
(!($old = $this->read($data['account_id'])) || // only for new account or changed contact-data
$old['account_firstname'] != $data['account_firstname'] ||
$old['account_lastname'] != $data['account_lastname'] ||
@ -369,7 +419,7 @@ class accounts extends accounts_backend
if (!$id) return false;
$this->cache_invalidate($id);
parent::delete($id);
$this->backend->delete($id);
// delete all acl_entries belonging to that user or group
$GLOBALS['egw']->acl->delete_account($id);
@ -419,7 +469,7 @@ class accounts extends accounts_backend
{
return False;
}
return $name_list[$which][$name] = parent::name2id($name,$which,$account_type);
return $name_list[$which][$name] = $this->backend->name2id($name,$which,$account_type);
}
/**
@ -488,7 +538,7 @@ class accounts extends accounts_backend
}
if (!isset($memberships_list[$account_id]))
{
$memberships_list[$account_id] = parent::memberships($account_id);
$memberships_list[$account_id] = $this->backend->memberships($account_id);
}
//echo "accounts::memberships($account_id)"; _debug_array($memberships_list[$account_id]);
return $just_id && $memberships_list[$account_id] ? array_keys($memberships_list[$account_id]) : $memberships_list[$account_id];
@ -507,7 +557,7 @@ class accounts extends accounts_backend
{
$account_id = $this->name2id($account_id);
}
parent::set_memberships($groups,$account_id);
$this->backend->set_memberships($groups,$account_id);
$this->cache_invalidate($account_id);
}
@ -531,7 +581,7 @@ class accounts extends accounts_backend
}
if (!isset($members_list[$account_id]))
{
$members_list[$account_id] = parent::members($account_id);
$members_list[$account_id] = $this->backend->members($account_id);
}
//echo "accounts::members($account_id)"; _debug_array($members_list[$account_id]);
return $just_id && $members_list[$account_id] ? array_keys($members_list[$account_id]) : $members_list[$account_id];
@ -546,7 +596,7 @@ class accounts extends accounts_backend
function set_members($members,$gid)
{
//echo "<p>accounts::set_members(".print_r($members,true).",$gid)</p>\n";
parent::set_members($members,$gid);
$this->backend->set_members($members,$gid);
$this->cache_invalidate(0);
}
@ -633,12 +683,12 @@ class accounts extends accounts_backend
*/
function auto_add($account_lid, $passwd)
{
$expires = !isset($GLOBALS['egw_info']['server']['auto_create_expire']) ||
$GLOBALS['egw_info']['server']['auto_create_expire'] == 'never' ? -1 :
time() + $GLOBALS['egw_info']['server']['auto_create_expire'] + 2;
$expires = !isset($this->config['auto_create_expire']) ||
$this->config['auto_create_expire'] == 'never' ? -1 :
time() + $this->config['auto_create_expire'] + 2;
if (!($default_group_id = $this->name2id($GLOBALS['egw_info']['server']['default_group_lid'])))
if (!($default_group_id = $this->name2id($this->config['default_group_lid'])))
{
$default_group_id = $this->name2id('Default');
}
@ -678,6 +728,18 @@ class accounts extends accounts_backend
return $data['account_id'];
}
/**
* Update the last login timestamps and the IP
*
* @param int $account_id
* @param string $ip
* @return int lastlogin time
*/
function update_lastlogin($account_id, $ip)
{
return $this->backend->update_lastlogin($account_id, $ip);
}
function list_methods($_type='xmlrpc')
{

View File

@ -38,7 +38,7 @@
* @subpackage accounts
* @access internal only use the interface provided by the accounts class
*/
class accounts_backend
class accounts_ldap
{
/**
* resource with connection to the ldap server
@ -89,7 +89,7 @@ class accounts_backend
/**
* Classes allowing to set a mail-address for a group and specify the memberaddresses as forwarding addresses
*
* @var unknown_type
* @var array
*/
var $group_mail_classes = array(
'dbmailforwardingaddress' => 'mailforwardingaddress',
@ -99,31 +99,51 @@ class accounts_backend
/**
* reference to the translation class
*
* @var object
* @var translation
*/
var $translation;
/**
* Reference to our frontend
*
* @var accounts
*/
private $frontend;
/**
* Instance of the ldap class
*
* @var ldap
*/
private $ldap;
/**
* Constructor
*
* @return accounts_backend
* @param accounts $frontend reference to the frontend class, to be able to call it's methods if needed
* @return accounts_ldap
*/
function accounts_backend()
function __construct(accounts $frontend)
{
$this->frontend = $frontend;
// enable the caching in the session, done by the accounts class extending this class.
$this->use_session_cache = true;
$this->ds = $GLOBALS['egw']->common->ldapConnect();
$this->ldap = new ldap();
$this->ds = $this->ldap->ldapConnect($this->frontend->config['ldap_host'],
$this->frontend->config['ldap_root_dn'],$this->frontend->config['ldap_root_pw']);
if(!@is_object($GLOBALS['egw']->translation))
{
$GLOBALS['egw']->translation =& CreateObject('phpgwapi.translation');
$GLOBALS['egw']->translation =& new translation();
}
$this->translation =& $GLOBALS['egw']->translation;
$this->user_context = $GLOBALS['egw_info']['server']['ldap_context'];
$this->account_filter = $GLOBALS['egw_info']['server']['ldap_search_filter'];
$this->group_context = $GLOBALS['egw_info']['server']['ldap_group_context'] ?
$GLOBALS['egw_info']['server']['ldap_group_context'] : $GLOBALS['egw_info']['server']['ldap_context'];
$this->user_context = $this->frontend->config['ldap_context'];
$this->account_filter = $this->frontend->config['ldap_search_filter'];
$this->group_context = $this->frontend->config['ldap_group_context'] ?
$this->frontend->config['ldap_group_context'] : $this->frontend->config['ldap_context'];
}
/**
@ -160,7 +180,7 @@ class accounts_backend
if (!is_object($this->ldapServerInfo))
{
$this->ldapServerInfo = $GLOBALS['egw']->ldap->getLDAPServerInfo($GLOBALS['egw_info']['server']['ldap_host']);
$this->ldapServerInfo = $this->ldap->getLDAPServerInfo($this->frontend->config['ldap_host']);
}
// common code for users and groups
// checks if accout_lid (dn) has been changed or required objectclass'es are missing
@ -197,8 +217,7 @@ class accounts_backend
$members = $old ? $old['memberuid'] : $this->members($data['account_id']);
}
// if dn has changed --> delete the old entry, as we cant rename the dn
// $this->delete would call accounts::delete, which will delete als ACL of the user too!
accounts_backend::delete($data['account_id']);
$this->delete($data['account_id']);
unset($old['dn']);
// removing the namedObject object-class, if it's included
if ($key !== false) unset($old['objectclass'][$key]);
@ -241,7 +260,7 @@ class accounts_backend
$groupOfNames = in_array('groupofnames',$old ? $old['objectclass'] : $to_write['objectclass']);
if (!$old && $groupOfNames || $members)
{
$to_write = array_merge($to_write,accounts_backend::set_members($members,
$to_write = array_merge($to_write,$this->set_members($members,
$data['account_id'],$groupOfNames,$dn));
}
// check if we should set a mail address and forwards for each member
@ -421,7 +440,7 @@ class accounts_backend
);
if (!is_object($this->ldapServerInfo))
{
$this->ldapServerInfo = $GLOBALS['egw']->ldap->getLDAPServerInfo($GLOBALS['egw_info']['server']['ldap_host']);
$this->ldapServerInfo = $this->ldap->getLDAPServerInfo($this->frontend->config['ldap_host']);
}
foreach($this->group_mail_classes as $objectclass => $forward)
{
@ -480,7 +499,7 @@ class accounts_backend
'person_id' => $data['uid'][0], // id of associated contact
);
//echo "<p align=right>accounts_ldap::_read_user($account_id): shadowexpire={$data['shadowexpire'][0]} --> account_expires=$user[account_expires]=".date('Y-m-d H:i',$user['account_expires'])."</p>\n";
if ($GLOBALS['egw_info']['server']['ldap_extra_attributes'])
if ($this->frontend->config['ldap_extra_attributes'])
{
$user['homedirectory'] = $data['homedirectory'][0];
$user['loginshell'] = $data['loginshell'][0];
@ -567,7 +586,7 @@ class accounts_backend
// $to_write['phpgwaccountlastlogin'] = $data['lastlogin'];
// $to_write['phpgwaccountlastloginfrom'] = $data['lastloginfrom'];
if ($GLOBALS['egw_info']['server']['ldap_extra_attributes'])
if ($this->frontend->config['ldap_extra_attributes'])
{
if (isset($data['homedirectory'])) $to_write['homedirectory'] = $data['homedirectory'];
if (isset($data['loginshell'])) $to_write['loginshell'] = $data['loginshell'] ? $data['loginshell'] : array();
@ -600,7 +619,7 @@ class accounts_backend
*/
function search($param)
{
//echo "<p>accounts_backend::search(".print_r($param,true)."): ".microtime()."</p>\n";
//echo "<p>accounts_ldap::search(".print_r($param,true)."): ".microtime()."</p>\n";
$account_search = &$this->cache['account_search'];
// check if the query is cached
@ -661,7 +680,7 @@ class accounts_backend
if (is_numeric($param['type'])) // return only group-members
{
if (!($members = $this->members($param['type']))) return array();
//echo "<p>accounts_backend::search() after members($param[type]): ".microtime()."</p>\n";
//echo "<p>accounts_ldap::search() after members($param[type]): ".microtime()."</p>\n";
$filter .= '(|(uid='.implode(')(uid=',$members).'))';
}
@ -679,7 +698,7 @@ class accounts_backend
{
settype($allVals,'array');
$test = @$allVals['uid'][0];
if (!$GLOBALS['egw_info']['server']['global_denied_users'][$test] && $allVals['uid'][0])
if (!$this->frontend->config['global_denied_users'][$test] && $allVals['uid'][0])
{
$accounts[] = Array(
'account_id' => $allVals['uidnumber'][0],
@ -709,7 +728,7 @@ class accounts_backend
{
settype($allVals,'array');
$test = $allVals['cn'][0];
if (!$GLOBALS['egw_info']['server']['global_denied_groups'][$test] && $allVals['cn'][0])
if (!$this->frontend->config['global_denied_groups'][$test] && $allVals['cn'][0])
{
$accounts[] = Array(
'account_id' => -$allVals['gidnumber'][0],
@ -731,7 +750,7 @@ class accounts_backend
$account_search[$unl_serial]['data'] = $sortedAccounts = $arrayFunctions->arfsort($accounts,explode(',',$param['order']),$param['sort']);
$account_search[$unl_serial]['total'] = $this->total = count($accounts);
}
//echo "<p>accounts_backend::search() found $this->total: ".microtime()."</p>\n";
//echo "<p>accounts_ldap::search() found $this->total: ".microtime()."</p>\n";
// return only the wanted accounts
reset($sortedAccounts);
if(is_numeric($start) && is_numeric($offset))
@ -786,6 +805,20 @@ class accounts_backend
}
return False;
}
/**
* Convert an numeric account_id to any other value of that account (account_lid, account_email, ...)
*
* Uses the read method to fetch all data.
*
* @param int $account_id numerica account_id
* @param string $which='account_lid' type to convert to: account_lid (default), account_email, ...
* @return string/false converted value or false on error ($account_id not found)
*/
function id2name($account_id,$which='account_lid')
{
return $this->frontend->id2name($account_id,$which);
}
/**
* Update the last login timestamps and the IP
@ -801,7 +834,7 @@ class accounts_backend
$entry['phpgwaccountlastlogin'] = time();
$entry['phpgwaccountlastloginfrom'] = $ip;
$sri = ldap_search($this->ds, $GLOBALS['egw_info']['server']['ldap_context'], 'uidnumber=' . (int)$_account_id);
$sri = ldap_search($this->ds, $this->frontend->config['ldap_context'], 'uidnumber=' . (int)$_account_id);
$allValues = ldap_get_entries($this->ds, $sri);
$dn = $allValues[0]['dn'];
@ -957,8 +990,8 @@ class accounts_backend
*/
function _get_nextid($account_type='u')
{
$min = $GLOBALS['egw_info']['server']['account_min_id'] ? $GLOBALS['egw_info']['server']['account_min_id'] : 0;
$max = $GLOBALS['egw_info']['server']['account_max_id'] ? $GLOBALS['egw_info']['server']['account_max_id'] : 0;
$min = $this->frontend->config['account_min_id'] ? $this->frontend->config['account_min_id'] : 0;
$max = $this->frontend->config['account_max_id'] ? $this->frontend->config['account_max_id'] : 0;
if ($account_type == 'g')
{
@ -975,10 +1008,10 @@ class accounts_backend
{
$account_id = (int) $GLOBALS['egw']->common->next_id($type,$min,$max);
}
while ($account_id && $this->exists($sign * $account_id)); // check need to include the sign!
while ($account_id && $this->frontend->exists($sign * $account_id)); // check need to include the sign!
if (!$account_id || $GLOBALS['egw_info']['server']['account_max_id'] &&
$account_id > $GLOBALS['egw_info']['server']['account_max_id'])
if (!$account_id || $this->frontend->config['account_max_id'] &&
$account_id > $this->frontend->config['account_max_id'])
{
return False;
}

View File

@ -32,7 +32,7 @@
* @subpackage accounts
* @access internal only use the interface provided by the accounts class
*/
class accounts_backend
class accounts_sql
{
/**
* instance of the db class
@ -65,8 +65,23 @@ class accounts_backend
*/
var $total;
function accounts_backend()
/**
* Reference to our frontend
*
* @var accounts
*/
private $fontend;
/**
* Constructor
*
* @param accounts $frontend reference to the frontend class, to be able to call it's methods if needed
* @return accounts_sql
*/
function __construct(accounts $frontend)
{
$this->frontend = $frontend;
if (is_object($GLOBALS['egw_setup']->db))
{
$this->db = clone($GLOBALS['egw_setup']->db);
@ -455,6 +470,20 @@ class accounts_backend
return ($this->db->f('account_type') == 'g' ? -1 : 1) * $this->db->f('account_id');
}
/**
* Convert an numeric account_id to any other value of that account (account_lid, account_email, ...)
*
* Uses the read method to fetch all data.
*
* @param int $account_id numerica account_id
* @param string $which='account_lid' type to convert to: account_lid (default), account_email, ...
* @return string/false converted value or false on error ($account_id not found)
*/
function id2name($account_id,$which='account_lid')
{
return $this->frontend->id2name($account_id,$which);
}
/**
* Update the last login timestamps and the IP
*