summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/dokuwiki.php1
-rw-r--r--inc/actions.php15
-rw-r--r--inc/auth.php163
-rw-r--r--inc/auth/basic.class.php159
-rw-r--r--inc/auth/plain.class.php317
-rw-r--r--inc/html.php110
-rw-r--r--inc/io.php16
-rw-r--r--inc/lang/en/lang.php17
-rw-r--r--inc/template.php41
-rw-r--r--lib/tpl/default/main.php1
10 files changed, 796 insertions, 44 deletions
diff --git a/conf/dokuwiki.php b/conf/dokuwiki.php
index e9afdb2be..87639ddd8 100644
--- a/conf/dokuwiki.php
+++ b/conf/dokuwiki.php
@@ -57,6 +57,7 @@ $conf['authtype'] = 'plain'; //which authentication backend should b
$conf['passcrypt'] = 'smd5'; //Used crypt method (smd5,md5,sha1,ssha,crypt,mysql,my411)
$conf['defaultgroup']= 'user'; //Default groups new Users are added to
$conf['superuser'] = '!!not set!!'; //The admin can be user or @group
+$conf['profileconfirm'] = '1'; //Require current password to confirm changes to user profile
/* Advanced Options */
$conf['userewrite'] = 0; //this makes nice URLs: 0: off 1: .htaccess 2: internal
diff --git a/inc/actions.php b/inc/actions.php
index 636858106..2b5fa7ace 100644
--- a/inc/actions.php
+++ b/inc/actions.php
@@ -46,7 +46,15 @@ function act_dispatch(){
if($ACT == 'register' && register()){
$ACT = 'login';
}
-
+
+ if ($ACT == 'resendpwd' && act_resendpwd()) {
+ $ACT = 'login';
+ }
+
+ //update user profile
+ if (($ACT == 'profile') && updateprofile()) {
+ }
+
//save
if($ACT == 'save')
$ACT = act_save($ACT);
@@ -118,7 +126,7 @@ function act_clean($act){
if(array_search($act,array('login','logout','register','save','edit',
'preview','search','show','check','index','revisions',
'diff','recent','backlink','admin','subscribe',
- 'unsubscribe',)) === false
+ 'unsubscribe','profile','resendpwd',)) === false
&& substr($act,0,7) != 'export_' ) {
msg('Unknown command: '.htmlspecialchars($act),-1);
return 'show';
@@ -147,7 +155,7 @@ function act_permcheck($act){
}else{
$permneed = AUTH_CREATE;
}
- }elseif(in_array($act,array('login','search','recent'))){
+ }elseif(in_array($act,array('login','search','recent','profile'))){
$permneed = AUTH_NONE;
}elseif($act == 'register'){
if ($conf['openregister']){
@@ -325,5 +333,4 @@ function act_subscription($act){
return 'show';
}
-
//Setup VIM: ex: et ts=2 enc=utf-8 :
diff --git a/inc/auth.php b/inc/auth.php
index 463d947a2..4db852d5c 100644
--- a/inc/auth.php
+++ b/inc/auth.php
@@ -14,8 +14,61 @@
require_once(DOKU_INC.'inc/io.php');
require_once(DOKU_INC.'inc/blowfish.php');
require_once(DOKU_INC.'inc/mail.php');
- // load the the auth functions
- require_once(DOKU_INC.'inc/auth/'.$conf['authtype'].'.php');
+
+ // load the the backend auth functions and instantiate the auth object
+ if (@file_exists(DOKU_INC.'inc/auth/'.$conf['authtype'].'.class.php')) {
+ require_once(DOKU_INC.'inc/auth/basic.class.php');
+ require_once(DOKU_INC.'inc/auth/'.$conf['authtype'].'.class.php');
+
+ $auth_class = "auth_".$conf['authtype'];
+ if (!class_exists($auth_class)) $auth_class = "auth_basic";
+ $auth = new $auth_class();
+
+ // interface between current dokuwiki/old auth system and new style auth object
+ function auth_canDo($fn) {
+ global $auth;
+ return method_exists($auth, $fn);
+ }
+
+ // mandatory functions - these should exist
+ function auth_checkPass($user,$pass) {
+ global $auth;
+ return method_exists($auth,'checkPass') ? $auth->checkPass($user, $pass) : false;
+ }
+
+ function auth_getUserData($user) {
+ global $auth;
+ return method_exists($auth, 'getUserData') ? $auth->getUserData($user) : false;
+ }
+
+ // optional functions, behave gracefully if these don't exist;
+ // potential calling code should query whether these exist in advance
+ function auth_createUser($user,$pass,$name,$mail) {
+ global $auth;
+ return method_exists($auth, 'createUser') ? $auth->createUser($user,$pass,$name,$mail) : null;
+ }
+
+ function auth_modifyUser($user, $changes) {
+ global $auth;
+ return method_exists($auth, 'modifyUser') ? $auth->modifyUser($user,$changes) : false;
+ }
+
+ function auth_deleteUsers($users) {
+ global $auth;
+ return method_exists($auth, 'deleteUsers') ? $auth->deleteUsers($users) : 0;
+ }
+
+ // other functions, will only be accessed by new code
+ //- these must query auth_canDo() or test method existence themselves.
+
+ } else {
+ // old style auth functions
+ require_once(DOKU_INC.'inc/auth/'.$conf['authtype'].'.php');
+ $auth = null;
+
+ // new function, allows other parts of dokuwiki to know what they can and can't do
+ function auth_canDo($fn) { return function_exists("auth_$fn"); }
+ }
if (!defined('DOKU_COOKIE')) define('DOKU_COOKIE', 'DW'.md5($conf['title']));
@@ -78,7 +131,7 @@ function auth_login($user,$pass,$sticky=false){
// make logininfo globally available
$_SERVER['REMOTE_USER'] = $user;
$USERINFO = auth_getUserData($user); //FIXME move all references to session
-
+
// set cookie
$pass = PMA_blowfish_encrypt($pass,auth_cookiesalt());
$cookie = base64_encode("$user|$sticky|$pass");
@@ -178,6 +231,7 @@ function auth_cookiesalt(){
function auth_logoff(){
global $conf;
global $USERINFO;
+ global $INFO, $ID;
if(isset($_SESSION[$conf['title']]['auth']['user']))
unset($_SESSION[$conf['title']]['auth']['user']);
@@ -438,6 +492,109 @@ function register(){
}
/**
+ * Update user profile
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+function updateprofile() {
+ global $conf;
+ global $INFO;
+ global $lang;
+
+ if(!$_POST['save']) return false;
+
+ // should not be able to get here without modifyUser being possible...
+ if(!auth_canDo('modifyUser')) {
+ msg($lang['profna'],-1);
+ return false;
+ }
+
+ if ($_POST['newpass'] != $_POST['passchk']) {
+ msg($lang['regbadpass'], -1); // complain about misspelled passwords
+ return false;
+ }
+
+ //clean fullname and email
+ $_POST['fullname'] = trim(str_replace(':','',$_POST['fullname']));
+ $_POST['email'] = trim(str_replace(':','',$_POST['email']));
+
+ if (empty($_POST['fullname']) || empty($_POST['email'])) {
+ msg($lang['profnoempty'],-1);
+ return false;
+ }
+
+ if (!mail_isvalid($_POST['email'])){
+ msg($lang['regbadmail'],-1);
+ return false;
+ }
+
+ if ($_POST['fullname'] != $INFO['userinfo']['name']) $changes['name'] = $_POST['fullname'];
+ if ($_POST['email'] != $INFO['userinfo']['mail']) $changes['mail'] = $_POST['email'];
+ if (!empty($_POST['newpass'])) $changes['pass'] = $_POST['newpass'];
+
+ if (!count($changes)) {
+ msg($lang['profnochange'], -1);
+ return false;
+ }
+
+ if ($conf['profileconfirm']) {
+ if (!auth_verifyPassword($_POST['oldpass'],$INFO['userinfo']['pass'])) {
+ msg($lang['badlogin'],-1);
+ return false;
+ }
+ }
+
+ return auth_modifyUser($_SERVER['REMOTE_USER'], $changes);
+}
+
+/**
+ * Send a new password
+ *
+ * @author Benoit Chesneau <benoit@bchesneau.info>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @return bool true on success, false on any error
+*/
+function act_resendpwd(){
+ global $lang;
+ global $conf;
+
+ if(!$_POST['save']) return false;
+
+ // should not be able to get here without modifyUser being possible...
+ if(!auth_canDo('modifyUser')) {
+ msg($lang['resendna'],-1);
+ return false;
+ }
+
+ if (empty($_POST['login'])) {
+ msg($lang['resendpwdmissing'], -1);
+ return false;
+ } else {
+ $user = $_POST['login'];
+ }
+
+ $userinfo = auth_getUserData($user);
+ if(!$userinfo['mail']) {
+ msg($lang['resendpwdnouser'], -1);
+ return false;
+ }
+
+ $pass = auth_pwgen();
+ if (!auth_modifyUser($user,array('pass' => $pass))) {
+ msg('error modifying user data',-1);
+ return false;
+ }
+
+ if (auth_sendPassword($user,$pass)) {
+ msg($lang['resendpwdsuccess'],1);
+ } else {
+ msg($lang['regmailfail'],-1);
+ }
+ return true;
+}
+
+/**
* Uses a regular expresion to check if a given mail address is valid
*
* May not be completly RFC conform!
diff --git a/inc/auth/basic.class.php b/inc/auth/basic.class.php
new file mode 100644
index 000000000..cf19e2c79
--- /dev/null
+++ b/inc/auth/basic.class.php
@@ -0,0 +1,159 @@
+<?php
+/**
+ * auth/basic.class.php
+ *
+ * foundation authorisation class
+ * all auth classes should inherit from this class
+ *
+ * @author Chris Smith <chris@jalakaic.co.uk>
+ */
+
+class auth_basic {
+
+ /**
+ * Check user+password [ MUST BE OVERRIDDEN ]
+ *
+ * Checks if the given user exists and the given
+ * plaintext password is correct
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @return bool
+ */
+ function checkPass($user,$pass){
+
+ msg("no valid authorisation system in use", -1);
+ return false;
+ }
+
+ /**
+ * Return user info [ MUST BE OVERRIDDEN ]
+ *
+ * Returns info about the given user needs to contain
+ * at least these fields:
+ *
+ * name string full name of the user
+ * mail string email addres of the user
+ * grps array list of groups the user is in
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @return array containing user data or false
+ */
+ function getUserData($user) {
+
+ msg("no valid authorisation system in use", -1);
+ return false;
+ }
+
+ /**
+ * Create a new User [implement only where required/possible]
+ *
+ * Returns false if the user already exists, null when an error
+ * occured and the cleartext password of the new user if
+ * everything went well.
+ *
+ * The new user HAS TO be added to the default group by this
+ * function!
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+# function createUser($user,$pass,$name,$mail,$grps=null){
+#
+# msg("authorisation method does not allow creation of new users", -1);
+# return null;
+# }
+
+ /**
+ * Modify user data [implement only where required/possible]
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param $user nick of the user to be changed
+ * @param $changes array of field/value pairs to be changed (password will be clear text)
+ * @return bool
+ */
+# function modifyUser($user, $changes) {
+# msg("authorisation method does not allow modifying of user data", -1);
+# return false;
+# }
+
+ /**
+ * Delete one or more users [implement only where required/possible]
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param array $users
+ * @return int number of users deleted
+ */
+# function deleteUsers($users) {
+# msg("authorisation method does not allow deleting of users", -1);
+# return false;
+# }
+
+ /**
+ * Return a count of the number of user which meet $filter criteria
+ * [should be implemented whenever retrieveUsers is implemented]
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+# function getUserCount($filter=array()) {
+#
+# msg("authorisation method does not provide user counts", -1);
+# return 0;
+# }
+
+ /**
+ * Bulk retrieval of user data [implement only where required/possible]
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param start index of first user to be returned
+ * @param limit max number of users to be returned
+ * @param filter array of field/pattern pairs, null for no filter
+ * @return array of userinfo (refer getUserData for internal userinfo details)
+ */
+# function retrieveUsers($start=0,$limit=-1,$filter=null) {
+# msg("authorisation method does not support mass retrieval of user data", -1);
+# return array();
+# }
+
+ /**
+ * Define a group [implement only where required/possible]
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @return bool
+ */
+# function addGroup($group) {
+# msg("authorisation method does not support independent group creation", -1);
+# return false;
+# }
+
+ /**
+ * Retrieve groups [implement only where required/possible]
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @return array
+ */
+# function retrieveGroups($start=0,$limit=0) {
+# msg("authorisation method does not support group list retrieval", -1);
+# return array();
+# }
+
+ /**
+ * Give user membership of a group [implement only where required/possible]
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @return bool
+ */
+# function joinGroup($user, $group) {
+# msg("authorisation method does not support alteration of group memberships", -1);
+# return false;
+# }
+
+ /**
+ * Remove user from a group [implement only where required/possible]
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @return bool
+ */
+# function leaveGroup($user, $group) {
+# msg("authorisation method does not support alteration of group memberships", -1);
+# return false;
+# }
+} \ No newline at end of file
diff --git a/inc/auth/plain.class.php b/inc/auth/plain.class.php
new file mode 100644
index 000000000..d492463e5
--- /dev/null
+++ b/inc/auth/plain.class.php
@@ -0,0 +1,317 @@
+<?php
+/**
+ * Plaintext authentication backend
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+
+define('DOKU_AUTH', dirname(__FILE__));
+require_once(DOKU_AUTH.'/basic.class.php');
+
+define('AUTH_USERFILE',DOKU_CONF.'users.auth.php');
+
+// we only accept page ids for auth_plain
+if(isset($_REQUEST['u']))
+ $_REQUEST['u'] = cleanID($_REQUEST['u']);
+
+class auth_plain extends auth_basic {
+
+ var $users = null;
+ var $_pattern = array();
+
+ /**
+ * Check user+password [required auth function]
+ *
+ * Checks if the given user exists and the given
+ * plaintext password is correct
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @return bool
+ */
+ function checkPass($user,$pass){
+
+ $userinfo = $this->getUserData($user);
+ if ($userinfo === false) return false;
+
+ return auth_verifyPassword($pass,$this->users[$user]['pass']);
+ }
+
+ /**
+ * Return user info [required auth function]
+ *
+ * Returns info about the given user needs to contain
+ * at least these fields:
+ *
+ * name string full name of the user
+ * mail string email addres of the user
+ * grps array list of groups the user is in
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function getUserData($user){
+
+ if($this->users === null) $this->_loadUserData();
+ return isset($this->users[$user]) ? $this->users[$user] : false;
+ }
+
+ /**
+ * Create a new User [implement only where required/possible]
+ *
+ * Returns false if the user already exists, null when an error
+ * occured and the cleartext password of the new user if
+ * everything went well.
+ *
+ * The new user will be added to the default group by this
+ * function if grps are not specified (default behaviour).
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+ function createUser($user,$pwd,$name,$mail,$grps=null){
+ global $conf;
+
+ // user mustn't already exist
+ if ($this->getUserData($user) !== false) return false;
+
+ $pass = auth_cryptPassword($pwd);
+
+ // set default group if no groups specified
+ if (!is_array($grps)) $grps = array($conf['defaultgroup']);
+
+ // prepare user line
+ $groups = join(',',$grps);
+ $userline = join(':',array($user,$pass,$name,$mail,$groups))."\n";
+
+ if (io_saveFile(AUTH_USERFILE,$userline,true)) {
+ $this->users[$user] = compact('pass','name','mail','grps');
+ return $pwd;
+ }
+
+ msg('The '.AUTH_USERFILE.' file is not writable. Please inform the Wiki-Admin',-1);
+ return null;
+ }
+
+ /**
+ * Modify user data [implement only where required/possible]
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param $user nick of the user to be changed
+ * @param $changes array of field/value pairs to be changed (password will be clear text)
+ * @return bool
+ */
+ function modifyUser($user, $changes) {
+ global $conf;
+ global $ACT;
+ global $INFO;
+
+ // sanity checks, user must already exist and there must be something to change
+ if (($userinfo = $this->getUserData($user)) === false) return false;
+ if (!is_array($changes) || !count($changes)) return true;
+
+ // update userinfo with new data, remembering to encrypt any password
+ foreach ($changes as $field => $value) {
+ if ($field == 'pass') $value = auth_cryptPassword($value);
+ $userinfo[$field] = $value;
+ }
+
+ $groups = join(',',$userinfo['grps']);
+ $userline = join(':',array($user, $userinfo['pass'], $userinfo['name'], $userinfo['mail'], $groups))."\n";
+
+ if (!$this->deleteUsers(array($user))) {
+ msg('Unable to modify user data. Please inform the Wiki-Admin',-1);
+ return false;
+ }
+
+ if (!io_saveFile(AUTH_USERFILE,$userline,true)) {
+ msg('There was an error modifying your user data. You should register again.',-1);
+ // FIXME, user has been deleted but not recreated, should force a logout and redirect to login page
+ $ACT == 'register';
+ return false;
+ }
+
+ $this->users[$user] = $userinfo;
+ return true;
+ }
+
+ /**
+ * Remove one or more users from the list of registered users
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @param array $users array of users to be deleted
+ * @return int the number of users deleted
+ */
+ function deleteUsers($users) {
+
+ if (!is_array($users) || empty($users)) return 0;
+
+ if ($this->users === null) $this->_loadUserData();
+
+ $deleted = array();
+ foreach ($users as $user) {
+ if (isset($this->users[$user])) $deleted[] = preg_quote($user,'/');
+ }
+
+ if (empty($deleted)) return 0;
+
+ $pattern = '/^('.join('|',$deleted).'):/';
+
+ if (io_deleteFromFile(AUTH_USERFILE,$pattern,true)) {
+ foreach ($deleted as $user) unset($this->users[$user]);
+ return count($deleted);
+ }
+
+ // problem deleting, reload the user list and count the difference
+ $count = count($this->users());
+ $this->_loadUserData();
+ $count -= $count($this->users());
+ return $count;
+ }
+
+ /**
+ * Return a count of the number of user which meet $filter criteria
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+ function getUserCount($filter=array()) {
+
+ if($this->users === null) $this->_loadUserData();
+
+ if (!count($filter)) return count($this->users);
+
+ $count = 0;
+ $this->_constructPattern($filter);
+
+ foreach ($this->users as $user => $info) {
+ $count += $this->_filter($user, $info);
+ }
+
+ return $count;
+ }
+
+ /**
+ * Bulk retrieval of user data [implement only where required/possible]
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param start index of first user to be returned
+ * @param limit max number of users to be returned
+ * @param filter array of field/pattern pairs
+ * @return array of userinfo (refer getUserData for internal userinfo details)
+ */
+ function retrieveUsers($start=0,$limit=0,$filter=array()) {
+
+ if ($this->users === null) $this->_loadUserData();
+
+ ksort($this->users);
+
+ $i = 0;
+ $count = 0;
+ $out = array();
+ $this->_constructPattern($filter);
+
+ foreach ($this->users as $user => $info) {
+ if ($this->_filter($user, $info)) {
+ if ($i >= $start) {
+ $out[$user] = $info;
+ $count++;
+ if (($limit > 0) && ($count >= $limit)) break;
+ }
+ $i++;
+ }
+ }
+
+ return $out;
+ }
+
+ /**
+ * Give user membership of a group [implement only where required/possible]
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @return bool
+ */
+ function joinGroup($user, $group) {
+
+ // sanity checks, user must exist, and not currently a group member
+ if (($userinfo = $this->getUserData($user)) === false) return false;
+ if (in_array($group, $userinfo['grps'])) return true;
+
+ $userinfo['grps'][] = $group;
+
+ return $this->modifyUser($user, array('grps' => $userinfo['grps']));
+ }
+
+ /**
+ * Remove user from a group [implement only where required/possible]
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @return bool
+ */
+ function leaveGroup($user, $group) {
+
+ // sanity checks, user must exist, and currently be a group member
+ if (($userinfo = $this->getUserData($user)) === false) return false;
+ if (($i = array_search($group, $userinfo['grps'])) === false) return true;
+
+ array_splice($userinfo['grps'],$i,1);
+
+ return $this->modifyUser($user, array('grps' => $userinfo['grps']));
+ }
+
+ /**
+ * Load all user data
+ *
+ * loads the user file into a datastructure
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _loadUserData(){
+ $this->users = array();
+
+ if(!@file_exists(AUTH_USERFILE)) return;
+
+ $lines = file(AUTH_USERFILE);
+ foreach($lines as $line){
+ $line = preg_replace('/#.*$/','',$line); //ignore comments
+ $line = trim($line);
+ if(empty($line)) continue;
+
+ $row = split(":",$line,5);
+ $groups = split(",",$row[4]);
+
+ $this->users[$row[0]]['pass'] = $row[1];
+ $this->users[$row[0]]['name'] = urldecode($row[2]);
+ $this->users[$row[0]]['mail'] = $row[3];
+ $this->users[$row[0]]['grps'] = $groups;
+ }
+ }
+
+ /**
+ * return 1 if $user + $info match $filter criteria, 0 otherwise
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+ function _filter($user, $info) {
+ // FIXME
+ foreach ($this->_pattern as $item => $pattern) {
+ if ($item == 'user') {
+ if (!preg_match($pattern, $user)) return 0;
+ } else if ($item == 'grps') {
+ if (!count(preg_grep($pattern, $info['grps']))) return 0;
+ } else {
+ if (!preg_match($pattern, $info[$item])) return 0;
+ }
+ }
+ return 1;
+ }
+
+ function _constructPattern($filter) {
+ $this->_pattern = array();
+ foreach ($filter as $item => $pattern) {
+// $this->_pattern[$item] = '/'.preg_quote($pattern,"/").'/'; // don't allow regex characters
+ $this->_pattern[$item] = '/'.str_replace('/','\/',$pattern).'/'; // allow regex characters
+ }
+ }
+}
+
+//Setup VIM: ex: et ts=2 enc=utf-8 :
diff --git a/inc/html.php b/inc/html.php
index b559b84bb..50844da88 100644
--- a/inc/html.php
+++ b/inc/html.php
@@ -78,6 +78,13 @@ function html_login(){
print ': <a href="'.wl($ID,'do=register').'" class="wikilink1">'.$lang['register'].'</a>';
print '</p>';
}
+
+ if (auth_canDo('modifyUser')) {
+ print '<p>';
+ print $lang['pwdforget'];
+ print ': <a href="'.wl($ID,'do=resendpwd').'" class="wikilink1">'.$lang['resendpwd'].'</a>';
+ print '</p>';
+ }
?>
</div>
<?php
@@ -830,6 +837,66 @@ function html_register(){
}
/**
+ * Print the update profile form
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_updateprofile(){
+ global $lang;
+ global $conf;
+ global $ID;
+ global $INFO;
+
+ print p_locale_xhtml('updateprofile');
+
+ if (empty($_POST['fullname'])) $_POST['fullname'] = $INFO['userinfo']['name'];
+ if (empty($_POST['email'])) $_POST['email'] = $INFO['userinfo']['mail'];
+?>
+ <div align="center">
+ <form name="register" method="post" action="<?php echo wl($ID)?>" accept-charset="<?php echo $lang['encoding']?>">
+ <input type="hidden" name="do" value="profile" />
+ <input type="hidden" name="save" value="1" />
+ <fieldset style="width: 80%;">
+ <legend><?php echo $lang['profile']?></legend>
+ <label class="block">
+ <?php echo $lang['user']?>
+ <input type="text" name="fullname" disabled="disabled" class="edit" size="50" value="<?php echo formText($_SERVER['REMOTE_USER'])?>" />
+ </label><br />
+ <label class="block">
+ <?php echo $lang['fullname']?>
+ <input type="text" name="fullname" class="edit" size="50" value="<?php echo formText($_POST['fullname'])?>" />
+ </label><br />
+ <label class="block">
+ <?php echo $lang['email']?>
+ <input type="text" name="email" class="edit" size="50" value="<?php echo formText($_POST['email'])?>" />
+ </label><br /><br />
+ <label class="block">
+ <?php echo $lang['newpass']?>
+ <input type="password" name="newpass" class="edit" size="50" />
+ </label><br />
+ <label class="block">
+ <?php echo $lang['passchk']?>
+ <input type="password" name="passchk" class="edit" size="50" />
+ </label><br />
+
+ <?php if ($conf['profileconfirm']) { ?>
+ <br />
+ <label class="block">
+ <?php echo $lang['oldpass']?>
+ <input type="password" name="oldpass" class="edit" size="50" />
+ </label><br />
+ <?php } ?>
+
+ <input type="submit" class="button" value="<?php echo $lang['btn_profile']?>" />
+ <input type="reset" class="button" value="<?php echo $lang['btn_reset']?>" />
+ </fieldset>
+ </form>
+ </div>
+<?php
+}
+
+/**
* This displays the edit form (lots of logic included)
*
* @fixme this is a huge lump of code and should be modularized
@@ -1064,19 +1131,36 @@ function html_admin(){
}
ptln('</ul>');
-
-/*
- ptln('<ul>'); ptln('<ul class="admin">');
-
- // currently ACL only - more to come
- ptln('<li><a href="'.wl($ID,'do=admin&amp;page=acl').'">'.$lang['admin_acl'].'</a></li>');
- if (!$conf['openregister']){
- ptln('<li><a href="'.wl($ID,'do=register').'">'.$lang['admin_register'].'</a></li>');
- }
-
- ptln('</ul>');
-*/
}
+/**
+ * Form to request a new password for an existing account
+ *
+ * @author Benoit Chesneau <benoit@bchesneau.info>
+ */
+function html_resendpwd() {
+ global $lang;
+ global $conf;
+ global $ID;
+
+ print p_locale_xhtml('resendpwd');
+?>
+ <div align="center">
+ <form name="resendpwd" action="<?php echo wl($ID)?>" accept-charset="<?php echo $lang['encoding']?>" method="post">
+ <fieldset>
+ <br />
+ <legend><?php echo $lang['btn_resendpwd']?></legend>
+ <input type="hidden" name="do" value="resendpwd" />
+ <input type="hidden" name="save" value="1" />
+ <label class="block">
+ <span><?php echo $lang['user']?></span>
+ <input type="text" name="login" value="<?php echo formText($_POST['login'])?>" class="edit" /><br /><br />
+ </label><br />
+ <input type="submit" value="<?php echo $lang['btn_resendpwd']?>" class="button" />
+ </fieldset>
+ </form>
+ </div>
+<?php
+}
-//Setup VIM: ex: et ts=2 enc=utf-8 :
+//Setup VIM: ex: et ts=2 enc=utf-8 : \ No newline at end of file
diff --git a/inc/io.php b/inc/io.php
index 1939dc6a0..e1c4d1eb9 100644
--- a/inc/io.php
+++ b/inc/io.php
@@ -92,10 +92,12 @@ function io_saveFile($file,$content,$append=false){
*
* Uses gzip if extension is .gz
*
+ * 2005-10-14 : added regex option -- Christopher Smith <chris@jalakai.co.uk>
+ *
* @author Steven Danz <steven-danz@kc.rr.com>
* @return bool true on success
*/
-function io_deleteFromFile($file,$badline){
+function io_deleteFromFile($file,$badline,$regex=false){
if (!@file_exists($file)) return true;
io_lock($file);
@@ -108,10 +110,14 @@ function io_deleteFromFile($file,$badline){
}
// remove all matching lines
- $pos = array_search($badline,$lines); //return null or false if not found
- while(is_int($pos)){
- unset($lines[$pos]);
- $pos = array_search($badline,$lines);
+ if ($regex) {
+ $lines = preg_grep($badline,$lines,PREG_GREP_INVERT);
+ } else {
+ $pos = array_search($badline,$lines); //return null or false if not found
+ while(is_int($pos)){
+ unset($lines[$pos]);
+ $pos = array_search($badline,$lines);
+ }
}
if(count($lines)){
diff --git a/inc/lang/en/lang.php b/inc/lang/en/lang.php
index c3de831cd..e615b4afd 100644
--- a/inc/lang/en/lang.php
+++ b/inc/lang/en/lang.php
@@ -35,15 +35,21 @@ $lang['btn_backlink'] = "Backlinks";
$lang['btn_backtomedia'] = 'Back to Mediafile Selection';
$lang['btn_subscribe'] = 'Subscribe Changes';
$lang['btn_unsubscribe'] = 'Unsubscribe Changes';
+$lang['btn_profile'] = 'Update Profile';
+$lang['btn_reset'] = 'Reset';
+$lang['btn_resendpwd'] = 'Send password';
$lang['loggedinas'] = 'Logged in as';
$lang['user'] = 'Username';
$lang['pass'] = 'Password';
+$lang['newpass'] = 'New password';
+$lang['oldpass'] = 'Confirm current password';
$lang['passchk'] = 'once again';
$lang['remember'] = 'Remember me';
$lang['fullname'] = 'Full name';
$lang['email'] = 'E-Mail';
$lang['register'] = 'Register';
+$lang['profile'] = 'User Profile';
$lang['badlogin'] = 'Sorry, username or password was wrong.';
$lang['minoredit'] = 'Minor Edit';
@@ -57,6 +63,17 @@ $lang['regbadpass'] = 'The two given passwords are not identically, please try a
$lang['regpwmail'] = 'Your DokuWiki password';
$lang['reghere'] = 'You don\'t have an account yet? Just get one';
+$lang['profna'] = 'This wiki does not support profile modification';
+$lang['profnochange'] = 'No changes, nothing to do.';
+$lang['profnoempty'] = 'An empty name or email address is not allowed.';
+
+$lang['pwdforget'] = 'Forgotten your password? Get it resent';
+$lang['resendna'] = 'This wiki does not support password resending.';
+$lang['resendpwd'] = 'Resend password';
+$lang['resendpwdmissing'] = 'Sorry, you must fill in all fields.';
+$lang['resendpwdnouser'] = 'Sorry, we can\'t find this user in our database.';
+$lang['resendpwdsuccess'] = 'Your new password has been sent by email.';
+
$lang['txt_upload'] = 'Select file to upload';
$lang['txt_filename'] = 'Enter wikiname (optional)';
$lang['txt_overwrt'] = 'Overwrite existing file';
diff --git a/inc/template.php b/inc/template.php
index b851fc584..ba64d4120 100644
--- a/inc/template.php
+++ b/inc/template.php
@@ -112,14 +112,20 @@ function tpl_content(){
case 'register':
html_register();
break;
+ case 'resendpwd':
+ html_resendpwd();
+ break;
case 'denied':
print p_locale_xhtml('denied');
- break;
+ break;
+ case 'profile' :
+ html_updateprofile();
+ break;
case 'admin':
tpl_admin();
break;
default:
- msg("Failed to handle command: ".hsc($ACT),-1);
+ msg("Failed to handle command: ".hsc($ACT),-1);
}
}
@@ -145,19 +151,6 @@ function tpl_admin(){
$plugin->html();
else
html_admin();
-/*
- switch($_REQUEST['page']){
- case 'acl':
- admin_acl_html();
- break;
- case 'plugin':
- require_once(DOKU_INC.'inc/admin_plugin.php');
- admin_plugin_html();
- break;
- default:
- html_admin();
- }
-*/
}
/**
@@ -418,6 +411,11 @@ function tpl_button($type){
case 'backlink':
print html_btn('backlink',$ID,'',array('do' => 'backlink'));
break;
+ case 'profile':
+ if(($_SERVER['REMOTE_USER']) && auth_canDo('modifyUser') && ($ACT!='profile')){
+ print html_btn('profile',$ID,'',array('do' => 'profile'));
+ }
+ break;
default:
print '[unknown button type]';
}
@@ -517,9 +515,14 @@ function tpl_actionlink($type,$pre='',$suf=''){
}
}
break;
- case 'backlink':
- tpl_link(wl($ID,'do=backlink'),$pre.$lang['btn_backlink'].$suf, 'class="action backlink"');
- break;
+ case 'backlink':
+ tpl_link(wl($ID,'do=backlink'),$pre.$lang['btn_backlink'].$suf, 'class="action backlink"');
+ break;
+ case 'profile':
+ if(($_SERVER['REMOTE_USER']) && auth_canDo('modifyUser') && ($ACT!='profile')){
+ tpl_link(wl($ID,'do=profile'),$pre.$lang['btn_profile'].$suf, 'class="action profile"');
+ }
+ break;
default:
print '[unknown link type]';
}
@@ -689,7 +692,7 @@ function tpl_pageinfo(){
* @author Andreas Gohr <andi@splitbrain.org>
*/
function tpl_medianamespaces(){
- global $conf;
+ global $conf;
$data = array();
search($data,$conf['mediadir'],'search_namespaces',array());
diff --git a/lib/tpl/default/main.php b/lib/tpl/default/main.php
index a2ec79a95..afa0b5534 100644
--- a/lib/tpl/default/main.php
+++ b/lib/tpl/default/main.php
@@ -116,6 +116,7 @@
<div class="bar-right" id="bar_bottomright">
<?php tpl_button('subscription')?>
<?php tpl_button('admin')?>
+ <?php tpl_button('profile')?>
<?php tpl_button('login')?>
<?php tpl_button('index')?>
<?php tpl_button('top')?>&nbsp;