/**
  * Test user_update_user.
  */
 public function test_user_update_user()
 {
     global $DB;
     $this->resetAfterTest();
     // Create user and modify user profile.
     $user = $this->getDataGenerator()->create_user();
     $user->firstname = 'Test';
     $user->password = '******';
     // Update user and capture event.
     $sink = $this->redirectEvents();
     user_update_user($user);
     $events = $sink->get_events();
     $sink->close();
     $event = array_pop($events);
     // Test updated value.
     $dbuser = $DB->get_record('user', array('id' => $user->id));
     $this->assertSame($user->firstname, $dbuser->firstname);
     $this->assertNotSame('M00dLe@T', $dbuser->password);
     // Test event.
     $this->assertInstanceOf('\\core\\event\\user_updated', $event);
     $this->assertSame($user->id, $event->objectid);
     $this->assertSame('user_updated', $event->get_legacy_eventname());
     $this->assertEventLegacyData($dbuser, $event);
     $this->assertEquals(context_user::instance($user->id), $event->get_context());
     $expectedlogdata = array(SITEID, 'user', 'update', 'view.php?id=' . $user->id, '');
     $this->assertEventLegacyLogData($expectedlogdata, $event);
     // Update user with no password update.
     $password = $user->password = hash_internal_user_password('M00dLe@T');
     user_update_user($user, false);
     $dbuser = $DB->get_record('user', array('id' => $user->id));
     $this->assertSame($password, $dbuser->password);
 }
 /**
  * Installs a site using $CFG->dataroot and $CFG->prefix
  * @throws coding_exception
  * @return void
  */
 public static function install_site()
 {
     global $DB, $CFG;
     require_once $CFG->dirroot . '/user/lib.php';
     if (!defined('BEHAT_UTIL')) {
         throw new coding_exception('This method can be only used by Behat CLI tool');
     }
     // New dataroot.
     self::reset_dataroot();
     $options = array();
     $options['adminuser'] = '******';
     $options['adminpass'] = '******';
     $options['fullname'] = self::BEHATSITENAME;
     $options['shortname'] = self::BEHATSITENAME;
     install_cli_database($options, false);
     $frontpagesummary = new admin_setting_special_frontpagedesc();
     $frontpagesummary->write_setting(self::BEHATSITENAME);
     // Update admin user info.
     $user = $DB->get_record('user', array('username' => 'admin'));
     $user->email = '*****@*****.**';
     $user->firstname = 'Admin';
     $user->lastname = 'User';
     $user->city = 'Perth';
     $user->country = 'AU';
     user_update_user($user, false);
     // Disable email message processor.
     $DB->set_field('message_processors', 'enabled', '0', array('name' => 'email'));
     // Sets maximum debug level.
     set_config('debug', DEBUG_DEVELOPER);
     set_config('debugdisplay', true);
     // Keeps the current version of database and dataroot.
     self::store_versions_hash();
     // Stores the database contents for fast reset.
     self::store_database_state();
 }
 /**
  * Install a site using $CFG->dataroot and $CFG->prefix
  *
  * @return string|bool true on success, else exception code.
  */
 public static function install_site($sitefullname = "Performance test site", $siteshortname = "Performance test site", $adminpass = "******", $adminemail = "*****@*****.**")
 {
     global $DB, $CFG;
     require_once $CFG->dirroot . '/user/lib.php';
     if (!defined('PERFORMANCE_SITE_GENERATOR')) {
         util::performance_exception('This method can be only used by performance site generator.');
     }
     // If already installed, then return with error.
     $tables = $DB->get_tables(false);
     if (!empty($tables)) {
         return self::SITE_ERROR_INSTALLED;
     }
     $options = array();
     $options['adminuser'] = '******';
     $options['adminpass'] = $adminpass;
     $options['fullname'] = $sitefullname;
     $options['shortname'] = $siteshortname;
     install_cli_database($options, false);
     $frontpagesummary = new \admin_setting_special_frontpagedesc();
     $frontpagesummary->write_setting($sitefullname);
     // Update admin user info.
     $user = $DB->get_record('user', array('username' => 'admin'));
     $user->email = $adminemail;
     $user->firstname = 'Admin';
     $user->lastname = 'User';
     $user->city = 'Perth';
     $user->country = 'AU';
     user_update_user($user, false);
     // Disable email message processor.
     $DB->set_field('message_processors', 'enabled', '0', array('name' => 'email'));
     // Disable some settings that are not wanted on test sites.
     set_config('noemailever', 1);
     // Enable web cron.
     set_config('cronclionly', 0);
     $CFG->dboptions = array('dbpersist' => 1);
     // Keeps the current version of components hash.
     self::store_versions_hash();
 }
Example #4
0
             if ($user = $DB->get_record('user', array('id' => $suspend, 'mnethostid' => $CFG->mnet_localhost_id, 'deleted' => 0))) {
                 if (!is_siteadmin($user) and $USER->id != $user->id and $user->suspended != 1) {
                     $user->suspended = 1;
                     // Force logout.
                     \core\session\manager::kill_user_sessions($user->id);
                     user_update_user($user, false);
                 }
             }
             redirect($returnurl);
         } else {
             if ($unsuspend and confirm_sesskey()) {
                 require_capability('moodle/user:update', $sitecontext);
                 if ($user = $DB->get_record('user', array('id' => $unsuspend, 'mnethostid' => $CFG->mnet_localhost_id, 'deleted' => 0))) {
                     if ($user->suspended != 0) {
                         $user->suspended = 0;
                         user_update_user($user, false);
                     }
                 }
                 redirect($returnurl);
             } else {
                 if ($unlock and confirm_sesskey()) {
                     require_capability('moodle/user:update', $sitecontext);
                     if ($user = $DB->get_record('user', array('id' => $unlock, 'mnethostid' => $CFG->mnet_localhost_id, 'deleted' => 0))) {
                         login_unlock_account($user);
                     }
                     redirect($returnurl);
                 }
             }
         }
     }
 }
