wiclear-2007-07-19/inc/classes/auth.class.php
<?php
# ***** BEGIN LICENSE BLOCK *****
# This file is part of WiClear.
# Copyright (c) 2004-2007 David Jobet. All rights
# reserved.
#
# WiClear 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.
#
# WiClear 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#
# ***** END LICENSE BLOCK *****
/**
* \brief authentification related functions
*/
class auth
{
/**
* \brief return user info from cookie or session
*
* \return array(user_id, MD5 encoded user_password)
*/
function getUserInfoFromCookieOrSession()
{
$user_id = 0;
$user_password = '';
// session has priority over cookie
if (existVarSession('user_id') && existVarSession('user_password'))
{
$user_id = varSession('user_id');
$user_password = varSession('user_password');
}
else
if (existVarCookie('login'))
{
$login_info = &varCookie('login');
$user_id = $login_info['user_id'];
$user_password = $login_info['user_password'];
setVarSession('user_id', $user_id);
setVarSession('user_password', $user_password);
}
return array($user_id, $user_password);
}
/**
* \brief return a user from session variables (user is logged) or anonymous user
*
* \param wiki the wiki controller object
* \return user
*/
function checkRights($wiki)
{
list($user_id, $user_password) = auth::getUserInfoFromCookieOrSession();
if ($user_id == '0' && $user_password == '')
{
return $wiki->anonymousUser();
}
else
{
return $wiki->getUser($user_id, $user_password);
}
}
/**
* \brief check if an ip is in a network/mask
*
* \param ip the ip to check
* \param network the network to compare against
* \param mask the mask to apply on network for comparison
*
* \return true if match
*/
function isIPInNet($ip, $network, $mask)
{
if ($mask == 0)
{
return $ip == $network;
}
$lnet = ip2long($network);
$lip = ip2long($ip);
$binnet = str_pad(decbin($lnet), 32, '0', 'STR_PAD_LEFT');
$firstpart = substr($binnet, 0, $mask);
$binip = str_pad(decbin($lip), 32, '0', 'STR_PAD_LEFT');
$firstip = substr($binip, 0, $mask);
return strcmp($firstpart, $firstip) == 0;
}
/**
* \brief check if an ip is in a list of network/mask
*
* \param ip the ip to check
* \param network_array a list of network/mask
*
* \return true if found
*/
function isIpInNetArray($ip, $network_array)
{
foreach ($network_array as $subnet)
{
list($network, $mask) = split('/', $subnet);
if (auth::isIPInNet($ip, $network, $mask))
{
return true;
}
}
return false;
}
/**
* \brief parse a comma separated list of ips and add it to ips
*
* \param ips the array of ip to complete
* \param str the string to parse
*/
function collectIpsFromString(&$ips, $str)
{
$new_ips = explode(',', $str);
foreach ($new_ips as $ip)
{
if (!in_array($ip, $ips))
{
$ips[] = $ip;
}
}
}
/**
* \brief return a list of filtered IP (private ips are taken out)
*
* \param ips ips to filter
*
* \return filtered ips
*/
function filterOutPrivateIps($ips)
{
$ip_private_list = array(
'127.0.0.1/0',
'10.0.0.0/8',
'172.16.0.0/12',
'192.168.0.0/16'
);
$result = array();
foreach ($ips as $ip)
{
if (!auth::isIpInNetArray($ip, $ip_private_list))
{
// not a private ip : keep this one
$result[] = $ip;
}
}
return $result;
}
/**
* \brief return list of IP from currently connected browser
*
* \param $filter_out_private_ips indicates if we need to filter out private ips
*
* \return IP array
*/
function getIPs($filter_out_private_ips = false)
{
$ips = array();
if (isset($_SERVER['HTTP_CLIENT_IP']))
{
auth::collectIpsFromString($ips, $_SERVER['HTTP_CLIENT_IP']);
}
if (isset($_SERVER['HTTP_X_REAL_IP']))
{
auth::collectIpsFromString($ips, $_SERVER['HTTP_X_REAL_IP']);
}
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
{
auth::collectIpsFromString($ips, $_SERVER['HTTP_X_FORWARDED_FOR']);
}
auth::collectIpsFromString($ips, $_SERVER['REMOTE_ADDR']);
if ($filter_out_private_ips)
{
$ips = auth::filterOutPrivateIps($ips);
}
return $ips;
}
/**
* \brief randomly generates a text
*
* \param $textLen length of text
* \return random text
*/
function generateRandomText($textLen)
{
$text = '';
for ($i = 0; $i < $textLen; ++$i)
{
switch(rand(1, 4))
{
case 1:
// 25% probability to generate a number
$text .= chr(rand(48, 57));
break;
default:
// 75% probability to generate a letter
$text .= chr(rand(97, 122));
break;
}
}
return $text;
}
/**
* \brief is it possible for this user to do an action on this node based on acls and an acl_type
*
* \param default_global_action the default parameter for the whole wiki
* \param acl_type the acl_type to check
* \param user the user to check
* \param node the node to check ACL
* \return true if the user can edit the node, false otherwise
*/
function aclMatch($default_global_action, $acl_type, $user, $node)
{
// if the user is admin or moderator
if ($user->isAdmin() || $user->isModerator())
{
return true;
}
// if the node is empty or if there are no acls
if (empty($node) || empty($node->groups[$acl_type]))
{
if ($user->isAnonymous() && !$default_global_action)
{
// if user is anonymous and this very acl right is denied by global configuration for anonymous
return false;
}
else
{
return true;
}
}
global $wiki;
$anonymousUser = $wiki->anonymousUser();
// else browse groups and try to find one that match the user
$matchAcl = empty($node->groups[$acl_type]);
foreach ($node->groups[$acl_type] as $group)
{
// if group validates current user, or if anonymous is allowed (which means everybody's allowed)
if ($group->validates($user) || $group->validates($anonymousUser))
{
$matchAcl = true;
break;
}
}
return $matchAcl;
}
/**
* \brief is it possible for this user to edit this node
*
* \param user the user to check
* \param node the node to check ACL
* \return true if the user can edit the node, false otherwise
*/
function canEdit($user, $node)
{
return auth::aclMatch(wc_wiki_accept_anonymous_content == 'true', acl_write, $user, $node);
}
/**
* \brief is it possible for this user to read this node
*
* \param user the user to check
* \param node the node to check ACL
* \return true if the user can edit the node, false otherwise
*/
function canRead($user, $node)
{
return auth::aclMatch(true, acl_read, $user, $node);
}
/**
* \brief is it possible for this user to comment
*
* \param user the user to check
* \param node the node to check ACL
* \return true if the user can comment, false otherwise
*/
function canComment($user, $node)
{
return auth::aclMatch(wc_wiki_accept_anonymous_comment == 'true', acl_comment, $user, $node);
}
/**
* \brief look into the table of banned ip and returns true if ip of current user was banned
*/
function banned()
{
global $wiki;
$ips = auth::getIPs();
return $wiki->containsBannedIp($ips);
}
}
?>