1
0
mirror of https://github.com/moodle/moodle.git synced 2025-04-23 09:23:09 +02:00

Merge branch 'MDL-64774-master' of git://github.com/junpataleta/moodle

This commit is contained in:
Andrew Nicols 2019-03-06 15:41:11 +08:00
commit 5bf82d7d9c
2 changed files with 166 additions and 24 deletions

@ -205,9 +205,17 @@ class core_user_external extends external_api {
// Make sure we validate current user info as handled by current GUI. See user/editadvanced_form.php func validation().
if (!validate_email($user['email'])) {
throw new invalid_parameter_exception('Email address is invalid: '.$user['email']);
} else if (empty($CFG->allowaccountssameemail) &&
$DB->record_exists('user', array('email' => $user['email'], 'mnethostid' => $user['mnethostid']))) {
throw new invalid_parameter_exception('Email address already exists: '.$user['email']);
} else if (empty($CFG->allowaccountssameemail)) {
// Make a case-insensitive query for the given email address.
$select = $DB->sql_equal('email', ':email', false) . ' AND mnethostid = :mnethostid';
$params = array(
'email' => $user['email'],
'mnethostid' => $user['mnethostid']
);
// If there are other user(s) that already have the same email, throw an error.
if ($DB->record_exists_select('user', $select, $params)) {
throw new invalid_parameter_exception('Email address already exists: '.$user['email']);
}
}
// End of user info validation.
@ -587,9 +595,18 @@ class core_user_external extends external_api {
if (isset($user['email']) && $user['email'] !== $existinguser->email) {
if (!validate_email($user['email'])) {
continue;
} else if (empty($CFG->allowaccountssameemail) &&
$DB->record_exists('user', array('email' => $user['email'], 'mnethostid' => $CFG->mnet_localhost_id))) {
continue;
} else if (empty($CFG->allowaccountssameemail)) {
// Make a case-insensitive query for the given email address and make sure to exclude the user being updated.
$select = $DB->sql_equal('email', ':email', false) . ' AND mnethostid = :mnethostid AND id <> :userid';
$params = array(
'email' => $user['email'],
'mnethostid' => $CFG->mnet_localhost_id,
'userid' => $user['id']
);
// Skip if there are other user(s) that already have the same email.
if ($DB->record_exists_select('user', $select, $params)) {
continue;
}
}
}

@ -598,6 +598,71 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
core_user_external::create_users([$user]);
}
/**
* Data provider for \core_user_externallib_testcase::test_create_users_with_same_emails().
*/
public function create_users_provider_with_same_emails() {
return [
'Same emails allowed, same case' => [
1, false
],
'Same emails allowed, different case' => [
1, true
],
'Same emails disallowed, same case' => [
0, false
],
'Same emails disallowed, different case' => [
0, true
],
];
}
/**
* Test for \core_user_external::create_users() when user using the same email addresses are being created.
*
* @dataProvider create_users_provider_with_same_emails
* @param int $sameemailallowed The value to set for $CFG->allowaccountssameemail.
* @param boolean $differentcase Whether to user a different case for the other user.
*/
public function test_create_users_with_same_emails($sameemailallowed, $differentcase) {
global $DB;
$this->resetAfterTest();
$this->setAdminUser();
// Allow multiple users with the same email address.
set_config('allowaccountssameemail', $sameemailallowed);
$users = [
[
'username' => 's1',
'firstname' => 'Johnny',
'lastname' => 'Bravo',
'email' => 's1@example.com',
'password' => 'Passw0rd!'
],
[
'username' => 's2',
'firstname' => 'John',
'lastname' => 'Doe',
'email' => $differentcase ? 'S1@EXAMPLE.COM' : 's1@example.com',
'password' => 'Passw0rd!'
],
];
if (!$sameemailallowed) {
// This should throw an exception when $CFG->allowaccountssameemail is empty.
$this->expectException(invalid_parameter_exception::class);
}
// Create our users.
core_user_external::create_users($users);
// Confirm that the users have been created.
list($insql, $params) = $DB->get_in_or_equal(['s1', 's2']);
$this->assertEquals(2, $DB->count_records_select('user', 'username ' . $insql, $params));
}
/**
* Test create_users with invalid parameters
*
@ -831,28 +896,88 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
}
/**
* Test update_users using duplicated email.
* Data provider for testing \core_user_external::update_users() for users with same emails
*
* @return array
*/
public function test_update_users_duplicated_email() {
global $DB, $CFG;
public function users_with_same_emails() {
return [
'Same emails not allowed: Update name using exactly the same email' => [
0, 'John', 's1@example.com', 'Johnny', 's1@example.com', false, true
],
'Same emails not allowed: Update using someone else\'s email' => [
0, 'John', 's1@example.com', 'Johnny', 's2@example.com', true, false
],
'Same emails allowed: Update using someone else\'s email' => [
1, 'John', 's1@example.com', 'Johnny', 's2@example.com', true, true
],
'Same emails not allowed: Update using same email but with different case' => [
0, 'John', 's1@example.com', 'Johnny', 'S1@EXAMPLE.COM', false, true
],
'Same emails not allowed: Update using another user\'s email similar to user but with different case' => [
0, 'John', 's1@example.com', 'Johnny', 'S1@EXAMPLE.COM', true, false
],
'Same emails allowed: Update using another user\'s email similar to user but with different case' => [
1, 'John', 's1@example.com', 'Johnny', 'S1@EXAMPLE.COM', true, true
],
];
}
$this->resetAfterTest(true);
/**
* Test update_users using similar emails with varying cases.
*
* @dataProvider users_with_same_emails
* @param boolean $allowsameemail The value to set for $CFG->allowaccountssameemail.
* @param string $currentname The user's current name.
* @param string $currentemail The user's current email.
* @param string $newname The user's new name.
* @param string $newemail The user's new email.
* @param boolean $withanotheruser Whether to create another user that has the same email as the target user's new email.
* @param boolean $successexpected Whether we expect that the target user's email/name will be updated.
*/
public function test_update_users_emails_with_different_cases($allowsameemail, $currentname, $currentemail,
$newname, $newemail, $withanotheruser, $successexpected) {
global $DB;
$this->resetAfterTest();
$this->setAdminUser();
$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();
$user2toupdate = array(
'id' => $user2->id,
'email' => $user1->email,
);
// E-mail duplicated not allowed.
$CFG->allowaccountssameemail = 0;
core_user_external::update_users(array($user2toupdate));
$this->assertNotEquals($user1->email, $DB->get_field('user', 'email', array('id' => $user2->id)));
// E-mail duplicated allowed.
$CFG->allowaccountssameemail = 1;
core_user_external::update_users(array($user2toupdate));
$this->assertEquals($user1->email, $DB->get_field('user', 'email', array('id' => $user2->id)));
// Set the value for $CFG->allowaccountssameemail.
set_config('allowaccountssameemail', $allowsameemail);
$generator = self::getDataGenerator();
// Create the user that we wish to update.
$usertoupdate = $generator->create_user(['email' => $currentemail, 'firstname' => $currentname]);
if ($withanotheruser) {
// Create another user that has the same email as the new email that we'd like to update for our target user.
$generator->create_user(['email' => $newemail]);
}
// Build the user update parameters.
$updateparams = [
'id' => $usertoupdate->id,
'email' => $newemail,
'firstname' => $newname
];
// Let's try to update the user's information.
core_user_external::update_users([$updateparams]);
// Fetch the updated user record.
$userrecord = $DB->get_record('user', ['id' => $usertoupdate->id], 'id, email, firstname');
// If we expect the update to succeed, then the email/name would have been changed.
if ($successexpected) {
$expectedemail = $newemail;
$expectedname = $newname;
} else {
$expectedemail = $currentemail;
$expectedname = $currentname;
}
// Confirm that our expectations are met.
$this->assertEquals($expectedemail, $userrecord->email);
$this->assertEquals($expectedname, $userrecord->firstname);
}
/**