Example #5
0
 /**
  * Performs the synchronisation of members.
  *
  * @return bool|void
  */
 public function execute()
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . '/enrol/lti/ims-blti/OAuth.php';
     require_once $CFG->dirroot . '/enrol/lti/ims-blti/OAuthBody.php';
     // Check if the authentication plugin is disabled.
     if (!is_enabled_auth('lti')) {
         mtrace('Skipping task - ' . get_string('pluginnotenabled', 'auth', get_string('pluginname', 'auth_lti')));
         return true;
     }
     // Check if the enrolment plugin is disabled - isn't really necessary as the task should not run if
     // the plugin is disabled, but there is no harm in making sure core hasn't done something wrong.
     if (!enrol_is_enabled('lti')) {
         mtrace('Skipping task - ' . get_string('enrolisdisabled', 'enrol_lti'));
         return true;
     }
     // Get all the enabled tools.
     if ($tools = \enrol_lti\helper::get_lti_tools(array('status' => ENROL_INSTANCE_ENABLED, 'membersync' => 1))) {
         $ltiplugin = enrol_get_plugin('lti');
         $consumers = array();
         $currentusers = array();
         $userphotos = array();
         foreach ($tools as $tool) {
             mtrace("Starting - Member sync for shared tool '{$tool->id}' for the course '{$tool->courseid}'.");
             // Variables to keep track of information to display later.
             $usercount = 0;
             $enrolcount = 0;
             $unenrolcount = 0;
             // We check for all the users - users can access the same tool from different consumers.
             if ($ltiusers = $DB->get_records('enrol_lti_users', array('toolid' => $tool->id), 'lastaccess DESC')) {
                 foreach ($ltiusers as $ltiuser) {
                     $mtracecontent = "for the user '{$ltiuser->userid}' in the tool '{$tool->id}' for the course " . "'{$tool->courseid}'";
                     $usercount++;
                     // Check if we do not have a membershipsurl - this can happen if the sync process has an unexpected error.
                     if (!$ltiuser->membershipsurl) {
                         mtrace("Skipping - Empty membershipsurl {$mtracecontent}.");
                         continue;
                     }
                     // Check if we do not have a membershipsid - this can happen if the sync process has an unexpected error.
                     if (!$ltiuser->membershipsid) {
                         mtrace("Skipping - Empty membershipsid {$mtracecontent}.");
                         continue;
                     }
                     $consumer = sha1($ltiuser->membershipsurl . ':' . $ltiuser->membershipsid . ':' . $ltiuser->consumerkey . ':' . $ltiuser->consumersecret);
                     if (in_array($consumer, $consumers)) {
                         // We have already synchronised with this consumer.
                         continue;
                     }
                     $consumers[] = $consumer;
                     $params = array('lti_message_type' => self::LTI_MESSAGE_TYPE, 'id' => $ltiuser->membershipsid, 'lti_version' => self::LTI_VERSION);
                     mtrace("Calling memberships url '{$ltiuser->membershipsurl}' with body '" . json_encode($params) . "'");
                     try {
                         $response = sendOAuthParamsPOST('POST', $ltiuser->membershipsurl, $ltiuser->consumerkey, $ltiuser->consumersecret, 'application/x-www-form-urlencoded', $params);
                     } catch (\Exception $e) {
                         mtrace("Skipping - No response received {$mtracecontent} from '{$ltiuser->membershipsurl}'");
                         mtrace($e->getMessage());
                         continue;
                     }
                     // Check the response from the consumer.
                     $data = new \SimpleXMLElement($response);
                     // Check if we did not receive a valid response.
                     if (empty($data->statusinfo)) {
                         mtrace("Skipping - Bad response received {$mtracecontent} from '{$ltiuser->membershipsurl}'");
                         mtrace('Skipping - Error parsing the XML received \'' . substr($response, 0, 125) . '\' ... (Displaying only 125 chars)');
                         continue;
                     }
                     // Check if we did not receive a valid response.
                     if (strpos(strtolower($data->statusinfo->codemajor), 'success') === false) {
                         mtrace('Skipping - Error received from the remote system: ' . $data->statusinfo->codemajor . ' ' . $data->statusinfo->severity . ' ' . $data->statusinfo->codeminor);
                         continue;
                     }
                     $members = $data->memberships->member;
                     mtrace(count($members) . ' members received.');
                     foreach ($members as $member) {
                         // Set the user data.
                         $user = new \stdClass();
                         $user->username = \enrol_lti\helper::create_username($ltiuser->consumerkey, $member->user_id);
                         $user->firstname = \core_user::clean_field($member->person_name_given, 'firstname');
                         $user->lastname = \core_user::clean_field($member->person_name_family, 'lastname');
                         $user->email = \core_user::clean_field($member->person_contact_email_primary, 'email');
                         // Get the user data from the LTI consumer.
                         $user = \enrol_lti\helper::assign_user_tool_data($tool, $user);
                         if (!($dbuser = $DB->get_record('user', array('username' => $user->username, 'deleted' => 0)))) {
                             if ($tool->membersyncmode == \enrol_lti\helper::MEMBER_SYNC_ENROL_AND_UNENROL || $tool->membersyncmode == \enrol_lti\helper::MEMBER_SYNC_ENROL_NEW) {
                                 // If the email was stripped/not set then fill it with a default one. This
                                 // stops the user from being redirected to edit their profile page.
                                 if (empty($user->email)) {
                                     $user->email = $user->username . "@example.com";
                                 }
                                 $user->auth = 'lti';
                                 $user->id = user_create_user($user);
                                 // Add the information to the necessary arrays.
                                 $currentusers[] = $user->id;
                                 $userphotos[$user->id] = $member->user_image;
                             }
                         } else {
                             // If email is empty remove it, so we don't update the user with an empty email.
                             if (empty($user->email)) {
                                 unset($user->email);
                             }
                             $user->id = $dbuser->id;
                             user_update_user($user);
                             // Add the information to the necessary arrays.
                             $currentusers[] = $user->id;
                             $userphotos[$user->id] = $member->user_image;
                         }
                         if ($tool->membersyncmode == \enrol_lti\helper::MEMBER_SYNC_ENROL_AND_UNENROL || $tool->membersyncmode == \enrol_lti\helper::MEMBER_SYNC_ENROL_NEW) {
                             // Enrol the user in the course.
                             \enrol_lti\helper::enrol_user($tool, $user->id);
                         }
                     }
                 }
                 // Now we check if we have to unenrol users who were not listed.
                 if ($tool->membersyncmode == \enrol_lti\helper::MEMBER_SYNC_ENROL_AND_UNENROL || $tool->membersyncmode == \enrol_lti\helper::MEMBER_SYNC_UNENROL_MISSING) {
                     // Go through the users and check if any were never listed, if so, remove them.
                     foreach ($ltiusers as $ltiuser) {
                         if (!in_array($ltiuser->userid, $currentusers)) {
                             $instance = new \stdClass();
                             $instance->id = $tool->enrolid;
                             $instance->courseid = $tool->courseid;
                             $instance->enrol = 'lti';
                             $ltiplugin->unenrol_user($instance, $ltiuser->id);
                         }
                     }
                 }
             }
             mtrace("Completed - Synced members for tool '{$tool->id}' in the course '{$tool->courseid}'. " . "Processed {$usercount} users; enrolled {$enrolcount} members; unenrolled {$unenrolcount} members.");
             mtrace("");
         }
         // Sync the user profile photos.
         mtrace("Started - Syncing user profile images.");
         $counter = 0;
         if (!empty($userphotos)) {
             foreach ($userphotos as $userid => $url) {
                 if ($url) {
                     $result = \enrol_lti\helper::update_user_profile_image($userid, $url);
                     if ($result === \enrol_lti\helper::PROFILE_IMAGE_UPDATE_SUCCESSFUL) {
                         $counter++;
                         mtrace("Profile image succesfully downloaded and created for user '{$userid}' from {$url}.");
                     } else {
                         mtrace($result);
                     }
                 }
             }
         }
         mtrace("Completed - Synced {$counter} profile images.");
     }
 }
Example #6
0
 /**
  * Installs a site using $CFG->dataroot and $CFG->prefix
  * @throws coding_exception
  * @return void
  */
 public static function install_site()
 {
     global $DB, $CFG;
     require_once $CFG->dirroot . '/user/lib.php';
     if (!defined('BEHAT_UTIL')) {
         throw new coding_exception('This method can be only used by Behat CLI tool');
     }
     $tables = $DB->get_tables(false);
     if (!empty($tables)) {
         behat_error(BEHAT_EXITCODE_INSTALLED);
     }
     // New dataroot.
     self::reset_dataroot();
     $options = array();
     $options['adminuser'] = '******';
     $options['adminpass'] = '******';
     $options['fullname'] = self::BEHATSITENAME;
     $options['shortname'] = self::BEHATSITENAME;
     install_cli_database($options, false);
     // We need to keep the installed dataroot filedir files.
     // So each time we reset the dataroot before running a test, the default files are still installed.
     self::save_original_data_files();
     $frontpagesummary = new admin_setting_special_frontpagedesc();
     $frontpagesummary->write_setting(self::BEHATSITENAME);
     // Update admin user info.
     $user = $DB->get_record('user', array('username' => 'admin'));
     $user->email = '*****@*****.**';
     $user->firstname = 'Admin';
     $user->lastname = 'User';
     $user->city = 'Perth';
     $user->country = 'AU';
     user_update_user($user, false);
     // Disable email message processor.
     $DB->set_field('message_processors', 'enabled', '0', array('name' => 'email'));
     // Sets maximum debug level.
     set_config('debug', DEBUG_DEVELOPER);
     set_config('debugdisplay', 1);
     // Disable some settings that are not wanted on test sites.
     set_config('noemailever', 1);
     // Enable web cron.
     set_config('cronclionly', 0);
     // Keeps the current version of database and dataroot.
     self::store_versions_hash();
     // Stores the database contents for fast reset.
     self::store_database_state();
 }
Example #7
0
                 // Use a low cost factor when generating bcrypt hash otherwise
                 // hashing would be slow when uploading lots of users. Hashes
                 // will be automatically updated to a higher cost factor the first
                 // time the user logs in.
                 $existinguser->password = hash_internal_user_password($user->password, true);
                 $upt->track('password', $user->password, 'normal', false);
             } else {
                 // do not print password when not changed
                 $upt->track('password', '', 'normal', false);
             }
         }
     }
 }
 if ($doupdate or $existinguser->password !== $oldpw) {
     // We want only users that were really updated.
     user_update_user($existinguser, false, false);
     $upt->track('status', $struserupdated);
     $usersupdated++;
     if (!$remoteuser) {
         // pre-process custom profile menu fields data from csv file
         $existinguser = uu_pre_process_custom_profile_data($existinguser);
         // save custom profile fields data from csv file
         profile_save_data($existinguser);
     }
     if ($bulk == UU_BULK_UPDATED or $bulk == UU_BULK_ALL) {
         if (!in_array($user->id, $SESSION->bulk_users)) {
             $SESSION->bulk_users[] = $user->id;
         }
     }
     // Trigger event.
     \core\event\user_updated::create_from_userid($existinguser->id)->trigger();
Example #8
0
 /**
  * Update users
  *
  * @param array $users
  * @return null
  * @since Moodle 2.2
  */
 public static function update_users($users)
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . "/user/lib.php";
     require_once $CFG->dirroot . "/user/profile/lib.php";
     //required for customfields related function
     // Ensure the current user is allowed to run this function
     $context = context_system::instance();
     require_capability('moodle/user:update', $context);
     self::validate_context($context);
     $params = self::validate_parameters(self::update_users_parameters(), array('users' => $users));
     $transaction = $DB->start_delegated_transaction();
     foreach ($params['users'] as $user) {
         if (empty($user['country'])) {
             //Allowing empty country leads to login issues. Let's not allow such updates
             continue;
         }
         user_update_user($user);
         //update user custom fields
         if (!empty($user['customfields'])) {
             foreach ($user['customfields'] as $customfield) {
                 $user["profile_field_" . $customfield['type']] = $customfield['value'];
                 //profile_save_data() saves profile file
                 //it's expecting a user with the correct id,
                 //and custom field to be named profile_field_"shortname"
             }
             profile_save_data((object) $user);
             events_trigger('user_updated', (object) $user);
         }
         //preferences
         if (!empty($user['preferences'])) {
             foreach ($user['preferences'] as $preference) {
                 set_user_preference($preference['type'], $preference['value'], $user['id']);
             }
         }
     }
     $transaction->allow_commit();
     return null;
 }
