/** * Handles an existing Moodle user disconnecting from OpenID Connect. * * @param \auth_oidc\event\user_disconnected $event The triggered event. * @return bool Success/Failure. */ public static function handle_oidc_user_disconnected(\auth_oidc\event\user_disconnected $event) { global $DB; $eventdata = $event->get_data(); if (!empty($eventdata['userid'])) { $DB->delete_records('local_o365_token', ['user_id' => $eventdata['userid']]); } }
/** * Handle OIDC disconnection from Moodle account. * * @param bool $justremovetokens If true, just remove the stored OIDC tokens for the user, otherwise revert login methods. */ public function disconnect($justremovetokens = false, \moodle_url $redirect = null) { if ($redirect === null) { $redirect = new \moodle_url('/auth/oidc/ucp.php'); } if ($justremovetokens === true) { global $USER, $DB, $CFG; // Delete token data. $DB->delete_records('auth_oidc_token', ['username' => $USER->username]); $eventdata = ['objectid' => $USER->id, 'userid' => $USER->id]; $event = \auth_oidc\event\user_disconnected::create($eventdata); $event->trigger(); redirect($redirect); } else { global $OUTPUT, $PAGE, $USER, $DB, $CFG; require_once $CFG->dirroot . '/user/lib.php'; $PAGE->set_url('/auth/oidc/ucp.php'); $PAGE->set_context(\context_system::instance()); $PAGE->set_pagelayout('standard'); $USER->editing = false; $ucptitle = get_string('ucp_disconnect_title', 'auth_oidc', $this->config->opname); $PAGE->navbar->add($ucptitle, $PAGE->url); $PAGE->set_title($ucptitle); // Check if we have recorded the user's previous login method. $prevmethodrec = $DB->get_record('auth_oidc_prevlogin', ['userid' => $USER->id]); $prevauthmethod = !empty($prevmethodrec) && is_enabled_auth($prevmethodrec->method) === true ? $prevmethodrec->method : null; // Manual is always available, we don't need it twice. if ($prevauthmethod === 'manual') { $prevauthmethod = null; } // We need either the user's previous method or the manual login plugin to be enabled for disconnection. if (empty($prevauthmethod) && is_enabled_auth('manual') !== true) { throw new \moodle_exception('errornodisconnectionauthmethod', 'auth_oidc'); } // Check to see if the user has a username created by OIDC, or a self-created username. // OIDC-created usernames are usually very verbose, so we'll allow them to choose a sensible one. // Otherwise, keep their existing username. $oidctoken = $DB->get_record('auth_oidc_token', ['username' => $USER->username]); $ccun = isset($oidctoken->oidcuniqid) && strtolower($oidctoken->oidcuniqid) === $USER->username ? true : false; $customdata = ['canchooseusername' => $ccun, 'prevmethod' => $prevauthmethod]; $mform = new \auth_oidc\form\disconnect('?action=disconnectlogin', $customdata); if ($mform->is_cancelled()) { redirect($redirect); } else { if ($fromform = $mform->get_data()) { $origusername = $USER->username; if (empty($fromform->newmethod) || $fromform->newmethod !== $prevauthmethod && $fromform->newmethod !== 'manual') { throw new \moodle_exception('errorauthdisconnectinvalidmethod', 'auth_oidc'); } $updateduser = new \stdClass(); if ($fromform->newmethod === 'manual') { if (empty($fromform->password)) { throw new \moodle_exception('errorauthdisconnectemptypassword', 'auth_oidc'); } if ($customdata['canchooseusername'] === true) { if (empty($fromform->username)) { throw new \moodle_exception('errorauthdisconnectemptyusername', 'auth_oidc'); } if (strtolower($fromform->username) !== $USER->username) { $newusername = strtolower($fromform->username); $usercheck = ['username' => $newusername, 'mnethostid' => $CFG->mnet_localhost_id]; if ($DB->record_exists('user', $usercheck) === false) { $updateduser->username = $newusername; } else { throw new \moodle_exception('errorauthdisconnectusernameexists', 'auth_oidc'); } } } $updateduser->auth = 'manual'; $updateduser->password = $fromform->password; } else { if ($fromform->newmethod === $prevauthmethod) { $updateduser->auth = $prevauthmethod; // We can't use user_update_user as it will rehash the value. if (!empty($prevmethodrec->password)) { $manualuserupdate = new \stdClass(); $manualuserupdate->id = $USER->id; $manualuserupdate->password = $prevmethodrec->password; $DB->update_record('user', $manualuserupdate); } } } // Update user. $updateduser->id = $USER->id; user_update_user($updateduser); // Delete token data. $DB->delete_records('auth_oidc_token', ['username' => $origusername]); $eventdata = ['objectid' => $USER->id, 'userid' => $USER->id]; $event = \auth_oidc\event\user_disconnected::create($eventdata); $event->trigger(); $USER = $DB->get_record('user', ['id' => $USER->id]); redirect($redirect); } } echo $OUTPUT->header(); $mform->display(); echo $OUTPUT->footer(); } }