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