Example #9
0
         $user->email = $user->username . "@example.com";
     }
     $user->auth = 'lti';
     $user->id = user_create_user($user);
     // Get the updated user record.
     $user = $DB->get_record('user', array('id' => $user->id));
 } else {
     if (\enrol_lti\helper::user_match($user, $dbuser)) {
         $user = $dbuser;
     } else {
         // If email is empty remove it, so we don't update the user with an empty email.
         if (empty($user->email)) {
             unset($user->email);
         }
         $user->id = $dbuser->id;
         user_update_user($user);
         // Get the updated user record.
         $user = $DB->get_record('user', array('id' => $user->id));
     }
 }
 // Update user image.
 $image = false;
 if (!empty($ltirequest->info['user_image'])) {
     $image = $ltirequest->info['user_image'];
 } else {
     if (!empty($ltirequest->info['custom_user_image'])) {
         $image = $ltirequest->info['custom_user_image'];
     }
 }
 // Check if there is an image to process.
 if ($image) {
Example #10
0
  * 1. Update user profile.
  * 2. Save request data into request table.
  * 3. Take the user to the list of request and pass the message if the request was made
  *    successfully.
  */
 $profile = new stdClass();
 $profile->id = $USER->id;
 $profile->firstname = $fromform->firstname;
 $profile->lastname = $fromform->lastname;
 $profile->email = $fromform->email;
 $profile->country = $fromform->country;
 $profile->city = $fromform->city;
 $profile->address = $fromform->address;
 $profile->phone1 = $fromform->phone1;
 // Update user.
 user_update_user($profile, false, true);
 // Reload from db.
 $user = $DB->get_record('user', array('id' => $profile->id), '*', MUST_EXIST);
 // Override old $USER session variable if needed.
 if ($USER->id == $user->id) {
     // Override old $USER session variable if needed.
     foreach ((array) $user as $variable => $value) {
         if ($variable === 'description' or $variable === 'password') {
             // These are not set for security nad perf reasons.
             continue;
         }
         $USER->{$variable} = $value;
     }
 }
 $today = time();
 $request = new stdClass();
Example #11
0
 /**
  * Update users
  *
  * @param array $users
  * @return null
  * @since Moodle 2.2
  */
 public static function update_users($users)
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . "/user/lib.php";
     require_once $CFG->dirroot . "/user/profile/lib.php";
     // Required for customfields related function.
     // Ensure the current user is allowed to run this function.
     $context = context_system::instance();
     require_capability('moodle/user:update', $context);
     self::validate_context($context);
     $params = self::validate_parameters(self::update_users_parameters(), array('users' => $users));
     $filemanageroptions = array('maxbytes' => $CFG->maxbytes, 'subdirs' => 0, 'maxfiles' => 1, 'accepted_types' => 'web_image');
     $transaction = $DB->start_delegated_transaction();
     foreach ($params['users'] as $user) {
         user_update_user($user, true, false);
         // Update user picture if it was specified for this user.
         if (empty($CFG->disableuserimages) && isset($user['userpicture'])) {
             $userobject = (object) $user;
             $userobject->deletepicture = null;
             if ($user['userpicture'] == 0) {
                 $userobject->deletepicture = true;
             } else {
                 $userobject->imagefile = $user['userpicture'];
             }
             core_user::update_picture($userobject, $filemanageroptions);
         }
         // Update user custom fields.
         if (!empty($user['customfields'])) {
             foreach ($user['customfields'] as $customfield) {
                 // Profile_save_data() saves profile file it's expecting a user with the correct id,
                 // and custom field to be named profile_field_"shortname".
                 $user["profile_field_" . $customfield['type']] = $customfield['value'];
             }
             profile_save_data((object) $user);
         }
         // Trigger event.
         \core\event\user_updated::create_from_userid($user['id'])->trigger();
         // Preferences.
         if (!empty($user['preferences'])) {
             foreach ($user['preferences'] as $preference) {
                 set_user_preference($preference['type'], $preference['value'], $user['id']);
             }
         }
     }
     $transaction->allow_commit();
     return null;
 }
/**
 * Create one or more users
 *
 * @param array $users  An array of users to create.
 * @return array An array of arrays
 */
function create_users($users)
{
    global $CFG, $DB;
    require_once $CFG->dirroot . "/user/lib.php";
    require_once $CFG->dirroot . "/user/profile/lib.php";
    //required for customfields related function
    //TODO: move the functions somewhere else as
    //they are "user" related
    $availableauths = get_plugin_list('auth');
    $availablethemes = get_plugin_list('theme');
    $availablelangs = get_string_manager()->get_list_of_translations();
    $transaction = $DB->start_delegated_transaction();
    $userids = array();
    foreach ($users as $user) {
        // Make sure that the username doesn't already exist
        if ($DB->record_exists('user', array('username' => $user['username'], 'mnethostid' => $CFG->mnet_localhost_id))) {
            //            $userids[] = array('id' => $user['id'], 'username' => $user['username'], 'error'=>'Username already exists: ' . $user['username']);
            $user_rec = $DB->get_record('user', array('username' => $user['username']));
            $user['id'] = $user_rec->id;
            unset($user['password']);
            unset($user['auth']);
            user_update_user($user);
            $userids[] = array('id' => $user['id'], 'username' => $user['username'], 'error' => 'Updated');
            continue;
        }
        // Make sure auth is valid
        if (empty($availableauths[$user['auth']])) {
            $userids[] = array('id' => $user['id'], 'username' => $user['username'], 'error' => 'Invalid authentication type: ' . $user['auth']);
            continue;
        }
        // Make sure lang is valid
        if (empty($availablelangs[$user['lang']])) {
            $userids[] = array('id' => $user['id'], 'username' => $user['username'], 'error' => 'Invalid language code: ' . $user['lang']);
            continue;
        }
        // Make sure lang is valid
        if (!empty($user['theme']) && empty($availablethemes[$user['theme']])) {
            //theme is VALUE_OPTIONAL,
            // so no default value.
            // We need to test if the client sent it
            // => !empty($user['theme'])
            $userids[] = array('id' => $user['id'], 'username' => $user['username'], 'error' => 'Invalid theme: ' . $user['theme']);
            continue;
        }
        // make sure there is no data loss during truncation
        $truncated = truncate_userinfo($user);
        foreach ($truncated as $key => $value) {
            if ($truncated[$key] !== $user[$key]) {
                $userids[] = array('id' => $user['id'], 'username' => $user['username'], 'error' => 'Property: ' . $key . ' is too long: ' . $user[$key]);
                continue;
            }
        }
        $user['confirmed'] = true;
        $user['mnethostid'] = $CFG->mnet_localhost_id;
        $user['id'] = user_create_user($user);
        //        // custom fields
        //        if (!empty($user['customfields'])) {
        //            foreach ($user['customfields'] as $customfield) {
        //                $user["profile_field_" . $customfield['type']] = $customfield['value']; //profile_save_data() saves profile file
        //                //it's expecting a user with the correct id,
        //                //and custom field to be named profile_field_"shortname"
        //            }
        //            profile_save_data((object)$user);
        //        }
        //
        //        //preferences
        //        if (!empty($user['preferences'])) {
        //            foreach ($user['preferences'] as $preference) {
        //                set_user_preference($preference['type'], $preference['value'], $user['id']);
        //            }
        //        }
        $userids[] = array('id' => $user['id'], 'username' => $user['username'], 'error' => "");
    }
    $transaction->allow_commit();
    return $userids;
}
Example #13
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();
     }
 }
 /**
  * Update details for the current user
  * Password is passed in plaintext.
  *
  * @param object $user current user object
  * @param boolean $notify print notice with link and terminate
  */
 public function user_update_details($user)
 {
     global $CFG, $DB, $USER;
     require_once $CFG->dirroot . '/user/profile/lib.php';
     require_once $CFG->dirroot . '/user/lib.php';
     if ($user->password == $user->confirmpassword and !empty($user->password)) {
         $plainpassword = $user->password;
         echo $plainpassword;
         $user->password = hash_internal_user_password($user->password);
         $this->user_update_password($user, $user->password);
         user_add_password_history($user->id, $plainpassword);
     }
     if (empty($user->calendartype)) {
         $user->calendartype = $CFG->calendartype;
     }
     try {
         $transaction = $DB->start_delegated_transaction();
         user_update_user($user, false, false);
         $user->profile_field_yearlevel = empty($user->profile_field_yearlevel) ? 'N/A' : $user->profile_field_yearlevel;
         $user->profile_field_yearofbirth = empty($user->profile_field_yearofbirth) ? 'N/A' : $user->profile_field_yearofbirth;
         $user->profile_field_whereareyoufrom = empty($user->profile_field_whereareyoufrom) ? 'Perth' : $user->profile_field_whereareyoufrom;
         $USER->profile['yearlevel'] = $user->profile_field_yearlevel;
         $USER->profile['yearofbirth'] = $user->profile_field_yearofbirth;
         $USER->profile['whereareyoufrom'] = $user->profile_field_whereareyoufrom;
         profile_save_data($user);
         // Trigger event.
         \core\event\user_updated::create_from_userid($user->id)->trigger();
         // Assuming the both inserts work, we get to the following line.
         $transaction->allow_commit();
     } catch (Exception $e) {
         $transaction->rollback($e);
         return false;
     }
     return $this->update_user_session($user);
 }
