Completed
Push — actionrefactor ( 6e4bf0 )
by Andreas
04:36
created

Resendpwd::preProcess()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace dokuwiki\Action;
4
5
use dokuwiki\Action\Exception\ActionAbort;
6
7
/**
8
 * Class Resendpwd
9
 *
10
 * Handle password recovery
11
 *
12
 * @package dokuwiki\Action
13
 */
14
class Resendpwd extends AbstractAclAction {
15
16
    /** @inheritdoc */
17
    function minimumPermission() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
18
        return AUTH_NONE;
19
    }
20
21
    /** @inheritdoc */
22
    public function preProcess() {
23
        if($this->resendpwd()) {
24
            throw new ActionAbort('login');
25
        }
26
    }
27
28
    /**
29
     * Send a  new password
30
     *
31
     * This function handles both phases of the password reset:
32
     *
33
     *   - handling the first request of password reset
34
     *   - validating the password reset auth token
35
     *
36
     * @author Benoit Chesneau <[email protected]>
37
     * @author Chris Smith <[email protected]>
38
     * @author Andreas Gohr <[email protected]>
39
     * @fixme this should be split up into multiple methods
40
     * @return bool true on success, false on any error
41
     */
42
    function resendpwd() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
43
        global $lang;
44
        global $conf;
45
        /* @var \DokuWiki_Auth_Plugin $auth */
46
        global $auth;
47
        global $INPUT;
48
49
        if(!actionOK('resendpwd')) {
50
            msg($lang['resendna'], -1);
51
            return false;
52
        }
53
54
        $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth'));
55
56
        if($token) {
57
            // we're in token phase - get user info from token
58
59
            $tfile = $conf['cachedir'] . '/' . $token{0} . '/' . $token . '.pwauth';
60
            if(!file_exists($tfile)) {
61
                msg($lang['resendpwdbadauth'], -1);
62
                $INPUT->remove('pwauth');
63
                return false;
64
            }
65
            // token is only valid for 3 days
66
            if((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) {
67
                msg($lang['resendpwdbadauth'], -1);
68
                $INPUT->remove('pwauth');
69
                @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...
70
                return false;
71
            }
72
73
            $user = io_readfile($tfile);
74
            $userinfo = $auth->getUserData($user, $requireGroups = false);
75
            if(!$userinfo['mail']) {
76
                msg($lang['resendpwdnouser'], -1);
77
                return false;
78
            }
79
80
            if(!$conf['autopasswd']) { // we let the user choose a password
81
                $pass = $INPUT->str('pass');
82
83
                // password given correctly?
84
                if(!$pass) return false;
85
                if($pass != $INPUT->str('passchk')) {
86
                    msg($lang['regbadpass'], -1);
87
                    return false;
88
                }
89
90
                // change it
91
                if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
92
                    msg($lang['proffail'], -1);
93
                    return false;
94
                }
95
96
            } else { // autogenerate the password and send by mail
97
98
                $pass = auth_pwgen($user);
99
                if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
100
                    msg($lang['proffail'], -1);
101
                    return false;
102
                }
103
104
                if(auth_sendPassword($user, $pass)) {
105
                    msg($lang['resendpwdsuccess'], 1);
106
                } else {
107
                    msg($lang['regmailfail'], -1);
108
                }
109
            }
110
111
            @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...
112
            return true;
113
114
        } else {
115
            // we're in request phase
116
117
            if(!$INPUT->post->bool('save')) return false;
118
119
            if(!$INPUT->post->str('login')) {
120
                msg($lang['resendpwdmissing'], -1);
121
                return false;
122
            } else {
123
                $user = trim($auth->cleanUser($INPUT->post->str('login')));
124
            }
125
126
            $userinfo = $auth->getUserData($user, $requireGroups = false);
127
            if(!$userinfo['mail']) {
128
                msg($lang['resendpwdnouser'], -1);
129
                return false;
130
            }
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
137
            io_saveFile($tfile, $user);
138
139
            $text = rawLocale('pwconfirm');
140
            $trep = array(
141
                'FULLNAME' => $userinfo['name'],
142
                'LOGIN' => $user,
143
                'CONFIRM' => $url
144
            );
145
146
            $mail = new \Mailer();
147
            $mail->to($userinfo['name'] . ' <' . $userinfo['mail'] . '>');
148
            $mail->subject($lang['regpwmail']);
149
            $mail->setBody($text, $trep);
150
            if($mail->send()) {
151
                msg($lang['resendpwdconfirm'], 1);
152
            } else {
153
                msg($lang['regmailfail'], -1);
154
            }
155
            return true;
156
        }
157
        // never reached
158
    }
159
160
}
161