| Current Path : /home/magalijoj/www/blog/inc/core/ |
| Current File : /home/magalijoj/www/blog/inc/core/class.dc.auth.php |
<?php
# ***** BEGIN LICENSE BLOCK *****
# This file is part of DotClear.
# Copyright (c) 2005 Olivier Meunier and contributors. All rights
# reserved.
#
# DotClear is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# DotClear is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with DotClear; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ***** END LICENSE BLOCK *****
/**
@ingroup DC_CORE
@nosubgrouping
@brief Authentication and user credentials management
dcAuth is a class used to handle everything related to user authentication
and credentials. Object is provided by dcCore $auth property.
*/
class dcAuth
{
protected $core; ///< <b>dcCore</b> dcCore instance
protected $con; ///< <b>connection</b> Database connection object
protected $user_table; ///< <b>string</b> User table name
protected $perm_table; ///< <b>string</b> Perm table name
protected $user_id; ///< <b>string</b> Current user ID
protected $user_info = array(); ///< <b>array</b> Array with user information
protected $user_options = array(); ///< <b>a<rray</b> Array with user options
protected $user_admin; ///< <b>boolean</b> User is super admin
protected $permissions = array(); ///< <b>array</b> Permissions for each blog
protected $allow_pass_change = true; ///< <b>boolean</b> User can change its password
protected $perm_types; ///< <b>array</b> Permission types
/**
Class constructor. Takes dcCore object as single argument.
@param core <b>dcCore</b> dcCore object
*/
public function __construct(&$core)
{
$this->core =& $core;
$this->con =& $core->con;
$this->blog_table = $core->prefix.'blog';
$this->user_table = $core->prefix.'user';
$this->perm_table = $core->prefix.'permissions';
$this->perm_types = array(
'admin' => __('administrator'),
'usage' => __('manage their own entries and comments'),
'publish' => __('publish entries and comments'),
'delete' => __('delete entries and comments'),
'contentadmin' => __('manage all entries and comments'),
'categories' => __('manage categories'),
'media' => __('manage their own media items'),
'media_admin' => __('manage all media items')
);
}
/// @name Credentials and user permissions
//@{
/**
Checks if user exists and can log in. <var>$pwd</var> argument is optionnal
while you may need to check user without password. This method will create
credentials and populate all needed object properties.
@param user_id <b>string</b> User ID
@param pwd <b>string</b> User password
@param user_key <b>string</b> User key check
@return <b>boolean</b>
*/
public function checkUser($user_id, $pwd=null, $user_key=null)
{
# Check user and password
$strReq = 'SELECT user_id, user_super, user_pwd, user_name, '.
'user_firstname, user_displayname, user_email, user_url, '.
'user_default_blog, user_options, '.
'user_lang, user_tz, user_post_status, user_creadt, user_upddt '.
'FROM '.$this->con->escapeSystem($this->user_table).' '.
"WHERE user_id = '".$this->con->escape($user_id)."' ";
$rs = $this->con->select($strReq);
if ($rs->isEmpty()) {
return false;
}
$rs->extend('rsExtUser');
if ($pwd != '')
{
if (crypt::hmac(DC_MASTER_KEY,$pwd) != $rs->user_pwd) {
sleep(rand(2,5));
return false;
}
}
elseif ($user_key != '')
{
if (http::browserUID(DC_MASTER_KEY.$rs->user_id.$rs->user_pwd) != $user_key) {
return false;
}
}
$this->user_id = $rs->user_id;
$this->user_admin = (boolean) $rs->user_super;
$this->user_info['user_pwd'] = $rs->user_pwd;
$this->user_info['user_name'] = $rs->user_name;
$this->user_info['user_firstname'] = $rs->user_firstname;
$this->user_info['user_displayname'] = $rs->user_displayname;
$this->user_info['user_email'] = $rs->user_email;
$this->user_info['user_url'] = $rs->user_url;
$this->user_info['user_default_blog'] = $rs->user_default_blog;
$this->user_info['user_lang'] = $rs->user_lang;
$this->user_info['user_tz'] = $rs->user_tz;
$this->user_info['user_post_status'] = $rs->user_post_status;
$this->user_info['user_creadt'] = $rs->user_creadt;
$this->user_info['user_upddt'] = $rs->user_upddt;
$this->user_info['user_cn'] = dcUtils::getUserCN($rs->user_id, $rs->user_name,
$rs->user_firstname, $rs->user_displayname);
$this->user_options = array_merge($this->core->userDefaults(),$rs->options());
# Get permissions on blogs
if ($this->user_admin)
{
$strReq = 'SELECT blog_id, blog_name, blog_url '.
'FROM '.$this->blog_table.' ';
$rs = $this->con->select($strReq);
if ($rs->isEmpty()) {
return false;
}
while ($rs->fetch()) {
$this->blogs[$rs->blog_id]['permissions'] = array('admin' => true);
$this->blogs[$rs->blog_id]['name'] = $rs->blog_name;
$this->blogs[$rs->blog_id]['url'] = $rs->blog_url;
}
}
else
{
$strReq = 'SELECT B.blog_id, blog_name, blog_url, permissions '.
'FROM '.$this->con->escapeSystem($this->perm_table).' P, '.
$this->blog_table.' B '.
'WHERE B.blog_id = P.blog_id '.
'AND B.blog_status IN (1,0) '.
"AND user_id = '".$this->con->escape($this->user_id)."' ";
$rs = $this->con->select($strReq);
if ($rs->isEmpty()) {
return false;
}
while ($rs->fetch()) {
$this->blogs[$rs->blog_id]['permissions'] = $this->parsePermissions($rs->permissions);
$this->blogs[$rs->blog_id]['name'] = $rs->blog_name;
$this->blogs[$rs->blog_id]['url'] = $rs->blog_url;
}
}
return true;
}
/**
This method only check current user password.
@param pwd <b>string</b> User password
@return <b>boolean</b>
*/
public function checkPassword($pwd)
{
if (!empty($this->user_info['user_pwd'])) {
return $pwd == $this->user_info['user_pwd'];
}
return false;
}
/**
Checks if user is super admin
@return <b>boolean</b>
*/
public function isSuperAdmin()
{
return $this->user_admin;
}
/**
Checks if user has permissions given in <var>$permissions</var> for blog
<var>$blog_id</var>. <var>$permissions</var> is a coma separated list of
permissions.
@param permissions <b>string</b> Permissions list
@param blog_id <b>string</b> Blog ID
@return <b>boolean</b>
*/
public function check($permissions,$blog_id)
{
if ($this->user_admin) {
return true;
}
$p = explode(',',$permissions);
if (isset($this->blogs[$blog_id]))
{
if (isset($this->blogs[$blog_id]['permissions']['admin'])) {
return true;
}
foreach ($p as $v)
{
if (isset($this->blogs[$blog_id]['permissions'][$v])) {
return true;
}
}
}
return false;
}
/**
Returns true if user is allowed to change its password.
@return <b>boolean</b>
*/
public function allowPassChange()
{
return $this->allow_pass_change;
}
//@}
/// @name Sudo
//@{
/**
Calls <var>$f</var> function with super admin rights.
@param f <b>callback</b> Callback function
@return <b>mixed</b> Function result
*/
public function sudo($f)
{
if (!is_callable($f)) {
throw new Exception($f.' function doest not exist');
}
$args = func_get_args();
array_shift($args);
if ($this->user_admin) {
$res = call_user_func_array($f,$args);
} else {
$this->user_admin = true;
$res = call_user_func_array($f,$args);
$this->user_admin = false;
}
return $res;
}
//@}
/// @name User information and options
//@{
/**
Returns all user permissions (blogs) as an array which looks like:
- [blog_id]
- [name] => Blog name
- [url] => Blog URL
- [permissions]
- [permission] => true
- ...
@return <b>array</b>
*/
public function getPermissions()
{
return $this->blogs;
}
/**
Returns current user ID
@return <b>string</b>
*/
public function userID()
{
return $this->user_id;
}
/**
Returns information about a user .
@param n <b>string</b> Information name
@return <b>string</b> Information value
*/
public function getInfo($n)
{
if (isset($this->user_info[$n])) {
return $this->user_info[$n];
}
return null;
}
/**
Returns a specific user option
@param n <b>string</b> Option name
@return <b>string</b> Option value
*/
public function getOption($n)
{
if (isset($this->user_options[$n])) {
return $this->user_options[$n];
}
return null;
}
/**
Returns all user options in an associative array.
@return <b>array</b>
*/
public function getOptions()
{
return $this->user_options;
}
//@}
/// @name Permissions
//@{
/**
Returns an array with permissions parsed from the string <var>$level</var>
@param level <b>string</b> Permissions string
@return <b>array</b>
*/
public function parsePermissions($level)
{
$level = preg_replace('/^\|/','',$level);
$level = preg_replace('/\|$/','',$level);
$res = array();
foreach (explode('|',$level) as $v) {
$res[$v] = true;
}
return $res;
}
/**
Returns <var>perm_types</var> property content.
@return <b>array</b>
*/
public function getPermissionsTypes()
{
return $this->perm_types;
}
/**
Adds a new permission type.
@param name <b>string</b> Permission name
@param title <b>string</b> Permission title
*/
public function setPermissionType($name,$title)
{
$this->perm_types[$name] = $title;
}
//@}
/// @name Password recovery
//@{
/**
Add a recover key to a specific user identified by its email and
password.
@param user_id <b>string</b> User ID
@param user_email <b>string</b> User Email
@return <b>string</b> Recover key
*/
public function setRecoverKey($user_id,$user_email)
{
$strReq = 'SELECT user_id '.
'FROM '.$this->user_table.' '.
"WHERE user_id = '".$this->con->escape($user_id)."' ".
"AND user_email = '".$this->con->escape($user_email)."' ";
$rs = $this->con->select($strReq);
if ($rs->isEmpty()) {
throw new Exception(__('That user does not exists in the database.'));
}
$key = md5(uniqid());
$cur = $this->con->openCursor($this->user_table);
$cur->user_recover_key = $key;
$cur->update("WHERE user_id = '".$this->con->escape($user_id)."'");
return $key;
}
/**
Creates a new user password using recovery key. Returns an array:
- user_email
- user_id
- new_pass
@param recover_key <b>string</b> Recovery key
@return <b>array</b>
*/
public function recoverUserPassword($recover_key)
{
$strReq = 'SELECT user_id, user_email '.
'FROM '.$this->user_table.' '.
"WHERE user_recover_key = '".$this->con->escape($recover_key)."' ";
$rs = $this->con->select($strReq);
if ($rs->isEmpty()) {
throw new Exception(__('That key does not exists in the database.'));
}
$new_pass = crypt::createPassword();
$cur = $this->con->openCursor($this->user_table);
$cur->user_pwd = crypt::hmac(DC_MASTER_KEY,$new_pass);
$cur->user_recover_key = null;
$cur->update("WHERE user_recover_key = '".$this->con->escape($recover_key)."'");
return array('user_email' => $rs->user_email, 'user_id' => $rs->user_id, 'new_pass' => $new_pass);
}
//@}
/** @name User management callbacks
This 3 functions only matter if you extend this class and use
DC_AUTH_CLASS constant.
These are called after core user management functions.
Could be useful if you need to add/update/remove stuff in your
LDAP directory or other third party authentication database.
*/
//@{
/**
Called after core->addUser
@see dcCore::addUser
@param cur <b>cursor</b> User cursor
*/
public function afterAddUser(&$cur) {}
/**
Called after core->updUser
@see dcCore::updUser
@param id <b>string</b> User ID
@param cur <b>cursor</b> User cursor
*/
public function afterUpdUser($id,&$cur) {}
/**
Called after core->delUser
@see dcCore::delUser
@param id <b>string</b> User ID
*/
public function afterDelUser($id) {}
//@}
}
?>