Exemplo n.º 1
0
 public function test_create_user()
 {
     global $DB, $CFG;
     require_once $CFG->dirroot . '/user/lib.php';
     $this->resetAfterTest(true);
     $generator = $this->getDataGenerator();
     $count = $DB->count_records('user');
     $this->setCurrentTimeStart();
     $user = $generator->create_user();
     $this->assertEquals($count + 1, $DB->count_records('user'));
     $this->assertSame($user->username, core_user::clean_field($user->username, 'username'));
     $this->assertSame($user->email, core_user::clean_field($user->email, 'email'));
     $this->assertSame(AUTH_PASSWORD_NOT_CACHED, $user->password);
     $this->assertNotEmpty($user->firstnamephonetic);
     $this->assertNotEmpty($user->lastnamephonetic);
     $this->assertNotEmpty($user->alternatename);
     $this->assertNotEmpty($user->middlename);
     $this->assertSame('manual', $user->auth);
     $this->assertSame('en', $user->lang);
     $this->assertSame('1', $user->confirmed);
     $this->assertSame('0', $user->deleted);
     $this->assertTimeCurrent($user->timecreated);
     $this->assertSame($user->timecreated, $user->timemodified);
     $this->assertSame('0.0.0.0', $user->lastip);
     $record = array('auth' => 'email', 'firstname' => 'Žluťoučký', 'lastname' => 'Koníček', 'firstnamephonetic' => 'Zhlutyoucky', 'lastnamephonetic' => 'Koniiczek', 'middlename' => 'Hopper', 'alternatename' => 'horse', 'idnumber' => 'abc1', 'mnethostid' => (string) $CFG->mnet_localhost_id, 'username' => 'konic666', 'password' => 'password1', 'email' => '*****@*****.**', 'confirmed' => '1', 'lang' => 'cs', 'maildisplay' => '1', 'mailformat' => '0', 'maildigest' => '1', 'autosubscribe' => '0', 'trackforums' => '0', 'deleted' => '0', 'timecreated' => '666');
     $user = $generator->create_user($record);
     $this->assertEquals($count + 2, $DB->count_records('user'));
     foreach ($record as $k => $v) {
         if ($k === 'password') {
             $this->assertTrue(password_verify($v, $user->password));
         } else {
             $this->assertSame($v, $user->{$k});
         }
     }
     $record = array('firstname' => 'Some', 'lastname' => 'User', 'idnumber' => 'def', 'username' => 'user666', 'email' => '*****@*****.**', 'deleted' => '1');
     $user = $generator->create_user($record);
     $this->assertEquals($count + 3, $DB->count_records('user'));
     $this->assertSame('', $user->idnumber);
     $this->assertSame(md5($record['username']), $user->email);
     $this->assertFalse(context_user::instance($user->id, IGNORE_MISSING));
     // Test generating user with interests.
     $user = $generator->create_user(array('interests' => 'Cats, Dogs'));
     $userdetails = user_get_user_details($user);
     $this->assertSame('Cats, Dogs', $userdetails['interests']);
 }
Exemplo n.º 2
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.");
     }
 }
