forgotpass.php 8.55 KB
Newer Older
Nigel McNie's avatar
Nigel McNie committed
1
2
3
4
5
<?php
/**
 *
 * @package    mahara
 * @subpackage core
6
 * @author     Catalyst IT Ltd
7
8
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
 * @copyright  For copyright information on Mahara, please see the README file distributed with this software.
Nigel McNie's avatar
Nigel McNie committed
9
10
11
12
13
 *
 */

define('INTERNAL', 1);
define('PUBLIC', 1);
14
15
16
17
define('SECTION_PLUGINTYPE', 'core');
define('SECTION_PLUGINNAME', 'site');
define('SECTION_PAGE', 'forgotpass');

Nigel McNie's avatar
Nigel McNie committed
18
require('init.php');
19
require_once('pieforms/pieform.php');
Nigel McNie's avatar
Nigel McNie committed
20

21
22
if (!empty($SESSION->pwchangerequested)) {
    unset($SESSION->pwchangerequested);
Nigel McNie's avatar
Nigel McNie committed
23
24
25
26
    die_info(get_string('pwchangerequestsent'));
}

if (isset($_GET['key'])) {
27
    $SESSION->set('forgotpasskey', $_GET['key']);
28
29
    redirect('/forgotpass.php');
}
30
if (isset($SESSION->forgotpasskey)) {
31
32
    define('TITLE', get_string('changepassword'));

33
34
    if (!$pwrequest = get_record('usr_password_request', 'key', $SESSION->forgotpasskey)) {
        unset($SESSION->forgotpasskey);
Nigel McNie's avatar
Nigel McNie committed
35
36
37
        die_info(get_string('nosuchpasswordrequest'));
    }

38
    if (strtotime($pwrequest->expiry) < time()) {
39
        unset($SESSION->forgotpasskey);
40
41
42
        die_info(get_string('passwordresetexpired'));
    }

Nigel McNie's avatar
Nigel McNie committed
43
44
45
46
47
48
49
50
51
    $form = array(
        'name' => 'forgotpasschange',
        'method' => 'post',
        'action' => '',
        'autofocus' => true,
        'elements' => array(
            'password1' => array(
                'type' => 'password',
                'title' => get_string('password'),
52
                'description' => get_string('yournewpassword'),
Nigel McNie's avatar
Nigel McNie committed
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
                'rules' => array(
                    'required' => true
                )
            ),
            'password2' => array(
                'type' => 'password',
                'title' => get_string('confirmpassword'),
                'rules' => array(
                    'required' => true
                )
            ),
            'user' => array(
                'type' => 'hidden',
                'value' => $pwrequest->usr
            ),
            'submit' => array(
                'type' => 'submit',
70
                'value' => get_string('change')
Nigel McNie's avatar
Nigel McNie committed
71
72
73
74
75
            )
        )
    );

    $smarty = smarty();
76
    $smarty->assign('forgotpasschange_form', pieform($form));
77
    $smarty->assign('heading', get_string('changepassword'));
Nigel McNie's avatar
Nigel McNie committed
78
79
    $smarty->display('forgotpass.tpl');
    exit;
80
81
82
}
else {
    define('TITLE', get_string('forgotusernamepassword'));
Nigel McNie's avatar
Nigel McNie committed
83
84
85
86
87
88
89
90
}

$form = array(
    'name'      => 'forgotpass',
    'method'    => 'post',
    'action'    => '',
    'autofocus' => true,
    'elements'  => array(
91
        'emailusername' => array(
Nigel McNie's avatar
Nigel McNie committed
92
            'type' => 'text',
93
            'title' => get_string('emailaddressorusername'),
Nigel McNie's avatar
Nigel McNie committed
94
95
96
97
98
99
100
            'description' => get_string('emailaddressdescription'),
            'rules' => array(
                'required' => true,
            )
        ),
        'submit' => array(
            'type' => 'submit',
101
            'value' => get_string('sendrequest')
Nigel McNie's avatar
Nigel McNie committed
102
103
104
105
        )
    )
);

