====== PunBB Authentication backend ======
This backend provides authentication against a [[http://www.punbb.org|PunBB]] 1.2.x forum installed on the same server. It provides Single-Sign-On for (SSO) the forum and the wiki by reusing PunBB's cookies.
===== Requirements =====
* A recent PunBB 1.2.x forum installation (1.3.x support is in beta)
* The forum needs to be on the same domain as the wiki
* magic_quotes_gpc needs to be **off** ((Either disable in your ''php.ini'' or use ''php_value magic_quotes_gpc off'' in ''.htaccess''))
===== Configuration =====
The backend reuses your PunBB configuration. You just need to enable it and set is the ''PUN_ROOT'' define pointing to the installation dir of your PunBB forum. Just add it to your ''conf/local.protected.php'':
$conf['useacl'] =1;
$conf['authtype']='punbb';
define('PUN_ROOT','/path/to/punbb/');
This path must be an absolute path, like ''/var/www/free.fr/2/8/mysite/punbb/'' for example and must end with a slash **/**.
To have your admin users recognized you need to set your [[config:superuser]] option to the name of the PunBB administrator group. How this group is named, varies with the used language of your forum. In a English setup it is usually ''@Administrators'', while French users might need to use ''@Administrateurs''.
===== Source and Installation =====
Up to DokuWiki 2008-05-05 this backend was included in the DokuWiki install. Never versions no longer come with this backend.
To install the backend, create a ''inc/auth/punbb.class.php'' file and copy'n'paste the following code:
*/
if(!defined('PUN_ROOT')) define('PUN_ROOT', DOKU_INC.'../forum/');
if(get_magic_quotes_gpc()){
nice_die('Sorry the punbb auth backend requires the PHP option
magic_quotes_gpc
to be disabled for proper operation. Either setup your PHP install accordingly or
choose a different auth backend.');
}
require_once PUN_ROOT.'include/common.php';
require_once DOKU_INC.'inc/auth/mysql.class.php';
#dbg($GLOBALS);
#dbg($pun_user);
class auth_punbb extends auth_mysql {
/**
* Constructor.
*
* Sets additional capabilities and config strings
*/
function auth_punbb(){
global $conf;
$this->cando['external'] = true;
$this->cando['logoff'] = true;
// make sure we use a crypt understood by punbb
if(function_exists('sha1')){
$conf['passcrypt'] = 'sha1';
}else{
$conf['passcrypt'] = 'md5';
}
// get global vars from PunBB config
global $db_host;
global $db_name;
global $db_username;
global $db_password;
global $db_prefix;
// now set up the mysql config strings
$conf['auth']['mysql']['server'] = $db_host;
$conf['auth']['mysql']['user'] = $db_username;
$conf['auth']['mysql']['password'] = $db_password;
$conf['auth']['mysql']['database'] = $db_name;
$conf['auth']['mysql']['checkPass'] = "SELECT u.password AS pass
FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
WHERE u.group_id = g.g_id
AND u.username = '%{user}'
AND g.g_title != 'Guest'";
$conf['auth']['mysql']['getUserInfo'] = "SELECT password AS pass, realname AS name, email AS mail,
id, g_title as `group`
FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
WHERE u.group_id = g.g_id
AND u.username = '%{user}'";
$conf['auth']['mysql']['getGroups'] = "SELECT g.g_title as `group`
FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
WHERE u.group_id = g.g_id
AND u.username = '%{user}'";
$conf['auth']['mysql']['getUsers'] = "SELECT DISTINCT u.username AS user
FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
WHERE u.group_id = g.g_id";
$conf['auth']['mysql']['FilterLogin'] = "u.username LIKE '%{user}'";
$conf['auth']['mysql']['FilterName'] = "u.realname LIKE '%{name}'";
$conf['auth']['mysql']['FilterEmail'] = "u.email LIKE '%{email}'";
$conf['auth']['mysql']['FilterGroup'] = "g.g_title LIKE '%{group}'";
$conf['auth']['mysql']['SortOrder'] = "ORDER BY u.username";
$conf['auth']['mysql']['addUser'] = "INSERT INTO ${db_prefix}users
(username, password, email, realname)
VALUES ('%{user}', '%{pass}', '%{email}', '%{name}')";
$conf['auth']['mysql']['addGroup'] = "INSERT INTO ${db_prefix}groups (g_title) VALUES ('%{group}')";
$conf['auth']['mysql']['addUserGroup']= "UPDATE ${db_prefix}users
SET group_id=%{gid}
WHERE id='%{uid}'";
$conf['auth']['mysql']['delGroup'] = "DELETE FROM ${db_prefix}groups WHERE g_id='%{gid}'";
$conf['auth']['mysql']['getUserID'] = "SELECT id FROM ${db_prefix}users WHERE username='%{user}'";
$conf['auth']['mysql']['updateUser'] = "UPDATE ${db_prefix}users SET";
$conf['auth']['mysql']['UpdateLogin'] = "username='%{user}'";
$conf['auth']['mysql']['UpdatePass'] = "password='%{pass}'";
$conf['auth']['mysql']['UpdateEmail'] = "email='%{email}'";
$conf['auth']['mysql']['UpdateName'] = "realname='%{name}'";
$conf['auth']['mysql']['UpdateTarget']= "WHERE id=%{uid}";
$conf['auth']['mysql']['delUserGroup']= "UPDATE ${db_prefix}users SET g_id=4 WHERE id=%{uid}";
$conf['auth']['mysql']['getGroupID'] = "SELECT g_id AS id FROM ${db_prefix}groups WHERE g_title='%{group}'";
$conf['auth']['mysql']['TablesToLock']= array("${db_prefix}users", "${db_prefix}users AS u",
"${db_prefix}groups", "${db_prefix}groups AS g");
$conf['auth']['mysql']['debug'] = 1;
// call mysql constructor
$this->auth_mysql();
}
/**
* Just checks against the $pun_user variable
*/
function trustExternal($user,$pass,$sticky=false){
global $USERINFO;
global $conf;
global $lang;
global $pun_user;
global $pun_config;
$sticky ? $sticky = true : $sticky = false; //sanity check
// someone used the login form
if(!empty($user)){
if($this->checkPass($user,$pass)){
$expire = ($sticky) ? time() + 31536000 : 0;
$uinfo = $this->getUserData($user);
pun_setcookie($uinfo['id'], auth_cryptPassword($pass), $expire);
$pun_user = array();
$pun_user['password'] = auth_cryptPassword($pass);
$pun_user['username'] = $user;
$pun_user['realname'] = $uinfo['name'];
$pun_user['email'] = $uinfo['mail'];
$pun_user['g_title'] = $uinfo['group'];
}else{
//invalid credentials - log off
msg($lang['badlogin'],-1);
auth_logoff();
return false;
}
}
if(isset($pun_user) && !$pun_user['is_guest']){
// okay we're logged in - set the globals
$USERINFO['pass'] = $pun_user['password'];
$USERINFO['name'] = $pun_user['realname'];
$USERINFO['mail'] = $pun_user['email'];
$USERINFO['grps'] = array($pun_user['g_title']);
$_SERVER['REMOTE_USER'] = $pun_user['username'];
$_SESSION[DOKU_COOKIE]['auth']['user'] = $pun_user['username'];
$_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
return true;
}
// to be sure
auth_logoff();
return false;
}
/**
* remove punbb cookie on logout
*/
function logOff(){
global $pun_user;
$pun_user = array();
$pun_user['is_guest'] = 1;
pun_setcookie(1, random_pass(8), time() + 31536000);
}
}
//Setup VIM: ex: et ts=2 enc=utf-8 :
===== Source and Installation - punbb 1.3.x =====
Up to DokuWiki 2008-05-05 this backend was included in the DokuWiki install. Newer versions no longer come with this backend.
To install the backend, create a ''inc/auth/punbb.class.php'' file and copy'n'paste the following code:
*/
// needed if you use URL rewrite in you Wiki and Punbb
// i.e.: example.com/wiki/article and example.com/punbb/topic/1515/subject/
define('FORUM_IGNORE_REQUEST_URI', 1);
// do not confirm the action in punbb, usefull for ajax in dokuwiki
define('FORUM_SKIP_CSRF_CONFIRM', 1);
if(!defined('FORUM_ROOT')) define('FORUM_ROOT', DOKU_INC.'../forum/');
if(get_magic_quotes_gpc()){
nice_die('Sorry the punbb auth backend requires the PHP option
magic_quotes_gpc
to be disabled for proper operation. Either setup your PHP install accordingly or
choose a different auth backend.');
}
require_once FORUM_ROOT.'include/common.php';
require_once DOKU_INC.'inc/auth/mysql.class.php';
#dbg($GLOBALS);
#dbg($forum_user);
class auth_punbb extends auth_mysql {
/**
* Constructor.
*
* Sets additional capabilities and config strings
*/
function auth_punbb(){
global $conf;
$this->cando['external'] = true;
$this->cando['logoff'] = true;
// make sure we use a crypt understood by punbb
if(function_exists('sha1')){
$conf['passcrypt'] = 'sha1';
}else{
$conf['passcrypt'] = 'md5';
}
// get global vars from PunBB config
global $db_host;
global $db_name;
global $db_username;
global $db_password;
global $db_prefix;
// now set up the mysql config strings
$conf['auth']['mysql']['server'] = $db_host;
$conf['auth']['mysql']['user'] = $db_username;
$conf['auth']['mysql']['password'] = $db_password;
$conf['auth']['mysql']['database'] = $db_name;
$conf['auth']['mysql']['checkPass'] = "SELECT u.password AS pass
FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
WHERE u.group_id = g.g_id
AND u.username = '%{user}'
AND g.g_title != 'Guest'";
$conf['auth']['mysql']['getUserInfo'] = "SELECT password AS pass, realname AS name, email AS mail,
id, g_title as `group`
FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
WHERE u.group_id = g.g_id
AND u.username = '%{user}'";
$conf['auth']['mysql']['getGroups'] = "SELECT g.g_title as `group`
FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
WHERE u.group_id = g.g_id
AND u.username = '%{user}'";
$conf['auth']['mysql']['getUsers'] = "SELECT DISTINCT u.username AS user
FROM ${db_prefix}users AS u, ${db_prefix}groups AS g
WHERE u.group_id = g.g_id";
$conf['auth']['mysql']['FilterLogin'] = "u.username LIKE '%{user}'";
$conf['auth']['mysql']['FilterName'] = "u.realname LIKE '%{name}'";
$conf['auth']['mysql']['FilterEmail'] = "u.email LIKE '%{email}'";
$conf['auth']['mysql']['FilterGroup'] = "g.g_title LIKE '%{group}'";
$conf['auth']['mysql']['SortOrder'] = "ORDER BY u.username";
$conf['auth']['mysql']['addUser'] = "INSERT INTO ${db_prefix}users
(username, password, email, realname)
VALUES ('%{user}', '%{pass}', '%{email}', '%{name}')";
$conf['auth']['mysql']['addGroup'] = "INSERT INTO ${db_prefix}groups (g_title) VALUES ('%{group}')";
$conf['auth']['mysql']['addUserGroup']= "UPDATE ${db_prefix}users
SET group_id=%{gid}
WHERE id='%{uid}'";
$conf['auth']['mysql']['delGroup'] = "DELETE FROM ${db_prefix}groups WHERE g_id='%{gid}'";
$conf['auth']['mysql']['getUserID'] = "SELECT id FROM ${db_prefix}users WHERE username='%{user}'";
$conf['auth']['mysql']['updateUser'] = "UPDATE ${db_prefix}users SET";
$conf['auth']['mysql']['UpdateLogin'] = "username='%{user}'";
$conf['auth']['mysql']['UpdatePass'] = "password='%{pass}'";
$conf['auth']['mysql']['UpdateEmail'] = "email='%{email}'";
$conf['auth']['mysql']['UpdateName'] = "realname='%{name}'";
$conf['auth']['mysql']['UpdateTarget']= "WHERE id=%{uid}";
$conf['auth']['mysql']['delUserGroup']= "UPDATE ${db_prefix}users SET g_id=4 WHERE id=%{uid}";
$conf['auth']['mysql']['getGroupID'] = "SELECT g_id AS id FROM ${db_prefix}groups WHERE g_title='%{group}'";
$conf['auth']['mysql']['TablesToLock']= array("${db_prefix}users", "${db_prefix}users AS u",
"${db_prefix}groups", "${db_prefix}groups AS g");
$conf['auth']['mysql']['debug'] = 1;
// call mysql constructor
$this->auth_mysql();
}
/**
* Just checks against the $forum_user variable
*/
function trustExternal($user,$pass,$sticky=false){
global $USERINFO;
global $conf;
global $lang;
global $forum_user;
global $pun_config;
$sticky ? $sticky = true : $sticky = false; //sanity check
// someone used the login form
if(!empty($user)){
if($this->checkPass($user,$pass)){
$expire = ($sticky) ? time() + 31536000 : 0;
$uinfo = $this->getUserData($user);
forum_setcookie($uinfo['id'], auth_cryptPassword($pass), $expire);
$forum_user = array();
$forum_user['password'] = auth_cryptPassword($pass);
$forum_user['username'] = $user;
$forum_user['realname'] = $uinfo['name'];
$forum_user['email'] = $uinfo['mail'];
$forum_user['g_title'] = $uinfo['group'];
}else{
//invalid credentials - log off
msg($lang['badlogin'],-1);
auth_logoff();
return false;
}
}
if(isset($forum_user) && !$forum_user['is_guest']){
// okay we're logged in - set the globals
$USERINFO['pass'] = $pun_user['password'];
$USERINFO['name'] = utf8_encode($forum_user['realname']);
$USERINFO['mail'] = $forum_user['email'];
$USERINFO['grps'] = array($forum_user['g_title']);
$_SERVER['REMOTE_USER'] = utf8_encode($forum_user['username']);
$_SESSION[DOKU_COOKIE]['auth']['user'] = utf8_encode($forum_user['username']);
$_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
return true;
}
// to be sure
auth_logoff();
return false;
}
/**
* remove punbb cookie on logout
*/
function logOff(){
global $forum_user;
$forum_user = array();
$forum_user['is_guest'] = 1;
forum_setcookie(1, random_key(8), time() + 31536000);
}
}
//Setup VIM: ex: et ts=2 enc=utf-8 :
===== Discussion =====
* Some username are not understand by DokuWiki (Pérot became P�rot or Pérot)
DokuWiki uses UTF-8 and PunBB ISO8859-1, so this is just a character encoding problem. In order to get the right usernames, open /dokuwiki/inc/auth/punbb.class.php, find (l136 on v. 2007-06-26b) :
if(isset($pun_user) && !$pun_user['is_guest']){
// okay we're logged in - set the globals
$USERINFO['pass'] = $pun_user['password'];
$USERINFO['name'] = $pun_user['realname'];
$USERINFO['mail'] = $pun_user['email'];
$USERINFO['grps'] = array($pun_user['g_title']);
$_SERVER['REMOTE_USER'] = $pun_user['username'];
$_SESSION[DOKU_COOKIE]['auth']['user'] = $pun_user['username'];
$_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
return true;
}
And replace by :
if(isset($pun_user) && !$pun_user['is_guest']){
// okay we're logged in - set the globals
$USERINFO['pass'] = $pun_user['password'];
$USERINFO['name'] = utf8_encode($pun_user['realname']);
$USERINFO['mail'] = $pun_user['email'];
$USERINFO['grps'] = array($pun_user['g_title']);
$_SERVER['REMOTE_USER'] = utf8_encode($pun_user['username']);
$_SESSION[DOKU_COOKIE]['auth']['user'] = utf8_encode($pun_user['username']);
$_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
return true;
}
//[[http://www.punbb.fr|Maximilien Thiel]] 2007-11-13 - 11:00 UTC +01:00//
* As punbb 1.3 will support utf8, a better patch is :
// okay we're logged in - set the globals
$USERINFO['pass'] = $pun_user['password'];
$USERINFO['name'] = preg_match('/^1\.2/',$pun_config['o_cur_version']) ? utf8_encode($pun_user['realname']) : $pun_user['realname'];
$USERINFO['mail'] = $pun_user['email'];
$USERINFO['grps'] = array($pun_user['g_title']);
(only the $USERINFO['name'] line is changed)\\ [[http://www.zeitoun.net|Stéphane Gully]]
* I think there is a problem when you use DokuWiki's ACL : a regular member with appropriate rights under PunBB can not edit a page though ACL seems properly configured (changes forbidden in : but allowed in :help: ). The problem may come from the fact DokuWiki has a "user" group while PunBB has a "members" and this is not *always* correctly seen.
* yann: edit the file conf/acl.auth.php, add there the group members (duplicate the line with "user", and replace "user" by "members".
* Better yet, use the group Members as is defined in the table groups in the PunBB MySQL database.