Resendpwd.php 5.4 KB

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