Exemplo n.º 3
0
 // Before we do anything check that the context is valid.
 $context = context::instance_by_id($tool->contextid);
 // Set the user data.
 $user = new stdClass();
 $user->username = \enrol_lti\helper::create_username($ltirequest->info['oauth_consumer_key'], $ltirequest->info['user_id']);
 if (!empty($ltirequest->info['lis_person_name_given'])) {
     $user->firstname = $ltirequest->info['lis_person_name_given'];
 } else {
     $user->firstname = $ltirequest->info['user_id'];
 }
 if (!empty($ltirequest->info['lis_person_name_family'])) {
     $user->lastname = $ltirequest->info['lis_person_name_family'];
 } else {
     $user->lastname = $ltirequest->info['context_id'];
 }
 $user->email = \core_user::clean_field($ltirequest->getUserEmail(), 'email');
 // Get the user data from the LTI consumer.
 $user = \enrol_lti\helper::assign_user_tool_data($tool, $user);
 // Check if the user exists.
 if (!($dbuser = $DB->get_record('user', array('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', array('id' => $user->id));
 } else {
     if (\enrol_lti\helper::user_match($user, $dbuser)) {
Exemplo n.º 4
0
 /**
  * Test clean_field() method.
  */
 public function test_clean_field()
 {
     // Create a 'malicious' user object/
     $user = new stdClass();
     $user->firstname = 'John <script>alert(1)</script> Doe';
     $user->username = '******';
     $user->email = ' john@testing.com ';
     $user->deleted = 'no';
     $user->description = '<b>A description <script>alert(123);</script>about myself.</b>';
     $user->userfullname = 'John Doe';
     // Expected results.
     $this->assertEquals('John alert(1) Doe', core_user::clean_field($user->firstname, 'firstname'));
     $this->assertEquals('john_doe', core_user::clean_field($user->username, 'username'));
     $this->assertEquals('*****@*****.**', core_user::clean_field($user->email, 'email'));
     $this->assertEquals(0, core_user::clean_field($user->deleted, 'deleted'));
     $this->assertEquals('<b>A description <script>alert(123);</script>about myself.</b>', core_user::clean_field($user->description, 'description'));
     // Try to clean an invalid property (fullname).
     core_user::clean_field($user->userfullname, 'fullname');
     $this->assertDebuggingCalled("The property 'fullname' could not be cleaned.");
 }
Exemplo n.º 5
0
 /**
  * Validate the form data.
  * @param array $usernew
  * @param array $files
  * @return array|bool
  */
 public function validation($usernew, $files)
 {
     global $CFG, $DB;
     $usernew = (object) $usernew;
     $usernew->username = trim($usernew->username);
     $user = $DB->get_record('user', array('id' => $usernew->id));
     $err = array();
     if (!$user and !empty($usernew->createpassword)) {
         if ($usernew->suspended) {
             // Show some error because we can not mail suspended users.
             $err['suspended'] = get_string('error');
         }
     } else {
         if (!empty($usernew->newpassword)) {
             $errmsg = '';
             // Prevent eclipse warning.
             if (!check_password_policy($usernew->newpassword, $errmsg)) {
                 $err['newpassword'] = $errmsg;
             }
         } else {
             if (!$user) {
                 $auth = get_auth_plugin($usernew->auth);
                 if ($auth->is_internal()) {
                     // Internal accounts require password!
                     $err['newpassword'] = get_string('required');
                 }
             }
         }
     }
     if (empty($usernew->username)) {
         // Might be only whitespace.
         $err['username'] = get_string('required');
     } else {
         if (!$user or $user->username !== $usernew->username) {
             // Check new username does not exist.
             if ($DB->record_exists('user', array('username' => $usernew->username, 'mnethostid' => $CFG->mnet_localhost_id))) {
                 $err['username'] = get_string('usernameexists');
             }
             // Check allowed characters.
             if ($usernew->username !== core_text::strtolower($usernew->username)) {
                 $err['username'] = get_string('usernamelowercase');
             } else {
                 if ($usernew->username !== core_user::clean_field($usernew->username, 'username')) {
                     $err['username'] = get_string('invalidusername');
                 }
             }
         }
     }
     if (!$user or isset($usernew->email) && $user->email !== $usernew->email) {
         if (!validate_email($usernew->email)) {
             $err['email'] = get_string('invalidemail');
         } else {
             if (empty($CFG->allowaccountssameemail) and $DB->record_exists('user', array('email' => $usernew->email, 'mnethostid' => $CFG->mnet_localhost_id))) {
                 $err['email'] = get_string('emailexists');
             }
         }
     }
     // Next the customisable profile fields.
     $err += profile_validation($usernew, $files);
     if (count($err) == 0) {
         return true;
     } else {
         return $err;
     }
 }
Exemplo n.º 6
0
$data = array();
$cir->init();
$linenum = 1;
//column header is first line
$noerror = true;
// Keep status of any error.
while ($linenum <= $previewrows and $fields = $cir->next()) {
    $linenum++;
    $rowcols = array();
    $rowcols['line'] = $linenum;
    foreach ($fields as $key => $field) {
        $rowcols[$filecolumns[$key]] = s(trim($field));
    }
    $rowcols['status'] = array();
    if (isset($rowcols['username'])) {
        $stdusername = core_user::clean_field($rowcols['username'], 'username');
        if ($rowcols['username'] !== $stdusername) {
            $rowcols['status'][] = get_string('invalidusernameupload');
        }
        if ($userid = $DB->get_field('user', 'id', array('username' => $stdusername, 'mnethostid' => $CFG->mnet_localhost_id))) {
            $rowcols['username'] = html_writer::link(new moodle_url('/user/profile.php', array('id' => $userid)), $rowcols['username']);
        }
    } else {
        $rowcols['status'][] = get_string('missingusername');
    }
    if (isset($rowcols['email'])) {
        if (!validate_email($rowcols['email'])) {
            $rowcols['status'][] = get_string('invalidemail');
        }
        $select = $DB->sql_like('email', ':email', false, true, false, '|');
        $params = array('email' => $DB->sql_like_escape($rowcols['email'], '|'));
Exemplo n.º 7
0
 function validation($data, $files)
 {
     global $CFG, $DB;
     $errors = parent::validation($data, $files);
     $authplugin = get_auth_plugin($CFG->registerauth);
     if ($DB->record_exists('user', array('username' => $data['username'], 'mnethostid' => $CFG->mnet_localhost_id))) {
         $errors['username'] = get_string('usernameexists');
     } else {
         //check allowed characters
         if ($data['username'] !== core_text::strtolower($data['username'])) {
             $errors['username'] = get_string('usernamelowercase');
         } else {
             if ($data['username'] !== core_user::clean_field($data['username'], 'username')) {
                 $errors['username'] = get_string('invalidusername');
             }
         }
     }
     //check if user exists in external db
     //TODO: maybe we should check all enabled plugins instead
     if ($authplugin->user_exists($data['username'])) {
         $errors['username'] = get_string('usernameexists');
     }
     if (!validate_email($data['email'])) {
         $errors['email'] = get_string('invalidemail');
     } else {
         if ($DB->record_exists('user', array('email' => $data['email']))) {
             $errors['email'] = get_string('emailexists') . ' <a href="forgot_password.php">' . get_string('newpassword') . '?</a>';
         }
     }
     if (empty($data['email2'])) {
         $errors['email2'] = get_string('missingemail');
     } else {
         if ($data['email2'] != $data['email']) {
             $errors['email2'] = get_string('invalidemail');
         }
     }
     if (!isset($errors['email'])) {
         if ($err = email_is_not_allowed($data['email'])) {
             $errors['email'] = $err;
         }
     }
     $errmsg = '';
     if (!check_password_policy($data['password'], $errmsg)) {
         $errors['password'] = $errmsg;
     }
     if ($this->signup_captcha_enabled()) {
         $recaptcha_element = $this->_form->getElement('recaptcha_element');
         if (!empty($this->_form->_submitValues['recaptcha_challenge_field'])) {
             $challenge_field = $this->_form->_submitValues['recaptcha_challenge_field'];
             $response_field = $this->_form->_submitValues['recaptcha_response_field'];
             if (true !== ($result = $recaptcha_element->verify($challenge_field, $response_field))) {
                 $errors['recaptcha'] = $result;
             }
         } else {
             $errors['recaptcha'] = get_string('missingrecaptchachallengefield');
         }
     }
     // Validate customisable profile fields. (profile_validation expects an object as the parameter with userid set)
     $dataobject = (object) $data;
     $dataobject->id = 0;
     $errors += profile_validation($dataobject, $files);
     return $errors;
 }
Exemplo n.º 8
0
 /**
  * Clean the user data.
  *
  * @param stdClass|array $user the user data to be validated against properties definition.
  * @return stdClass $user the cleaned user data.
  */
 public static function clean_data($user)
 {
     if (empty($user)) {
         return $user;
     }
     foreach ($user as $field => $value) {
         // Get the property parameter type and do the cleaning.
         try {
             $user->{$field} = core_user::clean_field($value, $field);
         } catch (coding_exception $e) {
             debugging("The property '{$field}' could not be cleaned.", DEBUG_DEVELOPER);
         }
     }
     return $user;
 }
Exemplo n.º 9
0
    }
}
// Restore the #anchor to the original wantsurl. Note that this
// will only work for internal auth plugins, SSO plugins such as
// SAML / CAS / OIDC will have to handle this correctly directly.
if ($anchor && isset($SESSION->wantsurl) && strpos($SESSION->wantsurl, '#') === false) {
    $wantsurl = new moodle_url($SESSION->wantsurl);
    $wantsurl->set_anchor(substr($anchor, 1));
    $SESSION->wantsurl = $wantsurl->out();
}
/// Check if the user has actually submitted login data to us
if ($frm and isset($frm->username)) {
    // Login WITH cookies
    $frm->username = trim(core_text::strtolower($frm->username));
    if (is_enabled_auth('none')) {
        if ($frm->username !== core_user::clean_field($frm->username, 'username')) {
            $errormsg = get_string('username') . ': ' . get_string("invalidusername");
            $errorcode = 2;
            $user = null;
        }
    }
    if ($user) {
        //user already supplied by aut plugin prelogin hook
    } else {
        if ($frm->username == 'guest' and empty($CFG->guestloginbutton)) {
            $user = false;
            /// Can't log in as guest if guest button is disabled
            $frm = false;
        } else {
            if (empty($errormsg)) {
                $user = authenticate_user_login($frm->username, $frm->password, false, $errorcode);
Exemplo n.º 10
0
Arquivo: lib.php Projeto: dg711/moodle
/**
 * Update a user with a user object (will compare against the ID)
 *
 * @throws moodle_exception
 * @param stdClass $user the user to update
 * @param bool $updatepassword if true, authentication plugin will update password.
 * @param bool $triggerevent set false if user_updated event should not be triggred.
 *             This will not affect user_password_updated event triggering.
 */
function user_update_user($user, $updatepassword = true, $triggerevent = true)
{
    global $DB;
    // Set the timecreate field to the current time.
    if (!is_object($user)) {
        $user = (object) $user;
    }
    // Check username.
    if (isset($user->username)) {
        if ($user->username !== core_text::strtolower($user->username)) {
            throw new moodle_exception('usernamelowercase');
        } else {
            if ($user->username !== core_user::clean_field($user->username, 'username')) {
                throw new moodle_exception('invalidusername');
            }
        }
    }
    // Unset password here, for updating later, if password update is required.
    if ($updatepassword && isset($user->password)) {
        // Check password toward the password policy.
        if (!check_password_policy($user->password, $errmsg)) {
            throw new moodle_exception($errmsg);
        }
        $passwd = $user->password;
        unset($user->password);
    }
    // Make sure calendartype, if set, is valid.
    if (empty($user->calendartype)) {
        // Unset this variable, must be an empty string, which we do not want to update the calendartype to.
        unset($user->calendartype);
    }
    $user->timemodified = time();
    // Validate user data object.
    $uservalidation = core_user::validate($user);
    if ($uservalidation !== true) {
        foreach ($uservalidation as $field => $message) {
            debugging("The property '{$field}' has invalid data and has been cleaned.", DEBUG_DEVELOPER);
            $user->{$field} = core_user::clean_field($user->{$field}, $field);
        }
    }
    $DB->update_record('user', $user);
    if ($updatepassword) {
        // Get full user record.
        $updateduser = $DB->get_record('user', array('id' => $user->id));
        // If password was set, then update its hash.
        if (isset($passwd)) {
            $authplugin = get_auth_plugin($updateduser->auth);
            if ($authplugin->can_change_password()) {
                $authplugin->user_update_password($updateduser, $passwd);
            }
        }
    }
    // Trigger event if required.
    if ($triggerevent) {
        \core\event\user_updated::create_from_userid($user->id)->trigger();
    }
}
Exemplo n.º 11
0
/**
 * Validates the standard sign-up data (except recaptcha that is validated by the form element).
 *
 * @param  array $data  the sign-up data
 * @param  array $files files among the data
 * @return array list of errors, being the key the data element name and the value the error itself
 * @since Moodle 3.2
 */
function signup_validate_data($data, $files)
{
    global $CFG, $DB;
    $errors = array();
    $authplugin = get_auth_plugin($CFG->registerauth);
    if ($DB->record_exists('user', array('username' => $data['username'], 'mnethostid' => $CFG->mnet_localhost_id))) {
        $errors['username'] = get_string('usernameexists');
    } else {
        // Check allowed characters.
        if ($data['username'] !== core_text::strtolower($data['username'])) {
            $errors['username'] = get_string('usernamelowercase');
        } else {
            if ($data['username'] !== core_user::clean_field($data['username'], 'username')) {
                $errors['username'] = get_string('invalidusername');
            }
        }
    }
    // Check if user exists in external db.
    // TODO: maybe we should check all enabled plugins instead.
    if ($authplugin->user_exists($data['username'])) {
        $errors['username'] = get_string('usernameexists');
    }
    if (!validate_email($data['email'])) {
        $errors['email'] = get_string('invalidemail');
    } else {
        if ($DB->record_exists('user', array('email' => $data['email']))) {
            $errors['email'] = get_string('emailexists') . ' <a href="forgot_password.php">' . get_string('newpassword') . '?</a>';
        }
    }
    if (empty($data['email2'])) {
        $errors['email2'] = get_string('missingemail');
    } else {
        if ($data['email2'] != $data['email']) {
            $errors['email2'] = get_string('invalidemail');
        }
    }
    if (!isset($errors['email'])) {
        if ($err = email_is_not_allowed($data['email'])) {
            $errors['email'] = $err;
        }
    }
    $errmsg = '';
    if (!check_password_policy($data['password'], $errmsg)) {
        $errors['password'] = $errmsg;
    }
    // Validate customisable profile fields. (profile_validation expects an object as the parameter with userid set).
    $dataobject = (object) $data;
    $dataobject->id = 0;
    $errors += profile_validation($dataobject, $files);
    return $errors;
}