Example #15
0
 /**
  * Override onLaunch with tool logic.
  * @return void
  */
 protected function onLaunch()
 {
     global $DB, $SESSION, $CFG;
     // Check for valid consumer.
     if (empty($this->consumer) || $this->dataConnector->loadToolConsumer($this->consumer) === false) {
         $this->ok = false;
         $this->message = get_string('invalidtoolconsumer', 'enrol_lti');
         return;
     }
     $url = helper::get_launch_url($this->tool->id);
     // If a tool proxy has been stored for the current consumer trying to access a tool,
     // check that the tool is being launched from the correct url.
     $correctlaunchurl = false;
     if (!empty($this->consumer->toolProxy)) {
         $proxy = json_decode($this->consumer->toolProxy);
         $handlers = $proxy->tool_profile->resource_handler;
         foreach ($handlers as $handler) {
             foreach ($handler->message as $message) {
                 $handlerurl = new moodle_url($message->path);
                 $fullpath = $handlerurl->out(false);
                 if ($message->message_type == "basic-lti-launch-request" && $fullpath == $url) {
                     $correctlaunchurl = true;
                     break 2;
                 }
             }
         }
     } else {
         if ($this->tool->secret == $this->consumer->secret) {
             // Test if the LTI1 secret for this tool is being used. Then we know the correct tool is being launched.
             $correctlaunchurl = true;
         }
     }
     if (!$correctlaunchurl) {
         $this->ok = false;
         $this->message = get_string('invalidrequest', 'enrol_lti');
         return;
     }
     // Before we do anything check that the context is valid.
     $tool = $this->tool;
     $context = context::instance_by_id($tool->contextid);
     // Set the user data.
     $user = new stdClass();
     $user->username = helper::create_username($this->consumer->getKey(), $this->user->ltiUserId);
     if (!empty($this->user->firstname)) {
         $user->firstname = $this->user->firstname;
     } else {
         $user->firstname = $this->user->getRecordId();
     }
     if (!empty($this->user->lastname)) {
         $user->lastname = $this->user->lastname;
     } else {
         $user->lastname = $this->tool->contextid;
     }
     $user->email = core_user::clean_field($this->user->email, 'email');
     // Get the user data from the LTI consumer.
     $user = helper::assign_user_tool_data($tool, $user);
     // Check if the user exists.
     if (!($dbuser = $DB->get_record('user', ['username' => $user->username, 'deleted' => 0]))) {
         // If the email was stripped/not set then fill it with a default one. This
         // stops the user from being redirected to edit their profile page.
         if (empty($user->email)) {
             $user->email = $user->username . "@example.com";
         }
         $user->auth = 'lti';
         $user->id = \user_create_user($user);
         // Get the updated user record.
         $user = $DB->get_record('user', ['id' => $user->id]);
     } else {
         if (helper::user_match($user, $dbuser)) {
             $user = $dbuser;
         } else {
             // If email is empty remove it, so we don't update the user with an empty email.
             if (empty($user->email)) {
                 unset($user->email);
             }
             $user->id = $dbuser->id;
             \user_update_user($user);
             // Get the updated user record.
             $user = $DB->get_record('user', ['id' => $user->id]);
         }
     }
     // Update user image.
     if (isset($this->user) && isset($this->user->image) && !empty($this->user->image)) {
         $image = $this->user->image;
     } else {
         // Use custom_user_image parameter as a fallback.
         $image = $this->resourceLink->getSetting('custom_user_image');
     }
     // Check if there is an image to process.
     if ($image) {
         helper::update_user_profile_image($user->id, $image);
     }
     // Check if we need to force the page layout to embedded.
     $isforceembed = $this->resourceLink->getSetting('custom_force_embed') == 1;
     // Check if we are an instructor.
     $isinstructor = $this->user->isStaff() || $this->user->isAdmin();
     if ($context->contextlevel == CONTEXT_COURSE) {
         $courseid = $context->instanceid;
         $urltogo = new moodle_url('/course/view.php', ['id' => $courseid]);
     } else {
         if ($context->contextlevel == CONTEXT_MODULE) {
             $cm = get_coursemodule_from_id(false, $context->instanceid, 0, false, MUST_EXIST);
             $urltogo = new moodle_url('/mod/' . $cm->modname . '/view.php', ['id' => $cm->id]);
             // If we are a student in the course module context we do not want to display blocks.
             if (!$isforceembed && !$isinstructor) {
                 $isforceembed = true;
             }
         } else {
             print_error('invalidcontext');
             exit;
         }
     }
     // Force page layout to embedded if necessary.
     if ($isforceembed) {
         $SESSION->forcepagelayout = 'embedded';
     } else {
         // May still be set from previous session, so unset it.
         unset($SESSION->forcepagelayout);
     }
     // Enrol the user in the course with no role.
     $result = helper::enrol_user($tool, $user->id);
     // Display an error, if there is one.
     if ($result !== helper::ENROLMENT_SUCCESSFUL) {
         print_error($result, 'enrol_lti');
         exit;
     }
     // Give the user the role in the given context.
     $roleid = $isinstructor ? $tool->roleinstructor : $tool->rolelearner;
     role_assign($roleid, $user->id, $tool->contextid);
     // Login user.
     $sourceid = $this->user->ltiResultSourcedId;
     $serviceurl = $this->resourceLink->getSetting('lis_outcome_service_url');
     // Check if we have recorded this user before.
     if ($userlog = $DB->get_record('enrol_lti_users', ['toolid' => $tool->id, 'userid' => $user->id])) {
         if ($userlog->sourceid != $sourceid) {
             $userlog->sourceid = $sourceid;
         }
         if ($userlog->serviceurl != $serviceurl) {
             $userlog->serviceurl = $serviceurl;
         }
         $userlog->lastaccess = time();
         $DB->update_record('enrol_lti_users', $userlog);
     } else {
         // Add the user details so we can use it later when syncing grades and members.
         $userlog = new stdClass();
         $userlog->userid = $user->id;
         $userlog->toolid = $tool->id;
         $userlog->serviceurl = $serviceurl;
         $userlog->sourceid = $sourceid;
         $userlog->consumerkey = $this->consumer->getKey();
         $userlog->consumersecret = $tool->secret;
         $userlog->lastgrade = 0;
         $userlog->lastaccess = time();
         $userlog->timecreated = time();
         $userlog->membershipsurl = $this->resourceLink->getSetting('ext_ims_lis_memberships_url');
         $userlog->membershipsid = $this->resourceLink->getSetting('ext_ims_lis_memberships_id');
         $DB->insert_record('enrol_lti_users', $userlog);
     }
     // Finalise the user log in.
     complete_user_login($user);
     // Everything's good. Set appropriate OK flag and message values.
     $this->ok = true;
     $this->message = get_string('success');
     if (empty($CFG->allowframembedding)) {
         // Provide an alternative link.
         $stropentool = get_string('opentool', 'enrol_lti');
         echo html_writer::tag('p', get_string('frameembeddingnotenabled', 'enrol_lti'));
         echo html_writer::link($urltogo, $stropentool, ['target' => '_blank']);
     } else {
         // All done, redirect the user to where they want to go.
         redirect($urltogo);
     }
 }
Example #16
0
    public static function update_users($users) {
        global $CFG, $DB;
        require_once($CFG->dirroot."/user/lib.php");
        require_once($CFG->dirroot."/user/profile/lib.php"); //required for customfields related function
                                                             //TODO: move the functions somewhere else as
                                                             //they are "user" related

        // Ensure the current user is allowed to run this function
        $context = get_context_instance(CONTEXT_SYSTEM);
        require_capability('moodle/user:update', $context);
        self::validate_context($context);

        $params = self::validate_parameters(self::update_users_parameters(), array('users'=>$users));

        $transaction = $DB->start_delegated_transaction();

        foreach ($params['users'] as $user) {
            user_update_user($user);
            //update user custom fields
            if(!empty($user['customfields'])) {

                foreach($user['customfields'] as $customfield) {
                    $user["profile_field_".$customfield['type']] = $customfield['value']; //profile_save_data() saves profile file
                                                                                            //it's expecting a user with the correct id,
                                                                                            //and custom field to be named profile_field_"shortname"
                }
                profile_save_data((object) $user);
            }

            //preferences
            if (!empty($user['preferences'])) {
                foreach($user['preferences'] as $preference) {
                    set_user_preference($preference['type'], $preference['value'],$user['id']);
                }
            }
        }

        $transaction->allow_commit();

        return null;
    }
 /**
  * Update users
  *
  * @param array $users
  * @return null
  * @since Moodle 2.2
  */
 public static function update_users($users)
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . "/user/lib.php";
     require_once $CFG->dirroot . "/user/profile/lib.php";
     // Required for customfields related function.
     // Ensure the current user is allowed to run this function.
     $context = context_system::instance();
     require_capability('moodle/user:update', $context);
     self::validate_context($context);
     $params = self::validate_parameters(self::update_users_parameters(), array('users' => $users));
     $transaction = $DB->start_delegated_transaction();
     foreach ($params['users'] as $user) {
         user_update_user($user, true, false);
         // Update user custom fields.
         if (!empty($user['customfields'])) {
             foreach ($user['customfields'] as $customfield) {
                 // Profile_save_data() saves profile file it's expecting a user with the correct id,
                 // and custom field to be named profile_field_"shortname".
                 $user["profile_field_" . $customfield['type']] = $customfield['value'];
             }
             profile_save_data((object) $user);
         }
         // Trigger event.
         \core\event\user_updated::create_from_userid($user['id'])->trigger();
         // Preferences.
         if (!empty($user['preferences'])) {
             foreach ($user['preferences'] as $preference) {
                 set_user_preference($preference['type'], $preference['value'], $user['id']);
             }
         }
     }
     $transaction->allow_commit();
     return null;
 }
 /**
  * Proceed with the import of the user.
  *
  * @return void
  */
 public function proceed()
 {
     if (!$this->prepared) {
         throw new coding_exception('The course has not been prepared.');
     } else {
         if ($this->has_errors()) {
             throw new moodle_exception('Cannot proceed, errors were detected.');
         } else {
             if ($this->processstarted) {
                 throw new coding_exception('The process has already been started.');
             }
         }
     }
     $this->processstarted = true;
     if ($this->do === self::DO_DELETE) {
         $this->finaldata = $this->existing;
         try {
             $success = delete_user($this->existing);
         } catch (moodle_exception $e) {
             $success = false;
         }
         if (!$success) {
             $this->error('usernotdeletederror', new lang_string('usernotdeletederror', 'tool_uploadusercli'));
             return false;
         }
         $this->set_status('userdeleted', new lang_string('userdeleted', 'tool_uploaduser'));
         return true;
     } else {
         if ($this->do === self::DO_CREATE) {
             try {
                 $this->finaldata->id = user_create_user($this->finaldata, false, false);
             } catch (Exception $e) {
                 $this->error('errorcreatinguser', new lang_string('errorcreatinguser', 'tool_uploadusercli'));
                 return false;
             }
             if ($this->needpasswordchange) {
                 set_user_preference('auth_forcepasswordchange', 1, $this->finaldata);
                 $this->set_status('forcepasswordchange', new lang_string('forcepasswordchange', 'tool_uploadusercli'));
             }
             if ($this->finaldata->password === 'to be generated') {
                 set_user_preference('create_password', 1, $this->finaldata);
             }
             $this->set_status('useradded', new lang_string('newuser'));
         } else {
             if ($this->do === self::DO_UPDATE) {
                 try {
                     user_update_user($this->finaldata, false, false);
                 } catch (Exception $e) {
                     $this->error('usernotupdatederror', new lang_string('usernotupdatederror', 'error'));
                     return false;
                 }
                 if ($this->dologout) {
                     \core\session\manager::kill_user_sessions($this->finaldata->id);
                 }
                 $this->set_status('useraccountupdated', new lang_string('useraccountupdated', 'tool_uploaduser'));
             }
         }
     }
     if ($this->do === self::DO_UPDATE || $this->do === self::DO_CREATE) {
         if (!$this->isremote) {
             $this->finaldata = uu_pre_process_custom_profile_data($this->finaldata);
             profile_save_data($this->finaldata);
         }
         $success = $this->add_to_cohort();
         $success = $success && $this->add_to_egr();
         if (!$success) {
             return false;
         }
     }
     return true;
 }
