MDL-67499 user: truncate long username/email during user deletion.

This commit is contained in:
Paul Holden 2019-12-31 13:18:29 +00:00
parent 1d4fdb0d1c
commit 343380d9c8
2 changed files with 61 additions and 2 deletions

View File

@ -4302,7 +4302,13 @@ function delete_user(stdClass $user) {
// 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);
$deltime = time();
$deltimelength = core_text::strlen((string) $deltime);
// Max username length is 100 chars. Select up to limit - (length of current time + 1 [period character]) from users email.
$delname = clean_param($delemail, PARAM_USERNAME);
$delname = core_text::substr($delname, 0, 100 - ($deltimelength + 1)) . ".{$deltime}";
// 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.
@ -4317,7 +4323,7 @@ function delete_user(stdClass $user) {
$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();
$updateuser->timemodified = $deltime;
// Don't trigger update event, as user is being deleted.
user_update_user($updateuser, false, false);

View File

@ -2465,6 +2465,59 @@ class core_moodlelib_testcase extends advanced_testcase {
$this->resetDebugging();
}
/**
* Test deletion of user with long username
*/
public function test_delete_user_long_username() {
global $DB;
$this->resetAfterTest();
// For users without an e-mail, one will be created during deletion using {$username}.{$id}@unknownemail.invalid format.
$user = $this->getDataGenerator()->create_user([
'username' => str_repeat('a', 75),
'email' => '',
]);
delete_user($user);
// The username for the deleted user shouldn't exceed 100 characters.
$usernamedeleted = $DB->get_field('user', 'username', ['id' => $user->id]);
$this->assertEquals(100, core_text::strlen($usernamedeleted));
$timestrlength = core_text::strlen((string) time());
// It should start with the user name, and end with the current time.
$this->assertStringStartsWith("{$user->username}.{$user->id}@", $usernamedeleted);
$this->assertRegExp('/\.\d{' . $timestrlength . '}$/', $usernamedeleted);
}
/**
* Test deletion of user with long email address
*/
public function test_delete_user_long_email() {
global $DB;
$this->resetAfterTest();
// Create user with 90 character email address.
$user = $this->getDataGenerator()->create_user([
'email' => str_repeat('a', 78) . '@example.com',
]);
delete_user($user);
// The username for the deleted user shouldn't exceed 100 characters.
$usernamedeleted = $DB->get_field('user', 'username', ['id' => $user->id]);
$this->assertEquals(100, core_text::strlen($usernamedeleted));
$timestrlength = core_text::strlen((string) time());
// Max username length is 100 chars. Select up to limit - (length of current time + 1 [period character]) from users email.
$expectedemail = core_text::substr($user->email, 0, 100 - ($timestrlength + 1));
$this->assertRegExp('/^' . preg_quote($expectedemail) . '\.\d{' . $timestrlength . '}$/', $usernamedeleted);
}
/**
* Test function convert_to_array()
*/