xref: /dokuwiki/inc/Action/Resendpwd.php (revision b2c9cd19ff3733a632c8d415256d3096765343f7)
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 */
23*b2c9cd19SAndreas Gohr    public function checkPreconditions() {
24*b2c9cd19SAndreas Gohr        parent::checkPreconditions();
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     */
54d5d08c05SAndreas 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