diff -c /apps/src/eventum-2.1.1/templates/navigation.tpl.html .//navigation.tpl.html
*** /apps/src/eventum-2.1.1/templates/navigation.tpl.html Sat Nov 10 00:52:36 2007
--- .//navigation.tpl.html Tue Jul 22 15:21:27 2008
***************
*** 8,13 ****
--- 8,16 ----
{$app_setup.tool_caption|default:$application_title} ({t}Logout{/t})
+ {if $current_role > $roles.reporter}
+ {t}Project @ Wiki{/t} |
+ {/if}
{if $current_role > $roles.developer}
{t}Administration{/t} |
{/if}
Only in ./: view_form.tpl.html.bak
=== ./templates/view_form.tpl.html ===
To create links to Dokuwiki from the issue view page, alter the "Issue Overview" code to:
diff -c /apps/src/eventum-2.1.1/templates/view_form.tpl.html .//view_form.tpl.html
*** /apps/src/eventum-2.1.1/templates/view_form.tpl.html Sat Nov 10 00:52:16 2007
--- .//view_form.tpl.html Fri Jul 18 16:53:17 2008
***************
*** 178,184 ****
|
! {t}Issue Overview{/t} (ID: {$issue.iss_id})
|
{if $current_role > $roles.customer}
--- 178,184 ----
|
! {t}Issue Overview{/t} (ID: {$issue.iss_id}) (Issue @ Wiki)
|
{if $current_role > $roles.customer}
***************
*** 402,408 ****
|
{t}Group{/t}:
|
!
{$issue.group.grp_name}
|
--- 402,408 ----
{t}Group{/t}:
|
!
{$issue.group.grp_name}
|
***************
*** 443,448 ****
--- 443,454 ----
{/literal}
+
+
+ [ Issue @ Wiki ]
+
+
+ |
|
===== Changes to Dokuwiki =====
==== ./conf/local.php ====
Add the following setup lines to your local.php file:
/* Eventum Single Sign on */
$conf['useacl'] = 1; // Use Access Control Lists to restrict access?
$conf['authtype'] = 'eventum'; //Auth type
define( EVENTUM_ROOT, '/path/to/apache2/htdocs/eventum/' ); // file path to Eventum, must terminate with /
define( EVENTUM_URL, 'http://myhost/eventum/' ); // url to Eventum, must terminate with /
define( EVENTUM_REL, '/eventum/' ); // relative url to Eventum, must terminate with /
==== ./conf/interwiki.conf ====
Add an appropriate entry to the interwiki list:
issue http://myhost/eventum/view.php?id=
==== ./inc/auth.php ====
At about line 25, add:
global $USERINFO;
At about line 78, I changed the code to allow the Dokuwiki ACL placeholder ''%%@USER@%%'' to represent the user id instead of the user name. This seems to work better with my Eventum authentication which ordinarily uses an email address for logging in rather than a user id. Also the ''$_SERVER'' array sometimes appeared unset - undoubtedly triggered by the Eventum authentication and cookie handling:
if(is_readable(DOKU_CONF.'acl.auth.php')){
$AUTH_ACL = file(DOKU_CONF.'acl.auth.php');
if(isset($_SERVER['REMOTE_USER'])){
$AUTH_ACL = str_replace('@USER@',$_SERVER['REMOTE_USER'],$AUTH_ACL);
} elseif (isset($USERINFO['user'])) {
$AUTH_ACL = str_replace('@USER@',$USERINFO['user'],$AUTH_ACL);
}
}else{
$AUTH_ACL = array();
}
Also, at around line 468 (in the ''auth_nameencode'' function) I changed the regular expressions to permit underscore characters in the ACL. The underscore chars are used in the ''eventum.class.php'' when converting spaces in user names, which is much easier than trying to encode all the Eventum user names with ''%%%5f%%''!
I believe this should be standard in Dokuwiki anyway as regexp's usually permit underscore chars without having to escape them.
if (!isset($cache[$name][$skip_group])) {
if($skip_group && $name{0} =='@'){
$cache[$name][$skip_group] = '@'.preg_replace('/([\x00-\x2f\x3a-\x40\x5b-\x5e\x60\x7b-\x7f])/e',
"'%'.dechex(ord(substr('\\1',-1)))",substr($name,1));
}else{
$cache[$name][$skip_group] = preg_replace('/([\x00-\x2f\x3a-\x40\x5b-\x5e\x60\x7b-\x7f])/e',
"'%'.dechex(ord(substr('\\1',-1)))",$name);
}
}
==== ./inc/auth/eventum.class.php ====
Create this file, it contains most of the code to make Eventum authentication work with Dokuwiki.
Notice in ''getGroups'' the role table is used as we defined earlier in the Eventum DB.
*/
if(!defined('EVENTUM_ROOT')) define('EVENTUM_ROOT', '/path/to/apache2/htdocs/eventum/');
require_once(EVENTUM_ROOT.'init.php');
require_once(DOKU_INC.'inc/auth/mysql.class.php');
class auth_eventum extends auth_mysql {
/**
* Constructor.
*
* Sets additional capabilities and config strings
*/
function auth_eventum(){
global $conf;
$this->cando['logoff'] = true;
$this->cando['external'] = true;
// make sure we use a crypt understood by eventum
$conf['passcrypt'] = 'md5';
// get global vars from PunBB config
$db_host = APP_SQL_DBHOST;
$db_name = APP_SQL_DBNAME;
$db_username = APP_SQL_DBUSER;
$db_password = APP_SQL_DBPASS;
$db_prefix = APP_TABLE_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.usr_password AS pass
FROM ${db_prefix}user AS u
WHERE u.usr_status = 'active'
AND LOWER(REPLACE(u.usr_full_name,' ','_')) = LOWER(REPLACE('%{user}',' ','_'))";
$conf['auth']['mysql']['getUserInfo'] = "SELECT LOWER(REPLACE(usr_full_name,' ','_')) AS user, usr_password AS pass, usr_full_name AS name, usr_email AS mail,
usr_id as id, grp_name as `group`
FROM ${db_prefix}user AS u
LEFT JOIN ${db_prefix}group AS g ON g.grp_id = u.usr_grp_id
WHERE LOWER(REPLACE(u.usr_full_name,' ','_')) = LOWER(REPLACE('%{user}',' ','_'))";
$conf['auth']['mysql']['getUserInfoByEmail'] = "SELECT LOWER(REPLACE(usr_full_name,' ','_')) AS user, usr_password AS pass, usr_full_name AS name, usr_email AS mail,
usr_id as id, grp_name as `group`
FROM ${db_prefix}user AS u
LEFT JOIN ${db_prefix}group AS g ON g.grp_id = u.usr_grp_id
WHERE u.usr_email = '%{mail}'";
$conf['auth']['mysql']['getGroups'] = "SELECT g.grp_name as `group`
FROM ${db_prefix}user AS u, ${db_prefix}group AS g
WHERE u.usr_grp_id = g.grp_id
AND LOWER(REPLACE(u.usr_full_name,' ','_')) = LOWER(REPLACE('%{user}',' ','_'))
UNION
SELECT DISTINCT CONCAT(UPPER(REPLACE(r.role_name,' ','_')),'!',REPLACE(p.prj_title,' ','_')) as `group`
FROM ${db_prefix}user AS u2
LEFT JOIN ${db_prefix}project_user AS pu ON pu.pru_usr_id = u2.usr_id
LEFT JOIN ${db_prefix}role AS r ON r.role_id = pu.pru_role
LEFT JOIN ${db_prefix}project AS p ON p.prj_id = pu.pru_prj_id
WHERE LOWER(REPLACE(u2.usr_full_name,' ','_')) = LOWER(REPLACE('%{user}',' ','_'))";
$conf['auth']['mysql']['getUsers'] = "SELECT DISTINCT LOWER(REPLACE(u.usr_full_name,' ','_')) AS user
FROM ${db_prefix}user AS u
LEFT JOIN ${db_prefix}group AS g ON g.grp_id = u.usr_grp_id
WHERE u.usr_id IS NOT NULL";
$conf['auth']['mysql']['FilterLogin'] = "LOWER(REPLACE(u.usr_full_name,' ','_')) LIKE LOWER(REPLACE('%{user}',' ','_'))";
$conf['auth']['mysql']['FilterName'] = "u.usr_full_name LIKE '%{name}'";
$conf['auth']['mysql']['FilterEmail'] = "u.usr_email LIKE '%{email}'";
$conf['auth']['mysql']['FilterGroup'] = "g.grp_name LIKE '%{group}'";
$conf['auth']['mysql']['SortOrder'] = "ORDER BY u.usr_full_name";
$conf['auth']['mysql']['addUser'] = "INSERT INTO ${db_prefix}user
(usr_full_name, usr_password, usr_email, usr_status, usr_created_date)
VALUES ('%{name}', '%{pass}', '%{email}', 'active', NOW())";
$conf['auth']['mysql']['addGroup'] = "INSERT INTO ${db_prefix}group (grp_name, grp_description) VALUES ('%{group}', CONCAT('%{group}',' group')";
$conf['auth']['mysql']['addUserGroup']= "UPDATE ${db_prefix}user
SET usr_grp_id=%{gid}
WHERE usr_id='%{uid}'";
// $conf['auth']['mysql']['delGroup'] = "DELETE FROM ${db_prefix}group WHERE grp_id='%{gid}'";
$conf['auth']['mysql']['getUserID'] = "SELECT usr_id FROM ${db_prefix}user WHERE LOWER(REPLACE(usr_full_name,' ','_'))=LOWER(REPLACE('%{user}',' ','_'))";
$conf['auth']['mysql']['updateUser'] = "UPDATE ${db_prefix}user SET";
$conf['auth']['mysql']['UpdateLogin'] = "usr_full_name='%{name}'";
$conf['auth']['mysql']['UpdatePass'] = "usr_password='%{pass}'";
$conf['auth']['mysql']['UpdateEmail'] = "usr_email='%{email}'";
// $conf['auth']['mysql']['UpdateName'] = "realname='%{name}'";
$conf['auth']['mysql']['UpdateTarget']= "WHERE usr_id=%{uid}";
$conf['auth']['mysql']['delUserGroup']= "UPDATE ${db_prefix}user SET usr_grp_id=NULL WHERE usr_id=%{uid}";
$conf['auth']['mysql']['getGroupID'] = "SELECT grp_id AS id FROM ${db_prefix}group WHERE grp_name='%{group}'";
$conf['auth']['mysql']['TablesToLock']= array("${db_prefix}user", "${db_prefix}user AS u", "${db_prefix}user AS u2",
"${db_prefix}group", "${db_prefix}group AS g",
"${db_prefix}project", "${db_prefix}project AS p",
"${db_prefix}project_user", "${db_prefix}project_user AS pu",
"${db_prefix}role", "${db_prefix}role AS r");
$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;
$sticky ? $sticky = true : $sticky = false; //sanity check
// Set expiration time to 60 days if "Remember Me" is checked.
$expire = ($sticky) ? time() + 60*60*24*60 : 0;
// someone used the login form
if(!empty($user)){
if($this->checkPass($user,$pass)){
# Must get email so we can set the eventum cookie.
# Use standard sql to get the email.
$eve_data = $this->getUserData($user);
$email = $eve_data['mail'];
if(empty($email)) {
return false;
}
Session::init($eve_data['id']);
// Set eventum cookie
Auth::createLoginCookie(APP_COOKIE, $email, $expire);
Auth::saveLoginAttempt($user, 'success');
// set dokuwiki cookie
$eve_data['pass'] = PMA_blowfish_encrypt($eve_data['pass'],auth_cookiesalt());
$doku_cookie = base64_encode(cleanID($eve_data['user'])."|$sticky|".$eve_data['pass']);
setcookie(DOKU_COOKIE,$doku_cookie,$expire,DOKU_REL);
}
} else {
$cookie = $_COOKIE[APP_COOKIE];
$eve_cookie = unserialize(base64_decode($cookie));
if (isset($_COOKIE[APP_COOKIE])) {
if (Auth::isValidCookie($eve_cookie)) {
$email = $eve_cookie['email'];
$eve_data = $this->getUserDataByEmail($email);
$eve_data['pass'] = PMA_blowfish_encrypt($eve_data['pass'],auth_cookiesalt());
}
}
}
if (!isset($eve_data)) {
// Unset cookie
Auth::removeCookie(APP_COOKIE);
//invalid credentials - log off
msg($lang['badlogin'],-1);
auth_logoff();
return false;
}
// check the session
Session::verify($eve_data['id']);
// okay we're logged in - set the globals
$USERINFO['pass'] = $eve_data['pass'];
$USERINFO['name'] = $eve_data['name'];
$USERINFO['mail'] = $eve_data['mail'];
$USERINFO['grps'] = $eve_data['grps'];
$_SERVER['REMOTE_USER'] = $eve_data['user'];
$_SESSION[DOKU_COOKIE]['auth']['user'] = $eve_data['user'];
$_SESSION[DOKU_COOKIE]['auth']['pass'] = $eve_data['pass'];
$_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid();
$_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
$_SESSION[DOKU_COOKIE]['auth']['time'] = time();
return true;
}
/**
* remove eventum cookie on logout
*/
function logOff(){
Auth::removeCookie(APP_COOKIE);
}
/**
* [public function]
*
* Returns the usr_id based on supplied usr_email
*
* @param $user user's nick to get data for
* @return user info
*
* @author Chris Usher
*/
function getUserDataByEmail($email){
if($this->_openDB()) {
$this->_lockTables("READ");
$info = $this->_getUserDataByEmail($email);
$this->_unlockTables();
$this->_closeDB();
} else
$info = false;
return $info;
}
/**
* Retrieves the user id of a given user email
*
* The database connection must already be established
* for this function to work. Otherwise it will return
* 'false'.
*
* @param $email user whose data is desired
* @return bool false on error
* @return array user info on success
*
* @author Chris Usher
*/
function _getUserDataByEmail($email) {
if($this->dbcon) {
$sql = str_replace('%{mail}',$this->_escape($email),$this->cnf['getUserInfoByEmail']);
$result = $this->_queryDB($sql);
if($result !== false && count($result)) {
$info = $result[0];
$info['grps'] = $this->_getGroups($info['name']);
return $info;
}
}
return false;
}
}
//Setup VIM: ex: et ts=2 enc=utf-8 :
===== Admin settings in Eventum =====
==== Groups ====
We have groups defined in mixed case, e.g: ''ITDevTeam'', ''ITSuppTeam'' and assigned to one or more projects.
==== Users ====
We have users identified by their email address and with a "Full Name" like 'Chris Usher'.
The space in the "Full Name" is converted to an underscore (_) by ''eventum.class.php''.
==== Projects ====
Projects may be identified simply with one or more words, and have been proven to work with mixed case, spaces and underscore characters as part of the project name.
===== Dokuwiki ACL =====
With projects, users and groups correctly identified in Eventum, the following lines should be valid in the dokuwiki ACL (''./conf/acl.auth.php''):
# acl.auth.php
#
# Note: use the following characters to encode the strings:
# Sp = %20
# ! = %21
# All characters other than [0-9a-zA-Z_] should be encoded!
#
# Example:
#* @DEVELOPER%21Adhoc_Tasks 1
#
* @ALL 0
* @ITDevTeam 1
* @ITSuppTeam 1
* @ITProjMan 1
* @ITOps 1
* @ITHelpDesk 1
start @ALL 1
adhoc_tasks:* @VIEWER%21Adhoc_Tasks 1
adhoc_tasks:* @REPORTER%21Adhoc_Tasks 2
adhoc_tasks:* @CUSTOMER%21Adhoc_Tasks 1
adhoc_tasks:* @STANDARD_USER%21Adhoc_Tasks 8
adhoc_tasks:* @DEVELOPER%21Adhoc_Tasks 8
adhoc_tasks:* @MANAGER%21Adhoc_Tasks 8
adhoc_tasks:* @ADMINISTRATOR%21Adhoc_Tasks 8
itdev:* @ITDevTeam 8
itdev:* @ITSuppTeam 4
itdev:* @ITOps 4
itdev:* @ITProjMan 8
minutes:* @ALL 1
minutes:itdev:* @ITDevTeam 8
minutes:itdev:* @ITSuppTeam 8
playground:* @ALL 8
blog:* @ALL 1
blog:* @USER@ 4
blog:@USER@:* @USER@ 8
blog:private:@USER@:* @ALL 0
blog:private:@USER@:* @USER@ 16
user:* @ALL 1
user:@USER@:* @USER@ 8
user:private:@USER@:* @ALL 0
user:private:@USER@:* @USER@ 16
In the above example you can see how a mixture of fine grain ACL control techniques can be used.
By specifying the ''%%@ITDevTeam%%'' group in the ACL, it represents any Eventum user who is a member of the "ITDevTeam" group.
By specifying the ''%%@VIEWER%21Adhoc_Tasks%%'' group in the ACL, it represents any Eventum user who has the role "Viewer" on project "Adhoc Tasks".\\
The ''%%%21%%'' or encoded ''!'' in the above group name is simply a divider between the role and project name that is inserted by the SQL queries defined in ''eventum.class.php''.
Note also that role names are uppercased when specified in the Dokuwiki ACL, this is to make them easier to read: roles are in upper case, project names are in whatever case they were defined in Eventum.
==== ACL editing ====
Try not to edit the ACL using the web interface (Admin option) if using ''%%@USER@%%'' in the ACL, as all occurrences are converted to the name of the user making changes, therefore breaking the ACL and undoing the flexibility of having the macro there in the first place.
===== Namespaces in Dokuwiki =====
For each issue in Eventum, when you click on a link that redirects to Dokuwiki, the Dokuwiki page name will be like ''project_name:issues:42'', where the project under Eventum was something like "Project Name", and the issue was no. "42".
So it is best to set up the namespace structure in Dokuwiki when creating a new Eventum project (this is something I haven't automated yet as we don't have new projects appearing every day).
So pages that it is beneficial to have (using the example above) are:
project_name:home
project_name:issues:_template.txt
The ''home'' page may be any page name, but will have to be set in the Eventum ''navigation.tpl.html'' file too. The link is hard coded :-(
By using a namespace template (''_template.txt'') when setting up a new project, it gives you the option to keep all issue pages looking the same.\\
Here is a copy of ours:
====== Issue @PAGE@ ======
^Issue Link:|[[issue>@PAGE@]]|
^First Added:| //[[@MAIL@|@NAME@]] @DATE@//|
===== Title... =====
===== Credits =====
Inspiration for integrating Dokuwiki and Eventum came from the Dokuwiki/Mantis integration at [[http://www.mantisbt.org/wiki/doku.php/mantisbt:issue:7075:integration_with_dokuwiki|Mantisbt]].
Many thanks to Andi and the folks behind [[http://www.dokuwiki.org|Dokuwiki]] for creating such a neat and flexible Wiki core.
~~DISCUSSION~~ |