diff options
author | chris <chris@teacherscpd.co.uk> | 2005-10-20 20:14:34 +0200 |
---|---|---|
committer | chris <chris@teacherscpd.co.uk> | 2005-10-20 20:14:34 +0200 |
commit | 8b06d178223afa83719d5719942e315c41adc596 (patch) | |
tree | 3a2a7e18d883a8aff5ba2db763e6d1eed6793578 | |
parent | 453493f24ca09d6d213a95e42de8d91bb5577458 (diff) | |
download | rpg-8b06d178223afa83719d5719942e315c41adc596.tar.gz rpg-8b06d178223afa83719d5719942e315c41adc596.tar.bz2 |
auth update, incl. auth object, plain.class.php; resend password & update profile actions
darcs-hash:20051020181434-50fdc-44222aa2074bb0e39a1c240c516259579b380740.gz
-rw-r--r-- | conf/dokuwiki.php | 1 | ||||
-rw-r--r-- | inc/actions.php | 15 | ||||
-rw-r--r-- | inc/auth.php | 163 | ||||
-rw-r--r-- | inc/auth/basic.class.php | 159 | ||||
-rw-r--r-- | inc/auth/plain.class.php | 317 | ||||
-rw-r--r-- | inc/html.php | 110 | ||||
-rw-r--r-- | inc/io.php | 16 | ||||
-rw-r--r-- | inc/lang/en/lang.php | 17 | ||||
-rw-r--r-- | inc/template.php | 41 | ||||
-rw-r--r-- | lib/tpl/default/main.php | 1 |
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&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')?> |