<?php
/**
* WBB2 UserDriver for LCC
*
* PHP Version 4, 5
*
* @author <hide@address.com>
* @copyright Copyright (c) 2007, Benedikt Hallinger
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/**
* UserDriver for Woltlab WBB 2.x and WBBLite
*
* This UserDriver enables LCC to use users defined from the
* well known forum software Woltlab Burning Board, lite version.
* Users that are logged in at WBB can use the calendar without the need
* to log in separately; a valid login in the forum is sufficient.
*
* The driver is known to work with WBB 2.3.6 but should work with any WBB 2.x.
* It is known to work with WBBLite 1.0.6 but should work with any WBBLite 1.x.
*
*
* Configuration is as follows:
* <code>
* $config = array(
* 'wbb_root' => './some/path/wbb/', // Where is your forum installed? (absolute or relative to your script that runs LCC)
* 'db_driver' => 'mysql' // Which database WBB connects to (wich file at acp/lib/class_db_*.php to include)
* );
* </code>
* wbb_root is the root dir of WBB in the servers filesystem.
* db_driver is for example 'mysql'. To ebnable LCC->WBB DB access, a file named acp/lib/class_db_*.php
* will be included, the configuration option tells LCC which db-driver to use.
* 'mysql' will be parsed to 'class_db_mysql.php'.
*
* The driver returns levels depending on wbb privilegues; for details when which levels are
* returned, refer to the documentation of the method {@link getLevel()} below.
*
* [INSTALLATION NOTES]
* This driver works only, if LCC has access to the session of WBB. This means, that if you use cookies
* to establish a session for WBB (comon case), you must configure your WBB to set the cookie path to a
* location LCC can access. Usually the cookie path is the installation path of WBB (e.g. /wbb/), so you
* must either install LCC bebeath the WBB installation directory (e.g. wbb/lcc/, not recommendet!) or
* alter the cookie path of the WBB cookies to a common path.
* If LCC is instaled at "somepath/lcc/" and WBB at "somepath/wbb/" then the cookie path should be "somepath/".
* Usually this means to simply set the cookie path to "/" but this may imply a security problem with
* software installed beside wbb and lcc, so please check this.
* You can alter the WBB cookie path in the "Admin Control Panel"->"Configuration".
*
* [NOTE]
* It looks like WBBLite doesn't support something like "group leaders". For this reason this driver, if
* used with WBBLite, assumes every user is leader of every group so adding whole groups can be restricted
* using ACL rules. Look at documentation/configuring_lcc.txt for more information on this.
*/
class LCC_UserDriver_WBB2 extends LCC_UserDriver
{
/**
* Default config of the driver
*
* @var array
*/
var $config = array (
'wbb_root' => '', // Where is your forum installed? (absolute or relative to your script that runs LCC)
'db_driver' => 'mysql' // Which database WBB connects to (wich file at acp/lib/class_db_*.php to include)
);
/**
* Userdata of wbb user, set by configure()
*
* @access private
* @var array|false
*/
var $_wbb_user = false;
/**
* Database object of wbb installation
*
* @access private
* @var array
*/
var $_wbb_dbms = false;
/**
* Important configuration options of running wbb
*
* @access private
* @var array
*/
var $_wbb_conf = array();
/**
* Return the username of the user currently logged in wbb
*
* @return false|string
*/
function &fetchLogin()
{
// Correct login = userid > 0 and username set
if ($this->_wbb_user !== false && is_array($this->_wbb_user)
&& $this->_wbb_user['userid'] > 0 && strlen($this->_wbb_user['username']) > 0) {
return $this->_wbb_user['username'];
} else {
// not logged in
return false;
}
}
/**
* Get the group names a user is member of
*
* [WBBLite]
* It looks like wbblite does only support users to be member of one group.
*
* [WBB2]
* Multiple groups per user are supported
*
* @param string $username Name of the user in question
* @return false|array
*/
function getGroups($username)
{
$groups = false;
$db =& $this->_wbb_dbms;
$p =& mysql_real_escape_string($this->_wbb_conf['tbl_prefix']);
if ($this->isWBB2()) {
$sql = "SELECT ".$p."_groups.title FROM ".$p."_groups, ".$p."_user2groups, ".$p."_users
WHERE ".$p."_users.username='".mysql_real_escape_string($username)."' AND ".$p."_user2groups.userid = ".$p."_users.userid AND
".$p."_groups.groupid = ".$p."_user2groups.groupid";
$groups_raw = $db->query_first($sql,0, 0, MYSQL_NUM);
if (is_array($groups_raw)) {
$groups = array();
foreach ($groups_raw as $data) {
array_push($groups, $data);
}
$groups = array_unique($groups);
}
} else {
if ($username === $this->fetchLogin()) {
$groups = array($this->_wbb_user['title']);
} else {
$sql = "SELECT ".$p."_groups.title FROM ".$p."_users, ".$p."_groups
WHERE ".$p."_users.username = '".mysql_real_escape_string($username)."'
AND ".$p."_users.groupid = ".$p."_groups.groupid";
$groups_raw = $db->query_first($sql,0, 0, MYSQL_NUM);
if (is_array($groups_raw)) {
$groups = array();
foreach ($groups_raw as $data) {
array_push($groups, $data);
}
$groups = array_unique($groups);
}
}
}
return $groups;
}
/**
* Get the group names the user leads
*
* This is similar to getGroups() but returns only the names of the
* groups, the user is a leader of.
*
* [WBBLite]
* It looks like in WBBLite there is no such thing like a "group leader".
* We consider all groups leaded by all users, so adding whole groups
* is still possible and can be controled using ACLs.
*
* [WBB2]
* Group leaders are supported
*
* @param string $username Name of the user in question
* @return false|array
*/
function getGroupsLeaded($username)
{
$groups = false;
if ($this->isWBB2()) {
$db =& $this->_wbb_dbms;
$p =& mysql_real_escape_string($this->_wbb_conf['tbl_prefix']);
$sql = "SELECT ".$p."_groups.title
FROM ".$p."_groups, ".$p."_groupleaders, ".$p."_users
WHERE ".$p."_users.username = '".mysql_real_escape_string($username)."'
AND ".$p."_groupleaders.userid = ".$p."_users.userid
AND ".$p."_groups.groupid = ".$p."_groupleaders.groupid";
$groups_raw = $db->query_first($sql,0, 0, MYSQL_ASSOC);
if (is_array($groups_raw)) {
$groups = array();
foreach ($groups_raw as $data) {
array_push($groups, $data);
}
$groups = array_unique($groups);
}
} else {
$groups = $this->getGroups($username);
}
return $groups;
}
/**
* Get the group members
*
* This method returns an array of usernames the group contains.
*
* @param string $groupname Name of the group in question
* @return false|array
*/
function getGroupMembers($groupname)
{
$users = false;
$db =& $this->_wbb_dbms;
$p =& mysql_real_escape_string($this->_wbb_conf['tbl_prefix']);
if ($this->isWBB2()) {
$sql = "SELECT ".$p."_users.username FROM ".$p."_users, ".$p."_groups, ".$p."_user2groups WHERE
".$p."_users.userid = ".$p."_user2groups.userid AND
".$p."_user2groups.groupid = ".$p."_groups.groupid AND
".$p."_groups.title = '".mysql_real_escape_string($groupname)."'";
} else {
$sql = "SELECT ".$p."_users.username FROM ".$p."_users, ".$p."_groups
WHERE ".$p."_groups.title = '".mysql_real_escape_string($groupname)."' AND ".$p."_groups.groupid = ".$p."_users.groupid";
}
$users_raw = $db->query_first($sql,0, 0, MYSQL_ASSOC);
if (is_array($users_raw)) {
$users = array();
foreach ($users_raw as $data) {
array_push($users, $data);
}
$users = array_unique($users);
}
return $users;
}
/**
* Get the "level" of a user
*
* Levels are as following (complies to 'how_to_write_a_driver.txt'):
* Level == 0: Unauthorized users (anonymous guest)
* Level > 0: Authorized users
* Level >= 50: Moderators and Supermods
* Level == 100: Administrators
*
* @param string $username Name of the user in question
* @return false|int
*/
function getLevel($username)
{
if (1 == $this->_wbb_user['userid']) {
$level = 100; // Admin
} elseif ($this->_wbb_user['issupermod'] || $this->_wbb_user['issupermod']) {
$level = 50; // Mod
} elseif (0 == $this->_wbb_user['userid']) {
$level = 0; // Guest
} else {
$level = 10; // ordinary user
}
return $level;
}
/**
* Custom configuration of driver
*
* LCC calls this method after the driver has been configured.
* It tries to fetch neccessary stuff from wbb and ensures
* that the wbb rootpath is set to a sane location
*/
function configure()
{
if (strlen($this->config['wbb_root']) == 0 || !is_readable($this->config['wbb_root'])) {
die('<b>LCC_UserDriver_WBB2 configuration error:</b> wbb_root path not found or not readable!');
} else {
if (!in_array(substr($this->config['wbb_root'], -1), array('/', '\\'))) $this->config['wbb_root'] .= '/';
$cwd = getcwd();
if (false === $cwd) {
die('<b>LCC_UserDriver_WBB2 configuration error:</b> could not access current work directory!');
}
if (!chdir($this->config['wbb_root'])) {
die('<b>LCC_UserDriver_WBB2 configuration error:</b> unable to change working directory to '.$this->config['wbb_root'].' !');
}
// grab core board config
require './acp/lib/config.inc.php';
$wbb_db_driverfile = './acp/lib/class_db_'.$this->config['db_driver'].'.php';
if (!is_readable($wbb_db_driverfile)) {
die('<b>LCC_UserDriver_WBB2 configuration error:</b> unable to include WBB db driver "'.$wbb_db_driverfile.'" !');
}
require $wbb_db_driverfile;
require './acp/lib/options.inc.php';
if (!preg_match('/\d+/', $n)) {
die('<b>LCC_UserDriver_WBB2 configuration error:</b> Board number not compatible (WBB2 config damaged?)');
}
// init WBB DBMS
$db = new db($sqlhost, $sqluser, $sqlpassword, $sqldb, $phpversion);
if (strtolower(get_class($db)) != 'db') {
die('<b>LCC_UserDriver_WBB2 configuration error:</b> unable to initialize access WBB database (WBB2 config damaged?)');
} else {
$this->_wbb_dbms =& $db;
}
$GLOBALS['db'] =& $db;
$GLOBALS['n'] =& $n;
require './acp/lib/functions.php';
require './acp/lib/session.php';
// switch WC back to old value
if (! chdir($cwd)) {
die('<b>LCC_UserDriver_WBB2 configuration error:</b> unable to change working directory to '.$cwd.' !');
}
// store wbb config items for further reference
$this->_wbb_conf['board_nr'] = $n;
$this->_wbb_conf['tbl_prefix'] = 'bb'.$this->_wbb_conf['board_nr']; // prefix+board number; prefix seems to be hardcoded!?
// store userdata for further reference
$this->_wbb_user = $wbbuserdata;
}
}
/*
* Helper functions
*/
/**
* Are we connecting to a WBBLite or on a WBB2?
*
* @return boolean
*/
function isWBB2()
{
$ret = (file_exists($this->config['wbb_root'].'usergroups.php')) ? true : false;
return $ret;
}
}
?>