/**
  * 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']]);
     }
 }
Exemple #2
0
 /**
  * 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();
     }
 }