Example #19
0
 /**
  * will update a local user record from an external source.
  * is a lighter version of the one in moodlelib -- won't do
  * expensive ops such as enrolment.
  *
  * If you don't pass $updatekeys, there is a performance hit and
  * values removed from DB won't be removed from moodle.
  *
  * @param string $username username
  * @param bool $updatekeys
  * @return stdClass
  */
 function update_user_record($username, $updatekeys = false)
 {
     global $CFG, $DB;
     //just in case check text case
     $username = trim(core_text::strtolower($username));
     // get the current user record
     $user = $DB->get_record('user', array('username' => $username, 'mnethostid' => $CFG->mnet_localhost_id));
     if (empty($user)) {
         // trouble
         error_log("Cannot update non-existent user: {$username}");
         print_error('auth_dbusernotexist', 'auth_db', $username);
         die;
     }
     // Ensure userid is not overwritten.
     $userid = $user->id;
     $needsupdate = false;
     $updateuser = new stdClass();
     $updateuser->id = $userid;
     if ($newinfo = $this->get_userinfo($username)) {
         $newinfo = truncate_userinfo($newinfo);
         if (empty($updatekeys)) {
             // All keys? This does not support removing values.
             $updatekeys = array_keys($newinfo);
         }
         foreach ($updatekeys as $key) {
             if (isset($newinfo[$key])) {
                 $value = $newinfo[$key];
             } else {
                 $value = '';
             }
             if (!empty($this->config->{'field_updatelocal_' . $key})) {
                 if (isset($user->{$key}) and $user->{$key} != $value) {
                     // Only update if it's changed.
                     $needsupdate = true;
                     $updateuser->{$key} = $value;
                 }
             }
         }
     }
     if ($needsupdate) {
         require_once $CFG->dirroot . '/user/lib.php';
         user_update_user($updateuser);
     }
     return $DB->get_record('user', array('id' => $userid, 'deleted' => 0));
 }
Example #20
0
 /**
  * This function confirms the remote (ID provider) host's mnet session
  * by communicating the token and UA over the XMLRPC transport layer, and
  * returns the local user record on success.
  *
  *   @param string    $token           The random session token.
  *   @param mnet_peer $remotepeer   The ID provider mnet_peer object.
  *   @return array The local user record.
  */
 function confirm_mnet_session($token, $remotepeer)
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
     require_once $CFG->libdir . '/gdlib.php';
     require_once $CFG->dirroot . '/user/lib.php';
     // verify the remote host is configured locally before attempting RPC call
     if (!($remotehost = $DB->get_record('mnet_host', array('wwwroot' => $remotepeer->wwwroot, 'deleted' => 0)))) {
         print_error('notpermittedtoland', 'mnet');
     }
     // set up the RPC request
     $mnetrequest = new mnet_xmlrpc_client();
     $mnetrequest->set_method('auth/mnet/auth.php/user_authorise');
     // set $token and $useragent parameters
     $mnetrequest->add_param($token);
     $mnetrequest->add_param(sha1($_SERVER['HTTP_USER_AGENT']));
     // Thunderbirds are go! Do RPC call and store response
     if ($mnetrequest->send($remotepeer) === true) {
         $remoteuser = (object) $mnetrequest->response;
     } else {
         foreach ($mnetrequest->error as $errormessage) {
             list($code, $message) = array_map('trim', explode(':', $errormessage, 2));
             if ($code == 702) {
                 $site = get_site();
                 print_error('mnet_session_prohibited', 'mnet', $remotepeer->wwwroot, format_string($site->fullname));
                 exit;
             }
             $message .= "ERROR {$code}:<br/>{$errormessage}<br/>";
         }
         print_error("rpcerror", '', '', $message);
     }
     unset($mnetrequest);
     if (empty($remoteuser) or empty($remoteuser->username)) {
         print_error('unknownerror', 'mnet');
         exit;
     }
     if (user_not_fully_set_up($remoteuser)) {
         print_error('notenoughidpinfo', 'mnet');
         exit;
     }
     $remoteuser = mnet_strip_user($remoteuser, mnet_fields_to_import($remotepeer));
     $remoteuser->auth = 'mnet';
     $remoteuser->wwwroot = $remotepeer->wwwroot;
     // the user may roam from Moodle 1.x where lang has _utf8 suffix
     // also, make sure that the lang is actually installed, otherwise set site default
     if (isset($remoteuser->lang)) {
         $remoteuser->lang = clean_param(str_replace('_utf8', '', $remoteuser->lang), PARAM_LANG);
     }
     if (empty($remoteuser->lang)) {
         if (!empty($CFG->lang)) {
             $remoteuser->lang = $CFG->lang;
         } else {
             $remoteuser->lang = 'en';
         }
     }
     $firsttime = false;
     // get the local record for the remote user
     $localuser = $DB->get_record('user', array('username' => $remoteuser->username, 'mnethostid' => $remotehost->id));
     // add the remote user to the database if necessary, and if allowed
     // TODO: refactor into a separate function
     if (empty($localuser) || !$localuser->id) {
         /*
         if (empty($this->config->auto_add_remote_users)) {
             print_error('nolocaluser', 'mnet');
         } See MDL-21327   for why this is commented out
         */
         $remoteuser->mnethostid = $remotehost->id;
         $remoteuser->firstaccess = time();
         // First time user in this server, grab it here
         $remoteuser->confirmed = 1;
         $remoteuser->id = $DB->insert_record('user', $remoteuser);
         $firsttime = true;
         $localuser = $remoteuser;
     }
     // check sso access control list for permission first
     if (!$this->can_login_remotely($localuser->username, $remotehost->id)) {
         print_error('sso_mnet_login_refused', 'mnet', '', array('user' => $localuser->username, 'host' => $remotehost->name));
     }
     $fs = get_file_storage();
     // update the local user record with remote user data
     foreach ((array) $remoteuser as $key => $val) {
         if ($key == '_mnet_userpicture_timemodified' and empty($CFG->disableuserimages) and isset($remoteuser->picture)) {
             // update the user picture if there is a newer verion at the identity provider
             $usercontext = context_user::instance($localuser->id, MUST_EXIST);
             if ($usericonfile = $fs->get_file($usercontext->id, 'user', 'icon', 0, '/', 'f1.png')) {
                 $localtimemodified = $usericonfile->get_timemodified();
             } else {
                 if ($usericonfile = $fs->get_file($usercontext->id, 'user', 'icon', 0, '/', 'f1.jpg')) {
                     $localtimemodified = $usericonfile->get_timemodified();
                 } else {
                     $localtimemodified = 0;
                 }
             }
             if (!empty($val) and $localtimemodified < $val) {
                 mnet_debug('refetching the user picture from the identity provider host');
                 $fetchrequest = new mnet_xmlrpc_client();
                 $fetchrequest->set_method('auth/mnet/auth.php/fetch_user_image');
                 $fetchrequest->add_param($localuser->username);
                 if ($fetchrequest->send($remotepeer) === true) {
                     if (strlen($fetchrequest->response['f1']) > 0) {
                         $imagefilename = $CFG->tempdir . '/mnet-usericon-' . $localuser->id;
                         $imagecontents = base64_decode($fetchrequest->response['f1']);
                         file_put_contents($imagefilename, $imagecontents);
                         if ($newrev = process_new_icon($usercontext, 'user', 'icon', 0, $imagefilename)) {
                             $localuser->picture = $newrev;
                         }
                         unlink($imagefilename);
                     }
                     // note that since Moodle 2.0 we ignore $fetchrequest->response['f2']
                     // the mimetype information provided is ignored and the type of the file is detected
                     // by process_new_icon()
                 }
             }
         }
         if ($key == 'myhosts') {
             $localuser->mnet_foreign_host_array = array();
             foreach ($val as $rhost) {
                 $name = clean_param($rhost['name'], PARAM_ALPHANUM);
                 $url = clean_param($rhost['url'], PARAM_URL);
                 $count = clean_param($rhost['count'], PARAM_INT);
                 $url_is_local = stristr($url, $CFG->wwwroot);
                 if (!empty($name) && !empty($count) && empty($url_is_local)) {
                     $localuser->mnet_foreign_host_array[] = array('name' => $name, 'url' => $url, 'count' => $count);
                 }
             }
         }
         $localuser->{$key} = $val;
     }
     $localuser->mnethostid = $remotepeer->id;
     if (empty($localuser->firstaccess)) {
         // Now firstaccess, grab it here
         $localuser->firstaccess = time();
     }
     user_update_user($localuser, false);
     if (!$firsttime) {
         // repeat customer! let the IDP know about enrolments
         // we have for this user.
         // set up the RPC request
         $mnetrequest = new mnet_xmlrpc_client();
         $mnetrequest->set_method('auth/mnet/auth.php/update_enrolments');
         // pass username and an assoc array of "my courses"
         // with info so that the IDP can maintain mnetservice_enrol_enrolments
         $mnetrequest->add_param($remoteuser->username);
         $fields = 'id, category, sortorder, fullname, shortname, idnumber, summary, startdate, visible';
         $courses = enrol_get_users_courses($localuser->id, false, $fields, 'visible DESC,sortorder ASC');
         if (is_array($courses) && !empty($courses)) {
             // Second request to do the JOINs that we'd have done
             // inside enrol_get_users_courses() if we had been allowed
             $sql = "SELECT c.id,\n                               cc.name AS cat_name, cc.description AS cat_description\n                          FROM {course} c\n                          JOIN {course_categories} cc ON c.category = cc.id\n                         WHERE c.id IN (" . join(',', array_keys($courses)) . ')';
             $extra = $DB->get_records_sql($sql);
             $keys = array_keys($courses);
             $studentroles = get_archetype_roles('student');
             if (!empty($studentroles)) {
                 $defaultrole = reset($studentroles);
                 //$defaultrole = get_default_course_role($ccache[$shortname]); //TODO: rewrite this completely, there is no default course role any more!!!
                 foreach ($keys as $id) {
                     if ($courses[$id]->visible == 0) {
                         unset($courses[$id]);
                         continue;
                     }
                     $courses[$id]->cat_id = $courses[$id]->category;
                     $courses[$id]->defaultroleid = $defaultrole->id;
                     unset($courses[$id]->category);
                     unset($courses[$id]->visible);
                     $courses[$id]->cat_name = $extra[$id]->cat_name;
                     $courses[$id]->cat_description = $extra[$id]->cat_description;
                     $courses[$id]->defaultrolename = $defaultrole->name;
                     // coerce to array
                     $courses[$id] = (array) $courses[$id];
                 }
             } else {
                 throw new moodle_exception('unknownrole', 'error', '', 'student');
             }
         } else {
             // if the array is empty, send it anyway
             // we may be clearing out stale entries
             $courses = array();
         }
         $mnetrequest->add_param($courses);
         // Call 0800-RPC Now! -- we don't care too much if it fails
         // as it's just informational.
         if ($mnetrequest->send($remotepeer) === false) {
             // error_log(print_r($mnetrequest->error,1));
         }
     }
     return $localuser;
 }
