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