1<?php 2 3namespace dokuwiki\Action; 4 5use dokuwiki\Action\Exception\ActionAbort; 6 7/** 8 * Class Resendpwd 9 * 10 * Handle password recovery 11 * 12 * @package dokuwiki\Action 13 */ 14class Resendpwd extends AbstractAclAction { 15 16 /** @inheritdoc */ 17 function minimumPermission() { 18 return AUTH_NONE; 19 } 20 21 /** @inheritdoc */ 22 public function preProcess() { 23 if($this->resendpwd()) { 24 throw new ActionAbort('login'); 25 } 26 } 27 28 /** 29 * Send a new password 30 * 31 * This function handles both phases of the password reset: 32 * 33 * - handling the first request of password reset 34 * - validating the password reset auth token 35 * 36 * @author Benoit Chesneau <benoit@bchesneau.info> 37 * @author Chris Smith <chris@jalakai.co.uk> 38 * @author Andreas Gohr <andi@splitbrain.org> 39 * @fixme this should be split up into multiple methods 40 * @return bool true on success, false on any error 41 */ 42 function resendpwd() { 43 global $lang; 44 global $conf; 45 /* @var \DokuWiki_Auth_Plugin $auth */ 46 global $auth; 47 global $INPUT; 48 49 if(!actionOK('resendpwd')) { 50 msg($lang['resendna'], -1); 51 return false; 52 } 53 54 $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth')); 55 56 if($token) { 57 // we're in token phase - get user info from token 58 59 $tfile = $conf['cachedir'] . '/' . $token{0} . '/' . $token . '.pwauth'; 60 if(!file_exists($tfile)) { 61 msg($lang['resendpwdbadauth'], -1); 62 $INPUT->remove('pwauth'); 63 return false; 64 } 65 // token is only valid for 3 days 66 if((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) { 67 msg($lang['resendpwdbadauth'], -1); 68 $INPUT->remove('pwauth'); 69 @unlink($tfile); 70 return false; 71 } 72 73 $user = io_readfile($tfile); 74 $userinfo = $auth->getUserData($user, $requireGroups = false); 75 if(!$userinfo['mail']) { 76 msg($lang['resendpwdnouser'], -1); 77 return false; 78 } 79 80 if(!$conf['autopasswd']) { // we let the user choose a password 81 $pass = $INPUT->str('pass'); 82 83 // password given correctly? 84 if(!$pass) return false; 85 if($pass != $INPUT->str('passchk')) { 86 msg($lang['regbadpass'], -1); 87 return false; 88 } 89 90 // change it 91 if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { 92 msg($lang['proffail'], -1); 93 return false; 94 } 95 96 } else { // autogenerate the password and send by mail 97 98 $pass = auth_pwgen($user); 99 if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { 100 msg($lang['proffail'], -1); 101 return false; 102 } 103 104 if(auth_sendPassword($user, $pass)) { 105 msg($lang['resendpwdsuccess'], 1); 106 } else { 107 msg($lang['regmailfail'], -1); 108 } 109 } 110 111 @unlink($tfile); 112 return true; 113 114 } else { 115 // we're in request phase 116 117 if(!$INPUT->post->bool('save')) return false; 118 119 if(!$INPUT->post->str('login')) { 120 msg($lang['resendpwdmissing'], -1); 121 return false; 122 } else { 123 $user = trim($auth->cleanUser($INPUT->post->str('login'))); 124 } 125 126 $userinfo = $auth->getUserData($user, $requireGroups = false); 127 if(!$userinfo['mail']) { 128 msg($lang['resendpwdnouser'], -1); 129 return false; 130 } 131 132 // generate auth token 133 $token = md5(auth_randombytes(16)); // random secret 134 $tfile = $conf['cachedir'] . '/' . $token{0} . '/' . $token . '.pwauth'; 135 $url = wl('', array('do' => 'resendpwd', 'pwauth' => $token), true, '&'); 136 137 io_saveFile($tfile, $user); 138 139 $text = rawLocale('pwconfirm'); 140 $trep = array( 141 'FULLNAME' => $userinfo['name'], 142 'LOGIN' => $user, 143 'CONFIRM' => $url 144 ); 145 146 $mail = new \Mailer(); 147 $mail->to($userinfo['name'] . ' <' . $userinfo['mail'] . '>'); 148 $mail->subject($lang['regpwmail']); 149 $mail->setBody($text, $trep); 150 if($mail->send()) { 151 msg($lang['resendpwdconfirm'], 1); 152 } else { 153 msg($lang['regmailfail'], -1); 154 } 155 return true; 156 } 157 // never reached 158 } 159 160} 161