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