106
function forgotpass_validate(Pieform $form, $values) {
107
108
    // See if the user input an email address or a username. We favour email addresses
    if (!$form->get_error('emailusername')) {
109
110
111
112
113
114
115
116
117
118
119
120
121
122
        // Check if the user who associates to username or email address is using the external authentication
        if (record_exists_sql('SELECT u.authinstance
            FROM {usr} u INNER JOIN {auth_instance} ai ON (u.authinstance = ai.id)
            WHERE (LOWER(u.email) = ? OR LOWER(u.username) = ?)
            AND ((ai.authname != \'internal\') AND (ai.authname != \'none\'))', array_fill(0, 2, strtolower($values['emailusername'])))) {
                $form->set_error('emailusername', get_string('forgotpassuserusingexternalauthentication', 'mahara', get_config('wwwroot') . 'contact.php'));
        }
        else {
            if (!($authinstance = get_field_sql('SELECT u.authinstance
                FROM {usr} u INNER JOIN {auth_instance} ai ON (u.authinstance = ai.id)
                WHERE (LOWER(u.email) = ? OR LOWER(u.username) = ?)
                AND ai.authname = \'internal\'', array_fill(0, 2, strtolower($values['emailusername']))))) {
                    $form->set_error('emailusername', get_string('forgotpassnosuchemailaddressorusername'));
            }
123
        }
Nigel McNie's avatar
Nigel McNie committed
124
    }
125

126
    if ($form->get_error('emailusername')) {
127
128
        return;
    }
129

130
    $authobj = AuthFactory::create($authinstance);
131
    if (!method_exists($authobj, 'change_password')) {
132
        die_info(get_string('cantchangepassword'));
Nigel McNie's avatar
Nigel McNie committed
133
134
135
    }
}

136
function forgotpass_submit(Pieform $form, $values) {
Nigel McNie's avatar
Nigel McNie committed
137
138
139
    global $SESSION;

    try {
140
        if (!($user = get_record_sql('SELECT u.* FROM {usr} u
141
142
143
            INNER JOIN {auth_instance} ai ON (u.authinstance = ai.id)
            WHERE (LOWER(u.email) = ? OR LOWER(u.username) = ?)
            AND ai.authname = \'internal\'', array_fill(0, 2, strtolower($values['emailusername']))))) {
144
                die_info(get_string('forgotpassnosuchemailaddressorusername'));
Nigel McNie's avatar
Nigel McNie committed
145
146
147
148
149
150
        }

        $pwrequest = new StdClass;
        $pwrequest->usr = $user->id;
        $pwrequest->expiry = db_format_timestamp(time() + 86400);
        $pwrequest->key = get_random_key();
151
152
        $sitename = get_config('sitename');
        $fullname = display_name($user);
153
154
        // Override the disabled status of this e-mail address
        $user->ignoredisabled = true;
Nigel McNie's avatar
Nigel McNie committed
155
        email_user($user, null,
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
            get_string('forgotusernamepasswordemailsubject', 'mahara', $sitename),
            get_string('forgotusernamepasswordemailmessagetext', 'mahara',
                $fullname,
                $sitename,
                $user->username,
                get_config('wwwroot') . 'forgotpass.php?key=' . $pwrequest->key,
                get_config('wwwroot') . 'contact.php',
                $sitename),
            get_string('forgotusernamepasswordemailmessagehtml', 'mahara',
                $fullname,
                $sitename,
                $user->username,
                get_config('wwwroot') . 'forgotpass.php?key=' . $pwrequest->key,
                get_config('wwwroot') . 'forgotpass.php?key=' . $pwrequest->key,
                get_config('wwwroot') . 'contact.php',
                $sitename));
Nigel McNie's avatar
Nigel McNie committed
172
173
174
        insert_record('usr_password_request', $pwrequest);
    }
    catch (SQLException $e) {
175
        die_info(get_string('forgotpassemailsendunsuccessful'));
Nigel McNie's avatar
Nigel McNie committed
176
177
    }
    catch (EmailException $e) {
178
        die_info(get_string('forgotpassemailsendunsuccessful'));
Nigel McNie's avatar
Nigel McNie committed
179
180
    }

181
182
183
184
    // Add a note if this e-mail address is over the bounce threshold to
    // warn users that they may not receive the e-mail
    if ($mailinfo = get_record_select('artefact_internal_profile_email', '"owner" = ? AND principal = 1', array($user->id))) {
        if (check_overcount($mailinfo)) {
185
            $SESSION->add_info_msg(get_string('forgotpassemailsentanyway1', 'mahara', get_config('sitename')));
186
187
188
189
190
191
        }
    }

    // Unsetting disabled status overriding
    unset($user->ignoredisabled);

Nigel McNie's avatar
Nigel McNie committed
192
    // Add a marker in the session to say that the user has registered
193
    $SESSION->set('pwchangerequested', true);
Nigel McNie's avatar
Nigel McNie committed
194

195
    redirect('/forgotpass.php');
Nigel McNie's avatar
Nigel McNie committed
196
197
}

198
function forgotpasschange_validate(Pieform $form, $values) {
199
200
    $user = new User();
    $user->find_by_id($values['user']);
201
    password_validate($form, $values, $user);
Nigel McNie's avatar
Nigel McNie committed
202
203
204
205
206
207
}

// TODO:
//   password_validate to maharalib, use it in places specified, test with a drop/create run
//   support autofocus => (true|'id'), remove stuff doing autofocus from where it is, focus error fields
//   commit stuff
208
function forgotpasschange_submit(Pieform $form, $values) {
209
    global $SESSION, $USER;
Nigel McNie's avatar
Nigel McNie committed
210

211
    unset($SESSION->forgotpasskey);
212
213
214
215
    try {
        $user = new User();
        $user->find_by_id($values['user']);
    } catch (AuthUnknownUserException $e) {
216
        throw new UserException('Request to change the password for a user who does not exist');
Nigel McNie's avatar
Nigel McNie committed
217
218
    }

219
220
    $authobj = AuthFactory::create($user->authinstance);
    if ($password = $authobj->change_password($user, $values['password1'])) {
Nigel McNie's avatar
Nigel McNie committed
221
222
223
224

        // Remove the password request(s) for the user
        delete_records('usr_password_request', 'usr', $values['user']);

225
226
        ensure_user_account_is_active($user);

227
        $USER->reanimate($user->id, $user->authinstance);
228
229
230
231

        // Destroy other sessions of the user
        remove_user_sessions($USER->get('id'));

Nigel McNie's avatar
Nigel McNie committed
232
        $SESSION->add_ok_msg(get_string('passwordchangedok'));
233
        redirect();
Nigel McNie's avatar
Nigel McNie committed
234
235
236
        exit;
    }

237
    throw new SystemException('User "' . $user->username
Nigel McNie's avatar
Nigel McNie committed
238
239
240
241
        . ' tried to change their password, but the attempt failed');
}

$smarty = smarty();
242
$smarty->assign('forgotpass_form', pieform($form));
243
$smarty->assign('heading', get_string('forgotusernamepassword'));
Nigel McNie's avatar
Nigel McNie committed
244
$smarty->display('forgotpass.tpl');