You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

183 lines
5.4 KiB

  1. <?php
  2. namespace dokuwiki\Action;
  3. use dokuwiki\Ui\UserResendPwd;
  4. use dokuwiki\Action\Exception\ActionAbort;
  5. use dokuwiki\Action\Exception\ActionDisabledException;
  6. use dokuwiki\Extension\AuthPlugin;
  7. use dokuwiki\Ui;
  8. /**
  9. * Class Resendpwd
  10. *
  11. * Handle password recovery
  12. *
  13. * @package dokuwiki\Action
  14. */
  15. class Resendpwd extends AbstractAclAction
  16. {
  17. /** @inheritdoc */
  18. public function minimumPermission()
  19. {
  20. return AUTH_NONE;
  21. }
  22. /** @inheritdoc */
  23. public function checkPreconditions()
  24. {
  25. parent::checkPreconditions();
  26. /** @var AuthPlugin $auth */
  27. global $auth;
  28. global $conf;
  29. if (isset($conf['resendpasswd']) && !$conf['resendpasswd'])
  30. throw new ActionDisabledException(); //legacy option
  31. if (!$auth->canDo('modPass')) throw new ActionDisabledException();
  32. }
  33. /** @inheritdoc */
  34. public function preProcess()
  35. {
  36. if ($this->resendpwd()) {
  37. throw new ActionAbort('login');
  38. }
  39. }
  40. /** @inheritdoc */
  41. public function tplContent()
  42. {
  43. (new UserResendPwd())->show();
  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. {
  61. global $lang;
  62. global $conf;
  63. /* @var AuthPlugin $auth */
  64. global $auth;
  65. global $INPUT;
  66. if (!actionOK('resendpwd')) {
  67. msg($lang['resendna'], -1);
  68. return false;
  69. }
  70. $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth'));
  71. if ($token) {
  72. // we're in token phase - get user info from token
  73. $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth';
  74. if (!file_exists($tfile)) {
  75. msg($lang['resendpwdbadauth'], -1);
  76. $INPUT->remove('pwauth');
  77. return false;
  78. }
  79. // token is only valid for 3 days
  80. if ((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) {
  81. msg($lang['resendpwdbadauth'], -1);
  82. $INPUT->remove('pwauth');
  83. @unlink($tfile);
  84. return false;
  85. }
  86. $user = io_readfile($tfile);
  87. $userinfo = $auth->getUserData($user, $requireGroups = false);
  88. if (empty($userinfo['mail'])) {
  89. msg($lang['resendpwdnouser'], -1);
  90. return false;
  91. }
  92. if (!$conf['autopasswd']) { // we let the user choose a password
  93. $pass = $INPUT->str('pass');
  94. // password given correctly?
  95. if (!$pass) return false;
  96. if ($pass != $INPUT->str('passchk')) {
  97. msg($lang['regbadpass'], -1);
  98. return false;
  99. }
  100. // change it
  101. if (!$auth->triggerUserMod('modify', [$user, ['pass' => $pass]])) {
  102. msg($lang['proffail'], -1);
  103. return false;
  104. }
  105. } else { // autogenerate the password and send by mail
  106. $pass = auth_pwgen($user);
  107. if (!$auth->triggerUserMod('modify', [$user, ['pass' => $pass]])) {
  108. msg($lang['proffail'], -1);
  109. return false;
  110. }
  111. if (auth_sendPassword($user, $pass)) {
  112. msg($lang['resendpwdsuccess'], 1);
  113. } else {
  114. msg($lang['regmailfail'], -1);
  115. }
  116. }
  117. @unlink($tfile);
  118. return true;
  119. } else {
  120. // we're in request phase
  121. if (!$INPUT->post->bool('save')) return false;
  122. if (!$INPUT->post->str('login')) {
  123. msg($lang['resendpwdmissing'], -1);
  124. return false;
  125. } else {
  126. $user = trim($auth->cleanUser($INPUT->post->str('login')));
  127. }
  128. $userinfo = $auth->getUserData($user, $requireGroups = false);
  129. if (empty($userinfo['mail'])) {
  130. msg($lang['resendpwdnouser'], -1);
  131. return false;
  132. }
  133. // generate auth token
  134. $token = md5(auth_randombytes(16)); // random secret
  135. $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth';
  136. $url = wl('', ['do' => 'resendpwd', 'pwauth' => $token], true, '&');
  137. io_saveFile($tfile, $user);
  138. $text = rawLocale('pwconfirm');
  139. $trep = [
  140. 'FULLNAME' => $userinfo['name'],
  141. 'LOGIN' => $user,
  142. 'CONFIRM' => $url
  143. ];
  144. $mail = new \Mailer();
  145. $mail->to($userinfo['name'] . ' <' . $userinfo['mail'] . '>');
  146. $mail->subject($lang['regpwmail']);
  147. $mail->setBody($text, $trep);
  148. if ($mail->send()) {
  149. msg($lang['resendpwdconfirm'], 1);
  150. } else {
  151. msg($lang['regmailfail'], -1);
  152. }
  153. return true;
  154. }
  155. // never reached
  156. }
  157. }