Example #21
0
 /**
  * Update a local user record from an external source.
  * This is a lighter version of the one in moodlelib -- won't do
  * expensive ops such as enrolment.
  *
  * If you don't pass $updatekeys, there is a performance hit and
  * values removed from LDAP won't be removed from moodle.
  *
  * @param string $username username
  * @param boolean $updatekeys true to update the local record with the external LDAP values.
  * @param bool $triggerevent set false if user_updated event should not be triggered.
  *             This will not affect user_password_updated event triggering.
  * @return stdClass|bool updated user record or false if there is no new info to update.
  */
 function update_user_record($username, $updatekeys = false, $triggerevent = false)
 {
     global $CFG, $DB;
     // Just in case check text case
     $username = trim(core_text::strtolower($username));
     // Get the current user record
     $user = $DB->get_record('user', array('username' => $username, 'mnethostid' => $CFG->mnet_localhost_id));
     if (empty($user)) {
         // trouble
         error_log($this->errorlogtag . get_string('auth_dbusernotexist', 'auth_db', '', $username));
         print_error('auth_dbusernotexist', 'auth_db', '', $username);
         die;
     }
     // Protect the userid from being overwritten
     $userid = $user->id;
     if ($newinfo = $this->get_userinfo($username)) {
         $newinfo = truncate_userinfo($newinfo);
         if (empty($updatekeys)) {
             // all keys? this does not support removing values
             $updatekeys = array_keys($newinfo);
         }
         if (!empty($updatekeys)) {
             $newuser = new stdClass();
             $newuser->id = $userid;
             foreach ($updatekeys as $key) {
                 if (isset($newinfo[$key])) {
                     $value = $newinfo[$key];
                 } else {
                     $value = '';
                 }
                 if (!empty($this->config->{'field_updatelocal_' . $key})) {
                     // Only update if it's changed.
                     if ($user->{$key} != $value) {
                         $newuser->{$key} = $value;
                     }
                 }
             }
             user_update_user($newuser, false, $triggerevent);
         }
     } else {
         return false;
     }
     return $DB->get_record('user', array('id' => $userid, 'deleted' => 0));
 }
