Completed
Push — master ( 13ce47...b2c9cd )
by Andreas
10:39 queued 06:48
created

Resendpwd::checkPreconditions()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 3
nop 0
dl 0
loc 9
rs 9.2
c 0
b 0
f 0
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
    /**
41
     * Send a  new password
42
     *
43
     * This function handles both phases of the password reset:
44
     *
45
     *   - handling the first request of password reset
46
     *   - validating the password reset auth token
47
     *
48
     * @author Benoit Chesneau <[email protected]>
49
     * @author Chris Smith <[email protected]>
50
     * @author Andreas Gohr <[email protected]>
51
     * @fixme this should be split up into multiple methods
52
     * @return bool true on success, false on any error
53
     */
54
    protected function resendpwd() {
55
        global $lang;
56
        global $conf;
57
        /* @var \DokuWiki_Auth_Plugin $auth */
58
        global $auth;
59
        global $INPUT;
60
61
        if(!actionOK('resendpwd')) {
62
            msg($lang['resendna'], -1);
63
            return false;
64
        }
65
66
        $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth'));
67
68
        if($token) {
69
            // we're in token phase - get user info from token
70
71
            $tfile = $conf['cachedir'] . '/' . $token{0} . '/' . $token . '.pwauth';
72
            if(!file_exists($tfile)) {
73
                msg($lang['resendpwdbadauth'], -1);
74
                $INPUT->remove('pwauth');
75
                return false;
76
            }
77
            // token is only valid for 3 days
78
            if((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) {
79
                msg($lang['resendpwdbadauth'], -1);
80
                $INPUT->remove('pwauth');
81
                @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...
82
                return false;
83
            }
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
92
            if(!$conf['autopasswd']) { // we let the user choose a password
93
                $pass = $INPUT->str('pass');
94
95
                // password given correctly?
96
                if(!$pass) return false;
97
                if($pass != $INPUT->str('passchk')) {
98
                    msg($lang['regbadpass'], -1);
99
                    return false;
100
                }
101
102
                // change it
103
                if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
104
                    msg($lang['proffail'], -1);
105
                    return false;
106
                }
107
108
            } else { // autogenerate the password and send by mail
109
110
                $pass = auth_pwgen($user);
111
                if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
112
                    msg($lang['proffail'], -1);
113
                    return false;
114
                }
115
116
                if(auth_sendPassword($user, $pass)) {
117
                    msg($lang['resendpwdsuccess'], 1);
118
                } else {
119
                    msg($lang['regmailfail'], -1);
120
                }
121
            }
122
123
            @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...
124
            return true;
125
126
        } else {
127
            // we're in request phase
128
129
            if(!$INPUT->post->bool('save')) return false;
130
131
            if(!$INPUT->post->str('login')) {
132
                msg($lang['resendpwdmissing'], -1);
133
                return false;
134
            } else {
135
                $user = trim($auth->cleanUser($INPUT->post->str('login')));
136
            }
137
138
            $userinfo = $auth->getUserData($user, $requireGroups = false);
139
            if(!$userinfo['mail']) {
140
                msg($lang['resendpwdnouser'], -1);
141
                return false;
142
            }
143
144
            // generate auth token
145
            $token = md5(auth_randombytes(16)); // random secret
146
            $tfile = $conf['cachedir'] . '/' . $token{0} . '/' . $token . '.pwauth';
147
            $url = wl('', array('do' => 'resendpwd', 'pwauth' => $token), true, '&');
148
149
            io_saveFile($tfile, $user);
150
151
            $text = rawLocale('pwconfirm');
152
            $trep = array(
153
                'FULLNAME' => $userinfo['name'],
154
                'LOGIN' => $user,
155
                'CONFIRM' => $url
156
            );
157
158
            $mail = new \Mailer();
159
            $mail->to($userinfo['name'] . ' <' . $userinfo['mail'] . '>');
160
            $mail->subject($lang['regpwmail']);
161
            $mail->setBody($text, $trep);
162
            if($mail->send()) {
163
                msg($lang['resendpwdconfirm'], 1);
164
            } else {
165
                msg($lang['regmailfail'], -1);
166
            }
167
            return true;
168
        }
169
        // never reached
170
    }
171
172
}
173