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