$forumform = new user_edit_forumng_form(null, array('id' => $userid, 'course' => $courseid, 'fid' => $cmid));
if ($user->maildigest == 2) {
    $user->maildigest = 1;
}
$forumform->set_data($user);
$redirect = new moodle_url('/user/preferences.php', array('userid' => $user->id));
if ($cmid) {
    $redirect = new moodle_url('/mod/forumng/view.php', array('id' => $cmid));
}
if ($forumform->is_cancelled()) {
    redirect($redirect);
} else {
    if ($data = $forumform->get_data()) {
        $user->maildigest = $data->maildigest;
        $user->mailformat = $data->mailformat;
        user_update_user($user, false, true);
        if ($USER->id == $user->id) {
            $USER->maildigest = $data->maildigest;
            $USER->mailformat = $data->mailformat;
        }
        redirect($redirect);
    }
}
// Display page header.
$streditmyforum = get_string('forumpreferences');
$userfullname = fullname($user, true);
// Add forum info to breadcrumbs.
if ($cmid) {
    $modinfo = get_fast_modinfo($courseid);
    $forum = $modinfo->get_cm($cmid);
    $PAGE->navbar->add(format_text($CFG->navshowfullcoursenames ? $course->fullname : $course->shortname), "/course/view.php?id={$courseid}");
Example #23
0
 /**
  * Parses the submitted form data and saves it into preferences array.
  *
  * @param stdClass $form preferences form class
  * @param array $preferences preferences array
  */
 function process_form($form, &$preferences)
 {
     global $CFG;
     if (isset($form->email_email)) {
         $preferences['message_processor_email_email'] = $form->email_email;
     }
     if (isset($form->preference_mailcharset)) {
         $preferences['mailcharset'] = $form->preference_mailcharset;
     }
     if (isset($form->mailformat) && isset($form->userid)) {
         require_once $CFG->dirroot . '/user/lib.php';
         $user = core_user::get_user($form->userid, '*', MUST_EXIST);
         $user->mailformat = clean_param($form->mailformat, PARAM_INT);
         user_update_user($user, false, false);
     }
 }
Example #24
0
 /**
  * Synchronizes user from external db to moodle user table.
  *
  * Sync should be done by using idnumber attribute, not username.
  * You need to pass firstsync parameter to function to fill in
  * idnumbers if they don't exists in moodle user table.
  *
  * Syncing users removes (disables) users that don't exists anymore in external db.
  * Creates new users and updates coursecreator status of users.
  *
  * This implementation is simpler but less scalable than the one found in the LDAP module.
  *
  * @param progress_trace $trace
  * @param bool $do_updates  Optional: set to true to force an update of existing accounts
  * @return int 0 means success, 1 means failure
  */
 function sync_users(progress_trace $trace, $do_updates = false)
 {
     global $CFG, $DB;
     // List external users.
     $userlist = $this->get_userlist();
     // Delete obsolete internal users.
     if (!empty($this->config->removeuser)) {
         $suspendselect = "";
         if ($this->config->removeuser == AUTH_REMOVEUSER_SUSPEND) {
             $suspendselect = "AND u.suspended = 0";
         }
         // Find obsolete users.
         if (count($userlist)) {
             list($notin_sql, $params) = $DB->get_in_or_equal($userlist, SQL_PARAMS_NAMED, 'u', false);
             $params['authtype'] = $this->authtype;
             $sql = "SELECT u.*\n                          FROM {user} u\n                         WHERE u.auth=:authtype AND u.deleted=0 AND u.mnethostid=:mnethostid {$suspendselect} AND u.username {$notin_sql}";
         } else {
             $sql = "SELECT u.*\n                          FROM {user} u\n                         WHERE u.auth=:authtype AND u.deleted=0 AND u.mnethostid=:mnethostid {$suspendselect}";
             $params = array();
             $params['authtype'] = $this->authtype;
         }
         $params['mnethostid'] = $CFG->mnet_localhost_id;
         $remove_users = $DB->get_records_sql($sql, $params);
         if (!empty($remove_users)) {
             require_once $CFG->dirroot . '/user/lib.php';
             $trace->output(get_string('auth_dbuserstoremove', 'auth_db', count($remove_users)));
             foreach ($remove_users as $user) {
                 if ($this->config->removeuser == AUTH_REMOVEUSER_FULLDELETE) {
                     delete_user($user);
                     $trace->output(get_string('auth_dbdeleteuser', 'auth_db', array('name' => $user->username, 'id' => $user->id)), 1);
                 } else {
                     if ($this->config->removeuser == AUTH_REMOVEUSER_SUSPEND) {
                         $updateuser = new stdClass();
                         $updateuser->id = $user->id;
                         $updateuser->suspended = 1;
                         user_update_user($updateuser, false);
                         $trace->output(get_string('auth_dbsuspenduser', 'auth_db', array('name' => $user->username, 'id' => $user->id)), 1);
                     }
                 }
             }
         }
         unset($remove_users);
     }
     if (!count($userlist)) {
         // Exit right here, nothing else to do.
         $trace->finished();
         return 0;
     }
     // Update existing accounts.
     if ($do_updates) {
         // Narrow down what fields we need to update.
         $all_keys = array_keys(get_object_vars($this->config));
         $updatekeys = array();
         foreach ($all_keys as $key) {
             if (preg_match('/^field_updatelocal_(.+)$/', $key, $match)) {
                 if ($this->config->{$key} === 'onlogin') {
                     array_push($updatekeys, $match[1]);
                     // The actual key name.
                 }
             }
         }
         unset($all_keys);
         unset($key);
         // Only go ahead if we actually have fields to update locally.
         if (!empty($updatekeys)) {
             list($in_sql, $params) = $DB->get_in_or_equal($userlist, SQL_PARAMS_NAMED, 'u', true);
             $params['authtype'] = $this->authtype;
             $sql = "SELECT u.id, u.username\n                          FROM {user} u\n                         WHERE u.auth=:authtype AND u.deleted=0 AND u.username {$in_sql}";
             if ($update_users = $DB->get_records_sql($sql, $params)) {
                 $trace->output("User entries to update: " . count($update_users));
                 foreach ($update_users as $user) {
                     if ($this->update_user_record($user->username, $updatekeys)) {
                         $trace->output(get_string('auth_dbupdatinguser', 'auth_db', array('name' => $user->username, 'id' => $user->id)), 1);
                     } else {
                         $trace->output(get_string('auth_dbupdatinguser', 'auth_db', array('name' => $user->username, 'id' => $user->id)) . " - " . get_string('skipped'), 1);
                     }
                 }
                 unset($update_users);
             }
         }
     }
     // Create missing accounts.
     // NOTE: this is very memory intensive and generally inefficient.
     $suspendselect = "";
     if ($this->config->removeuser == AUTH_REMOVEUSER_SUSPEND) {
         $suspendselect = "AND u.suspended = 0";
     }
     $sql = "SELECT u.id, u.username\n                  FROM {user} u\n                 WHERE u.auth=:authtype AND u.deleted='0' AND mnethostid=:mnethostid {$suspendselect}";
     $users = $DB->get_records_sql($sql, array('authtype' => $this->authtype, 'mnethostid' => $CFG->mnet_localhost_id));
     // Simplify down to usernames.
     $usernames = array();
     if (!empty($users)) {
         foreach ($users as $user) {
             array_push($usernames, $user->username);
         }
         unset($users);
     }
     $add_users = array_diff($userlist, $usernames);
     unset($usernames);
     if (!empty($add_users)) {
         $trace->output(get_string('auth_dbuserstoadd', 'auth_db', count($add_users)));
         // Do not use transactions around this foreach, we want to skip problematic users, not revert everything.
         foreach ($add_users as $user) {
             $username = $user;
             if ($this->config->removeuser == AUTH_REMOVEUSER_SUSPEND) {
                 if ($old_user = $DB->get_record('user', array('username' => $username, 'deleted' => 0, 'suspended' => 1, 'mnethostid' => $CFG->mnet_localhost_id, 'auth' => $this->authtype))) {
                     $DB->set_field('user', 'suspended', 0, array('id' => $old_user->id));
                     $trace->output(get_string('auth_dbreviveduser', 'auth_db', array('name' => $username, 'id' => $old_user->id)), 1);
                     continue;
                 }
             }
             // Do not try to undelete users here, instead select suspending if you ever expect users will reappear.
             // Prep a few params.
             $user = $this->get_userinfo_asobj($user);
             $user->username = $username;
             $user->confirmed = 1;
             $user->auth = $this->authtype;
             $user->mnethostid = $CFG->mnet_localhost_id;
             if (empty($user->lang)) {
                 $user->lang = $CFG->lang;
             }
             if (empty($user->calendartype)) {
                 $user->calendartype = $CFG->calendartype;
             }
             $user->timecreated = time();
             $user->timemodified = $user->timecreated;
             if ($collision = $DB->get_record_select('user', "username = :username AND mnethostid = :mnethostid AND auth <> :auth", array('username' => $user->username, 'mnethostid' => $CFG->mnet_localhost_id, 'auth' => $this->authtype), 'id,username,auth')) {
                 $trace->output(get_string('auth_dbinsertuserduplicate', 'auth_db', array('username' => $user->username, 'auth' => $collision->auth)), 1);
                 continue;
             }
             try {
                 $id = $DB->insert_record('user', $user);
                 // it is truly a new user
                 $trace->output(get_string('auth_dbinsertuser', 'auth_db', array('name' => $user->username, 'id' => $id)), 1);
             } catch (moodle_exception $e) {
                 $trace->output(get_string('auth_dbinsertusererror', 'auth_db', $user->username), 1);
                 continue;
             }
             // If relevant, tag for password generation.
             if ($this->is_internal()) {
                 set_user_preference('auth_forcepasswordchange', 1, $id);
                 set_user_preference('create_password', 1, $id);
             }
             // Make sure user context is present.
             context_user::instance($id);
         }
         unset($add_users);
     }
     $trace->finished();
     return 0;
 }
Example #25
0
                        // This error should get caught before here anyhow,
                        // so no need to translate this. This is just in case. :-)
                        $error = 'Invalid characters in login.';
                    } else {
                        if (empty($user)) {
                            // Username cannot be blank. This is currently the only place
                            // that calls addUser that is located in $user_inc.
                            $error = $blankUserStr;
                        } else {
                            user_add_user($user, $upassword1, $ufirstname, $ulastname, $uemail, $uis_admin, $u_enabled);
                            activity_log(0, $login, $user, LOG_USER_ADD, "{$ufirstname} {$ulastname}" . (empty($uemail) ? '' : " <{$uemail}>"));
                        }
                    }
                }
            } else {
                if (!empty($add) && !access_can_access_function(ACCESS_USER_MANAGEMENT)) {
                    $error = print_not_auth(15);
                } else {
                    // Don't allow a user to change themself to an admin by setting
                    // uis_admin in the URL by hand. They must be admin beforehand.
                    if (!$is_admin) {
                        $uis_admin = 'N';
                    }
                    user_update_user($user, $ufirstname, $ulastname, $uemail, $uis_admin, $uenabled);
                    activity_log(0, $login, $user, LOG_USER_UPDATE, "{$ufirstname} {$ulastname}" . (empty($uemail) ? '' : " <{$uemail}>"));
                }
            }
        }
    }
}
echo error_check('users.php', false);
Example #26
0
 /**
  * Test badges assertion generated when a badge is issued.
  */
 public function test_badges_assertion()
 {
     $this->preventResetByRollback();
     // Messaging is not compatible with transactions.
     $badge = new badge($this->coursebadge);
     $this->assertFalse($badge->is_issued($this->user->id));
     $criteria_overall = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id));
     $criteria_overall->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ANY));
     $criteria_overall1 = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_PROFILE, 'badgeid' => $badge->id));
     $criteria_overall1->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ALL, 'field_address' => 'address'));
     $this->user->address = 'Test address';
     $sink = $this->redirectEmails();
     user_update_user($this->user, false);
     $this->assertCount(1, $sink->get_messages());
     $sink->close();
     // Check if badge is awarded.
     $this->assertDebuggingCalled('Error baking badge image!');
     $awards = $badge->get_awards();
     $this->assertCount(1, $awards);
     // Get assertion.
     $award = reset($awards);
     $assertion = new core_badges_assertion($award->uniquehash);
     $testassertion = $this->assertion;
     // Make sure JSON strings have the same structure.
     $this->assertStringMatchesFormat($testassertion->badge, json_encode($assertion->get_badge_assertion()));
     $this->assertStringMatchesFormat($testassertion->class, json_encode($assertion->get_badge_class()));
     $this->assertStringMatchesFormat($testassertion->issuer, json_encode($assertion->get_issuer()));
 }
Example #27
0
/**
 * Marks user deleted in internal user database and notifies the auth plugin.
 * Also unenrols user from all roles and does other cleanup.
 *
 * Any plugin that needs to purge user data should register the 'user_deleted' event.
 *
 * @param stdClass $user full user object before delete
 * @return boolean success
 * @throws coding_exception if invalid $user parameter detected
 */
