From c401d002c308fa35011feba74949d23dead6dbea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Wed, 22 Feb 2023 14:09:28 +0100 Subject: [PATCH] Ensure emails are always attached to current user --- src/User.php | 24 ++++---- tests/functional/User.php | 115 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 10 deletions(-) diff --git a/src/User.php b/src/User.php index 55b049550a0..ed559bd4686 100644 --- a/src/User.php +++ b/src/User.php @@ -1440,26 +1440,28 @@ public function updateUserEmails() $userUpdated = false; if (isset($this->input['_useremails']) && count($this->input['_useremails'])) { - $useremail = new UserEmail(); foreach ($this->input['_useremails'] as $id => $email) { $email = trim($email); - // existing email - if ($id > 0) { + $useremail = new UserEmail(); + if ($id > 0 && $useremail->getFromDB($id) && $useremail->fields['users_id'] === $this->getID()) { + // Existing email attached to current user + $params = ['id' => $id]; - // empty email : delete - if (strlen($email) == 0) { + if (strlen($email) === 0) { + // Empty email, delete it $deleted = $useremail->delete($params); $userUpdated = $userUpdated || $deleted; - } else { // Update email + } else { + // Update email $params['email'] = $email; $params['is_default'] = $this->input['_default_email'] == $id ? 1 : 0; $existingUserEmail = new UserEmail(); - $existingUserEmail->getFromDB($id); if ( - $params['email'] == $existingUserEmail->fields['email'] + $existingUserEmail->getFromDB($id) + && $params['email'] == $existingUserEmail->fields['email'] && $params['is_default'] == $existingUserEmail->fields['is_default'] ) { // Do not update if email has not changed @@ -1469,8 +1471,10 @@ public function updateUserEmails() $updated = $useremail->update($params); $userUpdated = $userUpdated || $updated; } - } else { // New email - $email_input = ['email' => $email, + } else { + // New email + $email_input = [ + 'email' => $email, 'users_id' => $this->fields['id'] ]; if ( diff --git a/tests/functional/User.php b/tests/functional/User.php index 40e50821598..b6e17387be5 100644 --- a/tests/functional/User.php +++ b/tests/functional/User.php @@ -158,6 +158,121 @@ public function testGetDefaultEmail() $this->boolean($user->isEmail($tu_user->getDefaultEmail()))->isFalse(); } + public function testUpdateEmail() + { + // Create a user with some emails + $user1 = new \User(); + $uid1 = (int)$user1->add([ + 'name' => 'test_email 1', + '_useremails' => [ + -1 => 'email1@test.com', + -2 => 'email2@test.com', + -3 => 'email3@test.com', + ] + ]); + $this->integer($uid1)->isGreaterThan(0); + + // Emails are all attached to user 1 + $user1_email1_id = current( + getAllDataFromTable(\UserEmail::getTable(), ['users_id' => $uid1, 'email' => 'email1@test.com']) + )['id'] ?? 0; + $this->integer($user1_email1_id)->isGreaterThan(0); + + $this->string($user1->getDefaultEmail())->isIdenticalTo('email1@test.com'); + + $this->boolean($user1->getFromDB($uid1))->isTrue(); + $user1_emails = $user1->getAllEmails(); + asort($user1_emails); + $this->array(array_values($user1_emails))->isEqualTo( + [ + 'email1@test.com', + 'email2@test.com', + 'email3@test.com', + ] + ); + + // Create another user + $user2 = new \User(); + $uid2 = (int)$user2->add([ + 'name' => 'test_email 2', + '_useremails' => [ + -1 => 'anotheremail1@test.com', + $user1_email1_id => 'anotheremail2@test.com', // try to change email from user 1 + -3 => 'anotheremail3@test.com', + ] + ]); + $this->integer($uid2)->isGreaterThan(0); + + // Emails are all attached to user 2 + $user2_email1_id = current( + getAllDataFromTable(\UserEmail::getTable(), ['users_id' => $uid2, 'email' => 'anotheremail1@test.com']) + )['id'] ?? 0; + $this->integer($user2_email1_id)->isGreaterThan(0); + + $this->string($user2->getDefaultEmail())->isIdenticalTo('anotheremail1@test.com'); + + $this->boolean($user2->getFromDB($uid2))->isTrue(); + $user2_emails = $user2->getAllEmails(); + asort($user2_emails); + $this->array(array_values($user2_emails))->isEqualTo( + [ + 'anotheremail1@test.com', + 'anotheremail2@test.com', + 'anotheremail3@test.com', + ] + ); + + // User 1 emails did not changed + $this->boolean($user1->getFromDB($uid1))->isTrue(); + $user1_emails = $user1->getAllEmails(); + asort($user1_emails); + $this->array(array_values($user1_emails))->isEqualTo( + [ + 'email1@test.com', + 'email2@test.com', + 'email3@test.com', + ] + ); + + // Update the second user + $update = $user2->update([ + 'id' => $uid2, + '_useremails' => [ + $user1_email1_id => 'email1-updated@test.com', // try to change email from user 1 + $user2_email1_id => 'anotheremail1-update@test.com', + ], + '_default_email' => $user1_email1_id, + ]); + $this->boolean($update)->isTrue(); + + // Emails are all attached to user 2 + $this->boolean($user2->getFromDB($uid2))->isTrue(); + $user2_emails = $user2->getAllEmails(); + asort($user2_emails); + $this->array(array_values($user2_emails))->isEqualTo( + [ + 'anotheremail1-update@test.com', + 'anotheremail2@test.com', + 'anotheremail3@test.com', + 'email1-updated@test.com', + ] + ); + + $this->string($user2->getDefaultEmail())->isIdenticalTo('email1-updated@test.com'); + + // User 1 emails did not changed + $this->boolean($user1->getFromDB($uid1))->isTrue(); + $user1_emails = $user1->getAllEmails(); + asort($user1_emails); + $this->array(array_values($user1_emails))->isEqualTo( + [ + 'email1@test.com', + 'email2@test.com', + 'email3@test.com', + ] + ); + } + public function testGetFromDBbyToken() { $user = $this->newTestedInstance;