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