function delete_user(stdClass $user)
{
    global $CFG, $DB;
    require_once $CFG->libdir . '/grouplib.php';
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->dirroot . '/message/lib.php';
    require_once $CFG->dirroot . '/user/lib.php';
    // Make sure nobody sends bogus record type as parameter.
    if (!property_exists($user, 'id') or !property_exists($user, 'username')) {
        throw new coding_exception('Invalid $user parameter in delete_user() detected');
    }
    // Better not trust the parameter and fetch the latest info this will be very expensive anyway.
    if (!($user = $DB->get_record('user', array('id' => $user->id)))) {
        debugging('Attempt to delete unknown user account.');
        return false;
    }
    // There must be always exactly one guest record, originally the guest account was identified by username only,
    // now we use $CFG->siteguest for performance reasons.
    if ($user->username === 'guest' or isguestuser($user)) {
        debugging('Guest user account can not be deleted.');
        return false;
    }
    // Admin can be theoretically from different auth plugin, but we want to prevent deletion of internal accoutns only,
    // if anything goes wrong ppl may force somebody to be admin via config.php setting $CFG->siteadmins.
    if ($user->auth === 'manual' and is_siteadmin($user)) {
        debugging('Local administrator accounts can not be deleted.');
        return false;
    }
    // Allow plugins to use this user object before we completely delete it.
    if ($pluginsfunction = get_plugins_with_function('pre_user_delete')) {
        foreach ($pluginsfunction as $plugintype => $plugins) {
            foreach ($plugins as $pluginfunction) {
                $pluginfunction($user);
            }
        }
    }
    // Keep user record before updating it, as we have to pass this to user_deleted event.
    $olduser = clone $user;
    // Keep a copy of user context, we need it for event.
    $usercontext = context_user::instance($user->id);
    // Delete all grades - backup is kept in grade_grades_history table.
    grade_user_delete($user->id);
    // Move unread messages from this user to read.
    message_move_userfrom_unread2read($user->id);
    // TODO: remove from cohorts using standard API here.
    // Remove user tags.
    core_tag_tag::remove_all_item_tags('core', 'user', $user->id);
    // Unconditionally unenrol from all courses.
    enrol_user_delete($user);
    // Unenrol from all roles in all contexts.
    // This might be slow but it is really needed - modules might do some extra cleanup!
    role_unassign_all(array('userid' => $user->id));
    // Now do a brute force cleanup.
    // Remove from all cohorts.
    $DB->delete_records('cohort_members', array('userid' => $user->id));
    // Remove from all groups.
    $DB->delete_records('groups_members', array('userid' => $user->id));
    // Brute force unenrol from all courses.
    $DB->delete_records('user_enrolments', array('userid' => $user->id));
    // Purge user preferences.
    $DB->delete_records('user_preferences', array('userid' => $user->id));
    // Purge user extra profile info.
    $DB->delete_records('user_info_data', array('userid' => $user->id));
    // Purge log of previous password hashes.
    $DB->delete_records('user_password_history', array('userid' => $user->id));
    // Last course access not necessary either.
    $DB->delete_records('user_lastaccess', array('userid' => $user->id));
    // Remove all user tokens.
    $DB->delete_records('external_tokens', array('userid' => $user->id));
    // Unauthorise the user for all services.
    $DB->delete_records('external_services_users', array('userid' => $user->id));
    // Remove users private keys.
    $DB->delete_records('user_private_key', array('userid' => $user->id));
    // Remove users customised pages.
    $DB->delete_records('my_pages', array('userid' => $user->id, 'private' => 1));
    // Force logout - may fail if file based sessions used, sorry.
    \core\session\manager::kill_user_sessions($user->id);
    // Generate username from email address, or a fake email.
    $delemail = !empty($user->email) ? $user->email : $user->username . '.' . $user->id . '@unknownemail.invalid';
    $delname = clean_param($delemail . "." . time(), PARAM_USERNAME);
    // Workaround for bulk deletes of users with the same email address.
    while ($DB->record_exists('user', array('username' => $delname))) {
        // No need to use mnethostid here.
        $delname++;
    }
    // Mark internal user record as "deleted".
    $updateuser = new stdClass();
    $updateuser->id = $user->id;
    $updateuser->deleted = 1;
    $updateuser->username = $delname;
    // Remember it just in case.
    $updateuser->email = md5($user->username);
    // Store hash of username, useful importing/restoring users.
    $updateuser->idnumber = '';
    // Clear this field to free it up.
    $updateuser->picture = 0;
    $updateuser->timemodified = time();
    // Don't trigger update event, as user is being deleted.
    user_update_user($updateuser, false, false);
    // Now do a final accesslib cleanup - removes all role assignments in user context and context itself.
    context_helper::delete_instance(CONTEXT_USER, $user->id);
    // Any plugin that needs to cleanup should register this event.
    // Trigger event.
    $event = \core\event\user_deleted::create(array('objectid' => $user->id, 'relateduserid' => $user->id, 'context' => $usercontext, 'other' => array('username' => $user->username, 'email' => $user->email, 'idnumber' => $user->idnumber, 'picture' => $user->picture, 'mnethostid' => $user->mnethostid)));
    $event->add_record_snapshot('user', $olduser);
    $event->trigger();
    // We will update the user's timemodified, as it will be passed to the user_deleted event, which
    // should know about this updated property persisted to the user's table.
    $user->timemodified = $updateuser->timemodified;
    // Notify auth plugin - do not block the delete even when plugin fails.
    $authplugin = get_auth_plugin($user->auth);
    $authplugin->user_delete($user);
    return true;
}
Example #28
0
 /**
  * Test user_update_user.
  */
 public function test_user_update_user()
 {
     global $DB;
     $this->resetAfterTest();
     // Create user and modify user profile.
     $user = $this->getDataGenerator()->create_user();
     $user->firstname = 'Test';
     $user->password = '******';
     // Update user and capture event.
     $sink = $this->redirectEvents();
     user_update_user($user);
     $events = $sink->get_events();
     $sink->close();
     $event = array_pop($events);
     // Test updated value.
     $dbuser = $DB->get_record('user', array('id' => $user->id));
     $this->assertSame($user->firstname, $dbuser->firstname);
     $this->assertNotSame('M00dLe@T', $dbuser->password);
     // Test event.
     $this->assertInstanceOf('\\core\\event\\user_updated', $event);
     $this->assertSame($user->id, $event->objectid);
     $this->assertSame('user_updated', $event->get_legacy_eventname());
     $this->assertEventLegacyData($dbuser, $event);
     $this->assertEquals(context_user::instance($user->id), $event->get_context());
     $expectedlogdata = array(SITEID, 'user', 'update', 'view.php?id=' . $user->id, '');
     $this->assertEventLegacyLogData($expectedlogdata, $event);
     // Update user with no password update.
     $password = $user->password = hash_internal_user_password('M00dLe@T');
     user_update_user($user, false);
     $dbuser = $DB->get_record('user', array('id' => $user->id));
     $this->assertSame($password, $dbuser->password);
     // Verify event is not triggred by user_update_user when needed.
     $sink = $this->redirectEvents();
     user_update_user($user, false, false);
     $events = $sink->get_events();
     $sink->close();
     $this->assertCount(0, $events);
     // With password, there should be 1 event.
     $sink = $this->redirectEvents();
     user_update_user($user, true, false);
     $events = $sink->get_events();
     $sink->close();
     $this->assertCount(1, $events);
     $event = array_pop($events);
     $this->assertInstanceOf('\\core\\event\\user_password_updated', $event);
     // Test user data validation.
     $user->username = '******';
     $user->auth = 'shibolth';
     $user->country = 'WW';
     $user->lang = 'xy';
     $user->theme = 'somewrongthemename';
     $user->timezone = 'Paris';
     $user->url = 'wwww.somewrong@#$url.com.aus';
     $debugmessages = $this->getDebuggingMessages();
     user_update_user($user, true, false);
     $this->assertDebuggingCalledCount(6, $debugmessages);
     // Now, with valid user data.
     $user->username = '******';
     $user->auth = 'shibboleth';
     $user->country = 'AU';
     $user->lang = 'en';
     $user->theme = 'clean';
     $user->timezone = 'Australia/Perth';
     $user->url = 'www.moodle.org';
     user_update_user($user, true, false);
     $this->assertDebuggingNotCalled();
 }
Example #29
0
         $emailchanged = true;
     }
 }
 $authplugin = get_auth_plugin($user->auth);
 $usernew->timemodified = time();
 // Description editor element may not exist!
 if (isset($usernew->description_editor) && isset($usernew->description_editor['format'])) {
     $usernew = file_postupdate_standard_editor($usernew, 'description', $editoroptions, $personalcontext, 'user', 'profile', 0);
 }
 // Pass a true old $user here.
 if (!$authplugin->user_update($user, $usernew)) {
     // Auth update failed.
     print_error('cannotupdateprofile');
 }
 // Update user with new profile data.
 user_update_user($usernew, false, false);
 // Update preferences.
 useredit_update_user_preference($usernew);
 // Update interests.
 if (isset($usernew->interests)) {
     useredit_update_interests($usernew, $usernew->interests);
 }
 // Update user picture.
 if (empty($CFG->disableuserimages)) {
     useredit_update_picture($usernew, $userform, $filemanageroptions);
 }
 // Update mail bounces.
 useredit_update_bounces($user, $usernew);
 // Update forum track preference.
 useredit_update_trackforums($user, $usernew);
 // Save custom profile fields data.
Example #30
0
 /**
  * Performs synchronisation of member information and enrolments.
  *
  * @param stdClass $tool
  * @param ToolConsumer $consumer
  * @param User[] $members
  * @return array An array containing the number of members that were processed and the number of members that were enrolled.
  */
 protected function sync_member_information(stdClass $tool, ToolConsumer $consumer, $members)
 {
     global $DB;
     $usercount = 0;
     $enrolcount = 0;
     // Process member information.
     foreach ($members as $member) {
         $usercount++;
         // Set the user data.
         $user = new stdClass();
         $user->username = helper::create_username($consumer->getKey(), $member->ltiUserId);
         $user->firstname = core_user::clean_field($member->firstname, 'firstname');
         $user->lastname = core_user::clean_field($member->lastname, 'lastname');
         $user->email = core_user::clean_field($member->email, 'email');
         // Get the user data from the LTI consumer.
         $user = helper::assign_user_tool_data($tool, $user);
         $dbuser = core_user::get_user_by_username($user->username, 'id');
         if ($dbuser) {
             // If email is empty remove it, so we don't update the user with an empty email.
             if (empty($user->email)) {
                 unset($user->email);
             }
             $user->id = $dbuser->id;
             user_update_user($user);
             // Add the information to the necessary arrays.
             if (!in_array($user->id, $this->currentusers)) {
                 $this->currentusers[] = $user->id;
             }
             $this->userphotos[$user->id] = $member->image;
         } else {
             if ($this->should_sync_enrol($tool->membersyncmode)) {
                 // If the email was stripped/not set then fill it with a default one. This
                 // stops the user from being redirected to edit their profile page.
                 if (empty($user->email)) {
                     $user->email = $user->username . "@example.com";
                 }
                 $user->auth = 'lti';
                 $user->id = user_create_user($user);
                 // Add the information to the necessary arrays.
                 $this->currentusers[] = $user->id;
                 $this->userphotos[$user->id] = $member->image;
             }
         }
         // Sync enrolments.
         if ($this->should_sync_enrol($tool->membersyncmode)) {
             // Enrol the user in the course.
             if (helper::enrol_user($tool, $user->id) === helper::ENROLMENT_SUCCESSFUL) {
                 // Increment enrol count.
                 $enrolcount++;
             }
             // Check if this user has already been registered in the enrol_lti_users table.
             if (!$DB->record_exists('enrol_lti_users', ['toolid' => $tool->id, 'userid' => $user->id])) {
                 // Create an initial enrol_lti_user record that we can use later when syncing grades and members.
                 $userlog = new stdClass();
                 $userlog->userid = $user->id;
                 $userlog->toolid = $tool->id;
                 $userlog->consumerkey = $consumer->getKey();
                 $DB->insert_record('enrol_lti_users', $userlog);
             }
         }
     }
     return [$usercount, $enrolcount];
 }