forgotpass.php 8.67 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 19
require('init.php');

20
if ($SESSION->get('pwchangerequested')) {
21
    $SESSION->set('pwchangerequested', false);
Nigel McNie's avatar
Nigel McNie committed
22 23 24 25
    die_info(get_string('pwchangerequestsent'));
}

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

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

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

Nigel McNie's avatar
Nigel McNie committed
42 43 44 45 46 47 48 49 50
    $form = array(
        'name' => 'forgotpasschange',
        'method' => 'post',
        'action' => '',
        'autofocus' => true,
        'elements' => array(
            'password1' => array(
                'type' => 'password',
                'title' => get_string('password'),
51
                'description' => get_string('yournewpassword'),
Nigel McNie's avatar
Nigel McNie committed
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
                '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',
69
                'class' => 'btn-primary',
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
            'class' => 'btn-primary',
102
            'value' => get_string('sendrequest')
Nigel McNie's avatar
Nigel McNie committed
103 104 105 106
        )
    )
);

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

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

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

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

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

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

182 183 184 185
    // 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)) {
186
            $SESSION->add_info_msg(get_string('forgotpassemailsentanyway1', 'mahara', get_config('sitename')));
187 188 189 190 191 192
        }
    }

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

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

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

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

// 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
209
function forgotpasschange_submit(Pieform $form, $values) {
210
    global $SESSION, $USER;
Nigel McNie's avatar
Nigel McNie committed
211

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

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

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

226 227
        ensure_user_account_is_active($user);

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

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

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

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

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