/** * Modify user (modified user data has been recieved) */ function _modifyUser() { global $conf; if (!checkSecurityToken()) { return false; } if (!$this->_auth->canDo('UserMod')) { return false; } // get currently valid user data $olduser = cleanID(preg_replace('/.*:/', '', $_REQUEST['userid_old'])); $oldinfo = $this->_auth->getUserData($olduser); // get new user data subject to change list($newuser, $newpass, $newname, $newmail, $newgrps) = $this->_retrieveUser(); if (empty($newuser)) { return false; } $changes = array(); if ($newuser != $olduser) { if (!$this->_auth->canDo('modLogin')) { // sanity check, shouldn't be possible msg($this->lang['update_fail'], -1); return false; } // check if $newuser already exists if ($this->_auth->getUserData($newuser)) { msg(sprintf($this->lang['update_exists'], $newuser), -1); $re_edit = true; } else { $changes['user'] = $newuser; } } // generate password if left empty and notification is on if (!empty($_REQUEST['usernotify']) && empty($newpass)) { $newpass = auth_pwgen(); } if (!empty($newpass) && $this->_auth->canDo('modPass')) { $changes['pass'] = $newpass; } if (!empty($newname) && $this->_auth->canDo('modName') && $newname != $oldinfo['name']) { $changes['name'] = $newname; } if (!empty($newmail) && $this->_auth->canDo('modMail') && $newmail != $oldinfo['mail']) { $changes['mail'] = $newmail; } if (!empty($newgrps) && $this->_auth->canDo('modGroups') && $newgrps != $oldinfo['grps']) { $changes['grps'] = $newgrps; } if ($ok = $this->_auth->triggerUserMod('modify', array($olduser, $changes))) { msg($this->lang['update_ok'], 1); if (!empty($_REQUEST['usernotify']) && $newpass) { $notify = empty($changes['user']) ? $olduser : $newuser; $this->_notifyUser($notify, $newpass); } // invalidate all sessions io_saveFile($conf['cachedir'] . '/sessionpurge', time()); } else { msg($this->lang['update_fail'], -1); } if (!empty($re_edit)) { $this->_editUser($olduser); } return $ok; }
/** * Import a file of users in csv format * * csv file should have 4 columns, user_id, full name, email, groups (comma separated) * * @return bool whether successful */ protected function _import() { // check we are allowed to add users if (!checkSecurityToken()) { return false; } if (!$this->_auth->canDo('addUser')) { return false; } // check file uploaded ok. if (empty($_FILES['import']['size']) || !empty($_FILES['import']['error']) && $this->_isUploadedFile($_FILES['import']['tmp_name'])) { msg($this->lang['import_error_upload'], -1); return false; } // retrieve users from the file $this->_import_failures = array(); $import_success_count = 0; $import_fail_count = 0; $line = 0; $fd = fopen($_FILES['import']['tmp_name'], 'r'); if ($fd) { while ($csv = fgets($fd)) { if (!utf8_check($csv)) { $csv = utf8_encode($csv); } $raw = $this->_getcsv($csv); $error = ''; // clean out any errors from the previous line // data checks... if (1 == ++$line) { if ($raw[0] == 'user_id' || $raw[0] == $this->lang['user_id']) { continue; } // skip headers } if (count($raw) < 4) { // need at least four fields $import_fail_count++; $error = sprintf($this->lang['import_error_fields'], count($raw)); $this->_import_failures[$line] = array('error' => $error, 'user' => $raw, 'orig' => $csv); continue; } array_splice($raw, 1, 0, auth_pwgen()); // splice in a generated password $clean = $this->_cleanImportUser($raw, $error); if ($clean && $this->_addImportUser($clean, $error)) { $sent = $this->_notifyUser($clean[0], $clean[1], false); if (!$sent) { msg(sprintf($this->lang['import_notify_fail'], $clean[0], $clean[3]), -1); } $import_success_count++; } else { $import_fail_count++; array_splice($raw, 1, 1); // remove the spliced in password $this->_import_failures[$line] = array('error' => $error, 'user' => $raw, 'orig' => $csv); } } msg(sprintf($this->lang['import_success_count'], $import_success_count + $import_fail_count, $import_success_count), $import_success_count ? 1 : -1); if ($import_fail_count) { msg(sprintf($this->lang['import_failure_count'], $import_fail_count), -1); } } else { msg($this->lang['import_error_readfail'], -1); } // save import failures into the session if (!headers_sent()) { session_start(); $_SESSION['import_failures'] = $this->_import_failures; session_write_close(); } return true; }
/** * Send a new password * * This function handles both phases of the password reset: * * - handling the first request of password reset * - validating the password reset auth token * * @author Benoit Chesneau <*****@*****.**> * @author Chris Smith <*****@*****.**> * @author Andreas Gohr <*****@*****.**> * * @return bool true on success, false on any error */ function act_resendpwd() { global $lang; global $conf; /* @var auth_basic $auth */ global $auth; /* @var Input $INPUT */ global $INPUT; if (!actionOK('resendpwd')) { msg($lang['resendna'], -1); return false; } $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth')); if ($token) { // we're in token phase - get user info from token $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; if (!@file_exists($tfile)) { msg($lang['resendpwdbadauth'], -1); $INPUT->remove('pwauth'); return false; } // token is only valid for 3 days if (time() - filemtime($tfile) > 3 * 60 * 60 * 24) { msg($lang['resendpwdbadauth'], -1); $INPUT->remove('pwauth'); @unlink($tfile); return false; } $user = io_readfile($tfile); $userinfo = $auth->getUserData($user); if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } if (!$conf['autopasswd']) { // we let the user choose a password $pass = $INPUT->str('pass'); // password given correctly? if (!$pass) { return false; } if ($pass != $INPUT->str('passchk')) { msg($lang['regbadpass'], -1); return false; } // change it if (!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { msg('error modifying user data', -1); return false; } } else { // autogenerate the password and send by mail $pass = auth_pwgen(); if (!$auth->triggerUserMod('modify', array($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); } } @unlink($tfile); return true; } else { // we're in request phase if (!$INPUT->post->bool('save')) { return false; } if (!$INPUT->post->str('login')) { msg($lang['resendpwdmissing'], -1); return false; } else { $user = trim($auth->cleanUser($INPUT->post->str('login'))); } $userinfo = $auth->getUserData($user); if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } // generate auth token $token = md5(auth_cookiesalt() . $user); //secret but user based $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; $url = wl('', array('do' => 'resendpwd', 'pwauth' => $token), true, '&'); io_saveFile($tfile, $user); $text = rawLocale('pwconfirm'); $trep = array('FULLNAME' => $userinfo['name'], 'LOGIN' => $user, 'CONFIRM' => $url); $mail = new Mailer(); $mail->to($userinfo['name'] . ' <' . $userinfo['mail'] . '>'); $mail->subject($lang['regpwmail']); $mail->setBody($text, $trep); if ($mail->send()) { msg($lang['resendpwdconfirm'], 1); } else { msg($lang['regmailfail'], -1); } return true; } // never reached }
/** * Send a new password * * This function handles both phases of the password reset: * * - handling the first request of password reset * - validating the password reset auth token * * @author Benoit Chesneau <*****@*****.**> * @author Chris Smith <*****@*****.**> * @author Andreas Gohr <*****@*****.**> * * @return bool true on success, false on any error */ function act_resendpwd() { global $lang; global $conf; global $auth; if (!actionOK('resendpwd')) { return false; } if (!$auth) { return false; } // should not be able to get here without modPass being possible... if (!$auth->canDo('modPass')) { msg($lang['resendna'], -1); return false; } $token = preg_replace('/[^a-f0-9]+/', '', $_REQUEST['pwauth']); if ($token) { // we're in token phase $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; if (!@file_exists($tfile)) { msg($lang['resendpwdbadauth'], -1); return false; } $user = io_readfile($tfile); @unlink($tfile); $userinfo = $auth->getUserData($user); if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } $pass = auth_pwgen(); if (!$auth->triggerUserMod('modify', array($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; } else { // we're in request phase if (!$_POST['save']) { return false; } if (empty($_POST['login'])) { msg($lang['resendpwdmissing'], -1); return false; } else { $user = trim($auth->cleanUser($_POST['login'])); } $userinfo = $auth->getUserData($user); if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } // generate auth token $token = md5(auth_cookiesalt() . $user); //secret but user based $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; $url = wl('', array('do' => 'resendpwd', 'pwauth' => $token), true, '&'); io_saveFile($tfile, $user); $text = rawLocale('pwconfirm'); $text = str_replace('@DOKUWIKIURL@', DOKU_URL, $text); $text = str_replace('@FULLNAME@', $userinfo['name'], $text); $text = str_replace('@LOGIN@', $user, $text); $text = str_replace('@TITLE@', $conf['title'], $text); $text = str_replace('@CONFIRM@', $url, $text); if (mail_send($userinfo['name'] . ' <' . $userinfo['mail'] . '>', $lang['regpwmail'], $text, $conf['mailfrom'])) { msg($lang['resendpwdconfirm'], 1); } else { msg($lang['regmailfail'], -1); } return true; } return false; // never reached }
/** * Send a new password * * This function handles both phases of the password reset: * * - handling the first request of password reset * - validating the password reset auth token * * @author Benoit Chesneau <*****@*****.**> * @author Chris Smith <*****@*****.**> * @author Andreas Gohr <*****@*****.**> * * @return bool true on success, false on any error */ function act_resendpwd() { global $lang; global $conf; global $auth; if (!actionOK('resendpwd')) { msg($lang['resendna'], -1); return false; } $token = preg_replace('/[^a-f0-9]+/', '', $_REQUEST['pwauth']); if ($token) { // we're in token phase - get user info from token $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; if (!@file_exists($tfile)) { msg($lang['resendpwdbadauth'], -1); unset($_REQUEST['pwauth']); return false; } // token is only valid for 3 days if (time() - filemtime($tfile) > 3 * 60 * 60 * 24) { msg($lang['resendpwdbadauth'], -1); unset($_REQUEST['pwauth']); @unlink($tfile); return false; } $user = io_readfile($tfile); $userinfo = $auth->getUserData($user); if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } if (!$conf['autopasswd']) { // we let the user choose a password // password given correctly? if (!isset($_REQUEST['pass']) || $_REQUEST['pass'] == '') { return false; } if ($_REQUEST['pass'] != $_REQUEST['passchk']) { msg($lang['regbadpass'], -1); return false; } $pass = $_REQUEST['pass']; if (!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { msg('error modifying user data', -1); return false; } } else { // autogenerate the password and send by mail $pass = auth_pwgen(); if (!$auth->triggerUserMod('modify', array($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); } } @unlink($tfile); return true; } else { // we're in request phase if (!$_POST['save']) { return false; } if (empty($_POST['login'])) { msg($lang['resendpwdmissing'], -1); return false; } else { $user = trim($auth->cleanUser($_POST['login'])); } $userinfo = $auth->getUserData($user); if (!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } // generate auth token $token = md5(auth_cookiesalt() . $user); //secret but user based $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth'; $url = wl('', array('do' => 'resendpwd', 'pwauth' => $token), true, '&'); io_saveFile($tfile, $user); $text = rawLocale('pwconfirm'); $text = str_replace('@DOKUWIKIURL@', DOKU_URL, $text); $text = str_replace('@FULLNAME@', $userinfo['name'], $text); $text = str_replace('@LOGIN@', $user, $text); $text = str_replace('@TITLE@', $conf['title'], $text); $text = str_replace('@CONFIRM@', $url, $text); if (empty($conf['mailprefix'])) { $subject = $lang['regpwmail']; } else { $subject = '[' . $conf['mailprefix'] . '] ' . $lang['regpwmail']; } if (mail_send($userinfo['name'] . ' <' . $userinfo['mail'] . '>', $subject, $text, $conf['mailfrom'])) { msg($lang['resendpwdconfirm'], 1); } else { msg($lang['regmailfail'], -1); } return true; } return false; // never reached }
/** * new user, create him - making sure the login is unique by adding a number if needed * * @param array $uinfo user info received from the oAuth service * @param string $servicename * * @return bool */ protected function addUser(&$uinfo, $servicename) { global $conf; $user = $uinfo['user']; $count = ''; while ($this->getUserData($user . $count)) { if ($count) { $count++; } else { $count = 1; } } $user = $user . $count; $uinfo['user'] = $user; $groups_on_creation = array(); $groups_on_creation[] = $conf['defaultgroup']; $groups_on_creation[] = $this->cleanGroup($servicename); // add service as group $uinfo['grps'] = array_merge((array) $uinfo['grps'], $groups_on_creation); $ok = $this->triggerUserMod('create', array($user, auth_pwgen($user), $uinfo['name'], $uinfo['mail'], $groups_on_creation)); if (!$ok) { return false; } // send notification about the new user $subscription = new Subscription(); $subscription->send_register($user, $uinfo['name'], $uinfo['mail']); return true; }
function _addUser() { if (!checkSecurityToken()) { return false; } if (!$this->_auth->canDo('addUser')) { return false; } list($user, $pass, $name, $mail, $grps) = $this->_retrieveUser(); if (empty($user)) { return false; } if ($this->_auth->canDo('modPass')) { if (empty($pass)) { if (!empty($_REQUEST['usernotify'])) { $pass = auth_pwgen(); } else { msg($this->lang['add_fail'], -1); return false; } } } else { if (!empty($pass)) { msg($this->lang['add_fail'], -1); return false; } } if ($this->_auth->canDo('modName')) { if (empty($name)) { msg($this->lang['add_fail'], -1); return false; } } else { if (!empty($name)) { return false; } } if ($this->_auth->canDo('modMail')) { if (empty($mail)) { msg($this->lang['add_fail'], -1); return false; } } else { if (!empty($mail)) { return false; } } if ($ok = $this->_auth->triggerUserMod('create', array($user, $pass, $name, $mail, $grps))) { msg($this->lang['add_ok'], 1); if (!empty($_REQUEST['usernotify']) && $pass) { $this->_notifyUser($user, $pass); } } else { msg($this->lang['add_fail'], -1); } return $ok; }
/** * Handle the login * * This either trusts the session data (if any), processes the second oAuth step or simply * executes a normal plugin against local users. * * @param string $user * @param string $pass * @param bool $sticky * @return bool */ function trustExternal($user, $pass, $sticky = false) { global $conf; global $USERINFO; // are we in login progress? if (isset($_SESSION[DOKU_COOKIE]['oauth-inprogress'])) { $servicename = $_SESSION[DOKU_COOKIE]['oauth-inprogress']['service']; $page = $_SESSION[DOKU_COOKIE]['oauth-inprogress']['id']; unset($_SESSION[DOKU_COOKIE]['oauth-inprogress']); } // check session for existing oAuth login data $session = $_SESSION[DOKU_COOKIE]['auth']; if (!isset($servicename) && isset($session['oauth'])) { $servicename = $session['oauth']; // check if session data is still considered valid if ($session['time'] >= time() - $conf['auth_security_timeout'] && $session['buid'] == auth_browseruid()) { $_SERVER['REMOTE_USER'] = $session['user']; $USERINFO = $session['info']; return true; } } // either we're in oauth login or a previous log needs to be rechecked if (isset($servicename)) { /** @var helper_plugin_oauth $hlp */ $hlp = plugin_load('helper', 'oauth'); $service = $hlp->loadService($servicename); if (is_null($service)) { return false; } if ($service->checkToken()) { $uinfo = $service->getUser(); $uinfo['user'] = $this->cleanUser((string) $uinfo['user']); if (!$uinfo['name']) { $uinfo['name'] = $uinfo['user']; } if (!$uinfo['user'] || !$uinfo['mail']) { msg("{$servicename} did not provide the needed user info. Can't log you in", -1); return false; } // see if the user is known already $user = $this->getUserByEmail($uinfo['mail']); if ($user) { $sinfo = $this->getUserData($user); // check if the user allowed access via this service if (!in_array($this->cleanGroup($servicename), $sinfo['grps'])) { msg(sprintf($this->getLang('authnotenabled'), $servicename), -1); return false; } $uinfo['user'] = $user; $uinfo['name'] = $sinfo['name']; $uinfo['grps'] = array_merge((array) $uinfo['grps'], $sinfo['grps']); } else { // new user, create him - making sure the login is unique by adding a number if needed $user = $uinfo['user']; $count = ''; while ($this->getUserData($user . $count)) { if ($count) { $count++; } else { $count = 1; } } $user = $user . $count; $uinfo['user'] = $user; $groups_on_creation = array(); $groups_on_creation[] = $conf['defaultgroup']; $groups_on_creation[] = $this->cleanGroup($servicename); // add service as group $uinfo['grps'] = array_merge((array) $uinfo['grps'], $groups_on_creation); $ok = $this->triggerUserMod('create', array($user, auth_pwgen($user), $uinfo['name'], $uinfo['mail'], $groups_on_creation)); if (!$ok) { msg('something went wrong creating your user account. please try again later.', -1); return false; } // send notification about the new user $subscription = new Subscription(); $subscription->send_register($user, $uinfo['name'], $uinfo['mail']); } // set user session $this->setUserSession($uinfo, $servicename); $cookie = base64_encode($user) . '|' . (int) $sticky . '|' . base64_encode('oauth') . '|' . base64_encode($servicename); $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir']; $time = $sticky ? time() + 60 * 60 * 24 * 365 : 0; setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', $conf['securecookie'] && is_ssl(), true); if (isset($page)) { send_redirect(wl($page)); } return true; } else { $this->relogin($servicename); } unset($_SESSION[DOKU_COOKIE]['auth']); return false; // something went wrong during oAuth login } elseif (isset($_COOKIE[DOKU_COOKIE])) { global $INPUT; //try cookie list($cookieuser, $cookiesticky, $auth, $servicename) = explode('|', $_COOKIE[DOKU_COOKIE]); $cookieuser = base64_decode($cookieuser, true); $auth = base64_decode($auth, true); $servicename = base64_decode($servicename, true); if ($auth === 'oauth') { $this->relogin($servicename); } } // do the "normal" plain auth login via form return auth_login($user, $pass, $sticky); }