* * AuthUser account self-registration and management * * To install, add the following line to your configuration file : include_once("$FarmD/cookbook/authuserprofiles.php"); * * For more information, please see the online documentation at * http://www.pmwiki.org/wiki/Cookbook/AuthUserProfiles * * * This script is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This script is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ $RecipeInfo['AuthUserProfiles']['Version'] = '2010-05-25'; if (!IsEnabled($EnableAuthorTracking,1)) Abort('$EnableAuthorTracking required for AuthUserProfiles'); SDV($AuthUserFunctions['userprofilegroup'], 'AuthUserProfiles'); function AuthUserProfiles($pagename, $id, $pw, $pwlist, &$authlist) { foreach ((array)$pwlist as $pgroup) { $pn = MakePageName($pagename, "$pgroup.$id"); $page = ReadPage($pn, READPAGE_CURRENT); if ($page && !empty($page['userid']) && ($id == $page['userid']) && !empty($page['passwdhash']) && (_crypt($pw, $page['passwdhash']) == $page['passwdhash']) ) { if (!empty($page['usergroups']) && preg_match_all('/@[^,\s]+/', $page['usergroups'], $m)) foreach ($m[0] as $g) $authlist[$g] = 1; return true; } } return false; } if ($action != 'newuser') return; XLSDV('en', array( 'newuser_success_mail' => 'Account created, email sent with activation link', 'newuser_success_done' => 'Account created', 'newuser_success_key' => 'E-mail address verified, account activated', 'newuser_fail' => 'Error creating account, please contact site admin', 'newuser_fail_key' => 'Wrong activation key for this user', 'newuser_empty_userid' => 'Username is required', 'newuser_empty_userpw' => 'Password is required', 'newuser_empty_userpw2' => 'Please enter your password twice', 'newuser_empty_useremail' => 'An e-mail address is required', 'newuser_diff_userpw' => 'Passwords don\'t match', 'newuser_invalid_userid' => 'Username is not valid, please use alphanumeric characters only', 'newuser_invalid_email' => 'E-mail address is not valid', 'newuser_invalid_password' => 'Password is not valid', 'newuser_exists' => 'Username already exits', 'newuser_csum_done' => 'New user account created', 'newuser_csum_wait' => 'New user account: waiting for confirmation', 'newuser_email_error' => 'Error sending confirmation email, please contact site admin', 'newuser_email_from' => "no-reply@{$_SERVER['HTTP_HOST']}", 'newuser_email_subject' => "Welcome to $WikiTitle", 'newuser_email_body' => "Welcome \$newuser! Thank you for registering at $WikiTitle. To activate your account and confirm your e-mail address, please visit the following location: \$link " )); SDV($HandleActions['newuser'], 'HandleNewUser'); SDV($NewUserFields, array( 'userid' => '$[Username]', 'userpw' => '$[Password]', 'userpw2' => '$[Password, again]', 'useremail' => '$[E-mail address]' )); ## based on HandleEdit function NewUserSavePage($pagename, $opt, $auth = 'read') { global $Now, $EditFunctions, $IsPagePosted; Lock(2); $page = RetrieveAuthPage($pagename, $auth, TRUE); if (!$page) Abort("?cannot edit $pagename"); $new = $page; foreach((array)$opt as $k => $v) { if ($v) $new[$k] = $v; else unset($new[$k]); } if ($new['csum']) $new["csum:$Now"] = $new['csum']; PCache($pagename, $new); $k = array_search('SaveAttributes', $EditFunctions); if ($k !== FALSE) unset($EditFunctions[$k]); UpdatePage($pagename, $page, $new); Lock(0); return $IsPagePosted; } ## Profiles/User?action=newuser&key=1234567890 function NewUserConfirmKey($pagename, $key) { global $PCache, $ChangeSummary, $EditFields, $EditFunctions, $SaveProperties; $page = $PCache[$pagename]; if (empty($page['userkey']) || !preg_match("/^$key (.*)$/", $page['userkey'], $match)) return 'newuser_fail_key'; $opt = array( 'csum' => XL('newuser_csum_done'), 'passwdhash' => $match[1], 'userkey' => '', ); return NewUserSavePage($pagename, $opt) ? 'newuser_success_key' : 'newuser_fail'; } ## validate inputs SDV($UserNameValidFunction, 'UserNameValidSimple'); function UserNameValidSimple(&$pagename, $id) { global $AuthorGroup, $UserNameChars, $UserNameDeniedPages; SDV($UserNameChars,'-[:alnum:]'); $id = preg_replace("/[^$UserNameChars]+/", '', $id); if (!$id || ($id != $_POST['userid'])) return FALSE; SDV($UserNameDeniedPages, "$AuthorGroup|SideBar|(Group(Print)?(Attributes|Header|Footer))"); $pagename = MakePageName($pagename, "$AuthorGroup.$id"); if (preg_match("/\.($UserNameDeniedPages)$/", $pagename)) return FALSE; return TRUE; } SDV($UserEmailValidFunction, 'UserEmailValidSimple'); function UserEmailValidSimple($address) { return preg_match('/^.+@.+\..+$/', $address); } SDV($UserPasswordValidFunction, 'UserPasswordValidSimple'); function UserPasswordValidSimple($pw) { return (boolean)$pw; } SDV($UserExistsFunction, 'UserProfileExists'); function UserProfileExists($pagename, $id) { $page = ReadPage($pagename, READPAGE_CURRENT); return $page && (!empty($page['userid']) || preg_grep('/^passwd/', array_keys($page))); } function NewUserValidateInput($data, &$pn) { global $NewUserFields, $UserNameValidFunction, $UserEmailValidFunction, $UserPasswordValidFunction, $UserExistsFunction; foreach ($NewUserFields as $f => $p) { if (empty($data[$f])) return "newuser_empty_$f"; else if (preg_match('/^(.*)2$/', $f, $m)) { if ($data[$m[1]] != $data[$f]) return "newuser_diff_{$m[1]}"; } } $id = stripmagic($data['userid']); if (!$UserNameValidFunction($pn, $id)) return 'newuser_invalid_userid'; if ($UserExistsFunction($pn, $id)) return 'newuser_exists'; if (!$UserEmailValidFunction(@$data['useremail'])) return 'newuser_invalid_email'; if (!$UserPasswordValidFunction($data['userpw'])) return 'newuser_invalid_password'; return NULL; } ## send email with activation link function NewUserMailKey($pagename, $opt) { if (empty($opt['email'])) return 'newuser_err_send'; if (empty($opt['link'])) { $opt['link'] = FmtPageName('{$PageUrl}', $pagename); $opt['link'] .= (strpos($opt['link'], '?') ? '&' : '?'). "action=newuser&key={$opt['key']}"; } if (empty($opt['newuser'])) $opt['newuser'] = $_POST['userid']; $msg = XL('newuser_email_body'); foreach($opt as $k => $v) $msg = preg_replace("/\\$$k\b`?/", $v, $msg); $head = 'From: ' . XL('newuser_email_from'); return mail($opt['email'], XL('newuser_email_subject'), $msg, $head); } ## save the new user data & optionally mail the user an activation link function NewUserSubmit($pagename) { global $NewUserConfirmEmail; $hash = crypt(stripmagic($_POST['userpw'])); if (IsEnabled($NewUserConfirmEmail, 1)) { $key = strval(mt_rand() + 1); $mail_opt = array('key' => $key, 'email' => $_POST['useremail']); if (!NewUserMailKey($pagename, $mail_opt)) return 'newuser_email_error'; $opt = array( 'csum' => XL('newuser_csum_wait'), 'useremail' => stripmagic($_POST['useremail']), 'userid' => stripmagic($_POST['userid']), 'userkey' => "$key $hash", ); return NewUserSavePage($pagename, $opt) ? 'newuser_success_mail' : 'newuser_fail'; } else { $opt = array( 'csum' => XL('newuser_csum_done'), 'passwdhash' => $hash, 'useremail' => stripmagic(@$_POST['useremail']), 'userid' => stripmagic($_POST['userid']), ); return NewUserSavePage($pagename, $opt) ? 'newuser_success_done' : 'newuser_fail'; } } function PrintNewUserForm($pagename, $result) { global $MessagesFmt, $NewUserFields; if (!empty($MessagesFmt)) echo FmtPageName(implode('', (array)$MessagesFmt), $pagename); if (preg_match('/^newuser_(fail|success)/', $result)) { echo FmtPageName("\nView page", $pagename); return; } echo FmtPageName("\n
", $pagename); foreach ($NewUserFields as $f => $p) { if (strpos($f, 'pw') !== FALSE) { $type = 'password'; $value = ''; } else { $type = 'text'; $value = isset($_POST[$f]) ? $_POST[$f] : ''; } $prompt = FmtPageName($p, $pagename); echo "\n\t\t"; } echo FmtPageName("\n\t
$prompt
\n\t\n
", $pagename); } function HandleNewUser($pagename, $auth = 'read') { global $HandleNewUserFmt, $PageStartFmt, $PageEndFmt, $MessagesFmt; $pform = RetrieveAuthPage($pagename, $auth, TRUE); if (!$pform) Abort("?cannot add new user"); PCache($pagename, $pform); $result = NULL; if (!empty($_REQUEST['key'])) $result = NewUserConfirmKey($pagename, preg_replace('/[^0-9]+/', '', $_REQUEST['key'])); if (!$result && !empty($_POST)) { if (!$result) $result = NewUserValidateInput($_POST, $pn); if (!$result) $result = NewUserSubmit($pn); } if ($result) $MessagesFmt[] = "

$[$result]

"; SDV($HandleNewUserFmt, array(&$PageStartFmt, "function:PrintNewUserForm $result", &$PageEndFmt)); PrintFmt($pagename, $HandleNewUserFmt); }