Completed
Push — master ( a628a7...1ffed7 )
by Andreas
03:36
created

Resendpwd::tplContent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
cc 1
eloc 2
c 1
b 1
f 1
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
namespace dokuwiki\Action;
4
5
use dokuwiki\Action\Exception\ActionAbort;
6
use dokuwiki\Action\Exception\ActionDisabledException;
7
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
        return AUTH_NONE;
20
    }
21
22
    /** @inheritdoc */
23
    public function checkPreconditions() {
24
        parent::checkPreconditions();
25
26
        /** @var \DokuWiki_Auth_Plugin $auth */
27
        global $auth;
28
        global $conf;
29
        if(isset($conf['resendpasswd']) && !$conf['resendpasswd']) throw new ActionDisabledException(); //legacy option
30
        if(!$auth->canDo('modPass')) throw new ActionDisabledException();
31
    }
32
33
    /** @inheritdoc */
34
    public function preProcess() {
35
        if($this->resendpwd()) {
36
            throw new ActionAbort('login');
37
        }
38
    }
39
40
    /** @inheritdoc */
41
    public function tplContent() {
42
        html_resendpwd();
43
    }
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 <[email protected]>
54
     * @author Chris Smith <[email protected]>
55
     * @author Andreas Gohr <[email protected]>
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
        global $lang;
61
        global $conf;
62
        /* @var \DokuWiki_Auth_Plugin $auth */
63
        global $auth;
64
        global $INPUT;
65
66
        if(!actionOK('resendpwd')) {
67
            msg($lang['resendna'], -1);
68
            return false;
69
        }
70
71
        $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth'));
72
73
        if($token) {
74
            // we're in token phase - get user info from token
75
76
            $tfile = $conf['cachedir'] . '/' . $token{0} . '/' . $token . '.pwauth';
77
            if(!file_exists($tfile)) {
78
                msg($lang['resendpwdbadauth'], -1);
79
                $INPUT->remove('pwauth');
80
                return false;
81
            }
82
            // token is only valid for 3 days
83
            if((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) {
84
                msg($lang['resendpwdbadauth'], -1);
85
                $INPUT->remove('pwauth');
86
                @unlink($tfile);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
87
                return false;
88
            }
89
90
            $user = io_readfile($tfile);
91
            $userinfo = $auth->getUserData($user, $requireGroups = false);
92
            if(!$userinfo['mail']) {
93
                msg($lang['resendpwdnouser'], -1);
94
                return false;
95
            }
96
97
            if(!$conf['autopasswd']) { // we let the user choose a password
98
                $pass = $INPUT->str('pass');
99
100
                // password given correctly?
101
                if(!$pass) return false;
102
                if($pass != $INPUT->str('passchk')) {
103
                    msg($lang['regbadpass'], -1);
104
                    return false;
105
                }
106
107
                // change it
108
                if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
109
                    msg($lang['proffail'], -1);
110
                    return false;
111
                }
112
113
            } else { // autogenerate the password and send by mail
114
115
                $pass = auth_pwgen($user);
116
                if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
117
                    msg($lang['proffail'], -1);
118
                    return false;
119
                }
120
121
                if(auth_sendPassword($user, $pass)) {
122
                    msg($lang['resendpwdsuccess'], 1);
123
                } else {
124
                    msg($lang['regmailfail'], -1);
125
                }
126
            }
127
128
            @unlink($tfile);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
129
            return true;
130
131
        } else {
132
            // we're in request phase
133
134
            if(!$INPUT->post->bool('save')) return false;
135
136
            if(!$INPUT->post->str('login')) {
137
                msg($lang['resendpwdmissing'], -1);
138
                return false;
139
            } else {
140
                $user = trim($auth->cleanUser($INPUT->post->str('login')));
141
            }
142
143
            $userinfo = $auth->getUserData($user, $requireGroups = false);
144
            if(!$userinfo['mail']) {
145
                msg($lang['resendpwdnouser'], -1);
146
                return false;
147
            }
148
149
            // generate auth token
150
            $token = md5(auth_randombytes(16)); // random secret
151
            $tfile = $conf['cachedir'] . '/' . $token{0} . '/' . $token . '.pwauth';
152
            $url = wl('', array('do' => 'resendpwd', 'pwauth' => $token), true, '&');
153
154
            io_saveFile($tfile, $user);
155
156
            $text = rawLocale('pwconfirm');
157
            $trep = array(
158
                'FULLNAME' => $userinfo['name'],
159
                'LOGIN' => $user,
160
                'CONFIRM' => $url
161
            );
162
163
            $mail = new \Mailer();
164
            $mail->to($userinfo['name'] . ' <' . $userinfo['mail'] . '>');
165
            $mail->subject($lang['regpwmail']);
166
            $mail->setBody($text, $trep);
167
            if($mail->send()) {
168
                msg($lang['resendpwdconfirm'], 1);
169
            } else {
170
                msg($lang['regmailfail'], -1);
171
            }
172
            return true;
173
        }
174
        // never reached
175
    }
176
177
}
178