aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorskjnldsv <skjnldsv@protonmail.com>2025-07-09 19:43:02 +0200
committerskjnldsv <skjnldsv@protonmail.com>2025-07-10 09:10:01 +0200
commit027471b146913de0cb05fb9f98b379f266b0ca2d (patch)
tree6fb3a5d9ea75aa69d0bcdc670bb54ce0178e37e6
parent6cc5484f0e990fe3cbe03a944e77f794c2a88093 (diff)
downloadnextcloud-server-fix/lower-email-case.tar.gz
nextcloud-server-fix/lower-email-case.zip
fix: force lowercase emailsfix/lower-email-case
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
-rw-r--r--apps/provisioning_api/lib/Controller/AUserDataOCSController.php3
-rw-r--r--apps/provisioning_api/lib/Controller/UsersController.php8
-rw-r--r--apps/provisioning_api/tests/Controller/UsersControllerTest.php49
-rw-r--r--build/psalm-baseline.xml2
-rw-r--r--core/Command/User/Setting.php3
-rw-r--r--lib/private/User/User.php8
6 files changed, 63 insertions, 10 deletions
diff --git a/apps/provisioning_api/lib/Controller/AUserDataOCSController.php b/apps/provisioning_api/lib/Controller/AUserDataOCSController.php
index 8840bb09403..8c0763f4378 100644
--- a/apps/provisioning_api/lib/Controller/AUserDataOCSController.php
+++ b/apps/provisioning_api/lib/Controller/AUserDataOCSController.php
@@ -142,7 +142,8 @@ abstract class AUserDataOCSController extends OCSController {
$additionalEmails = $additionalEmailScopes = [];
$emailCollection = $userAccount->getPropertyCollection(IAccountManager::COLLECTION_EMAIL);
foreach ($emailCollection->getProperties() as $property) {
- $additionalEmails[] = $property->getValue();
+ $email = mb_strtolower(trim($property->getValue()));
+ $additionalEmails[] = $email;
if ($includeScopes) {
$additionalEmailScopes[] = $property->getScope();
}
diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php
index 9136ded5b7a..51b18306b51 100644
--- a/apps/provisioning_api/lib/Controller/UsersController.php
+++ b/apps/provisioning_api/lib/Controller/UsersController.php
@@ -537,6 +537,7 @@ class UsersController extends AUserDataOCSController {
$generatePasswordResetToken = true;
}
+ $email = mb_strtolower(trim($email));
if ($email === '' && $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes') {
throw new OCSException($this->l10n->t('Required email address was not provided'), 110);
}
@@ -583,7 +584,7 @@ class UsersController extends AUserDataOCSController {
// Send new user mail only if a mail is set
if ($email !== '') {
- $newUser->setEMailAddress($email);
+ $newUser->setSystemEMailAddress($email);
if ($this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes') {
try {
$emailTemplate = $this->newUserMailHelper->generateTemplate($newUser, $generatePasswordResetToken);
@@ -857,6 +858,7 @@ class UsersController extends AUserDataOCSController {
$mailCollection = $userAccount->getPropertyCollection(IAccountManager::COLLECTION_EMAIL);
$mailCollection->removePropertyByValue($key);
if ($value !== '') {
+ $value = mb_strtolower(trim($value));
$mailCollection->addPropertyWithDefaults($value);
$property = $mailCollection->getPropertyByValue($key);
if ($isAdminOrSubadmin && $property) {
@@ -1142,13 +1144,15 @@ class UsersController extends AUserDataOCSController {
}
break;
case IAccountManager::PROPERTY_EMAIL:
+ $value = mb_strtolower(trim($value));
if (filter_var($value, FILTER_VALIDATE_EMAIL) || $value === '') {
- $targetUser->setEMailAddress($value);
+ $targetUser->setSystemEMailAddress($value);
} else {
throw new OCSException('', 101);
}
break;
case IAccountManager::COLLECTION_EMAIL:
+ $value = mb_strtolower(trim($value));
if (filter_var($value, FILTER_VALIDATE_EMAIL) && $value !== $targetUser->getSystemEMailAddress()) {
$userAccount = $this->accountManager->getAccount($targetUser);
$mailCollection = $userAccount->getPropertyCollection(IAccountManager::COLLECTION_EMAIL);
diff --git a/apps/provisioning_api/tests/Controller/UsersControllerTest.php b/apps/provisioning_api/tests/Controller/UsersControllerTest.php
index cf35a4fb324..85ec9e374d6 100644
--- a/apps/provisioning_api/tests/Controller/UsersControllerTest.php
+++ b/apps/provisioning_api/tests/Controller/UsersControllerTest.php
@@ -609,7 +609,7 @@ class UsersControllerTest extends TestCase {
->willReturn(false);
$newUser = $this->createMock(IUser::class);
$newUser->expects($this->once())
- ->method('setEMailAddress');
+ ->method('setSystemEMailAddress');
$this->userManager
->expects($this->once())
->method('createUser')
@@ -645,6 +645,51 @@ class UsersControllerTest extends TestCase {
));
}
+ public function testAddUserSuccessfulLowercaseEmail(): void {
+ $this->userManager
+ ->expects($this->once())
+ ->method('userExists')
+ ->with('NewUser')
+ ->willReturn(false);
+ $newUser = $this->createMock(IUser::class);
+ $newUser->expects($this->once())
+ ->method('setSystemEMailAddress')
+ ->with('foo@bar.com');
+ $this->userManager
+ ->expects($this->once())
+ ->method('createUser')
+ ->willReturn($newUser);
+ $this->logger
+ ->expects($this->once())
+ ->method('info')
+ ->with('Successful addUser call with userid: NewUser', ['app' => 'ocs_api']);
+ $loggedInUser = $this->getMockBuilder(IUser::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $loggedInUser
+ ->expects($this->exactly(2))
+ ->method('getUID')
+ ->willReturn('adminUser');
+ $this->userSession
+ ->expects($this->once())
+ ->method('getUser')
+ ->willReturn($loggedInUser);
+ $this->groupManager
+ ->expects($this->once())
+ ->method('isAdmin')
+ ->with('adminUser')
+ ->willReturn(true);
+ $this->eventDispatcher
+ ->expects($this->once())
+ ->method('dispatchTyped')
+ ->with(new GenerateSecurePasswordEvent());
+
+ $this->assertTrue(key_exists(
+ 'id',
+ $this->api->addUser('NewUser', '', '', 'fOo@BaR.CoM')->getData()
+ ));
+ }
+
public function testAddUserFailedToGenerateUserID(): void {
$this->expectException(OCSException::class);
@@ -1629,7 +1674,7 @@ class UsersControllerTest extends TestCase {
->willReturn($targetUser);
$targetUser
->expects($this->once())
- ->method('setEMailAddress')
+ ->method('setSystemEMailAddress')
->with('demo@nextcloud.com');
$targetUser
->expects($this->any())
diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml
index 21007bec0bf..63c24b64c30 100644
--- a/build/psalm-baseline.xml
+++ b/build/psalm-baseline.xml
@@ -1992,8 +1992,6 @@
<code><![CDATA[implementsActions]]></code>
<code><![CDATA[implementsActions]]></code>
<code><![CDATA[implementsActions]]></code>
- <code><![CDATA[setEMailAddress]]></code>
- <code><![CDATA[setEMailAddress]]></code>
</DeprecatedMethod>
<TypeDoesNotContainNull>
<code><![CDATA[$groupid === null]]></code>
diff --git a/core/Command/User/Setting.php b/core/Command/User/Setting.php
index 16e851d8252..7fc5aab1dc7 100644
--- a/core/Command/User/Setting.php
+++ b/core/Command/User/Setting.php
@@ -155,7 +155,8 @@ class Setting extends Base {
$user = $this->userManager->get($uid);
if ($user instanceof IUser) {
if ($key === 'email') {
- $user->setEMailAddress($input->getArgument('value'));
+ $email = $input->getArgument('value');
+ $user->setSystemEMailAddress(mb_strtolower(trim($email)));
} elseif ($key === 'display_name') {
if (!$user->setDisplayName($input->getArgument('value'))) {
if ($user->getDisplayName() === $input->getArgument('value')) {
diff --git a/lib/private/User/User.php b/lib/private/User/User.php
index 88ed0d44387..1f908918b20 100644
--- a/lib/private/User/User.php
+++ b/lib/private/User/User.php
@@ -154,6 +154,7 @@ class User implements IUser {
*/
public function setSystemEMailAddress(string $mailAddress): void {
$oldMailAddress = $this->getSystemEMailAddress();
+ $mailAddress = mb_strtolower(trim($mailAddress));
if ($mailAddress === '') {
$this->config->deleteUserValue($this->uid, 'settings', 'email');
@@ -176,6 +177,7 @@ class User implements IUser {
* @inheritDoc
*/
public function setPrimaryEMailAddress(string $mailAddress): void {
+ $mailAddress = mb_strtolower(trim($mailAddress));
if ($mailAddress === '') {
$this->config->deleteUserValue($this->uid, 'settings', 'primary_email');
return;
@@ -514,14 +516,16 @@ class User implements IUser {
* @inheritDoc
*/
public function getSystemEMailAddress(): ?string {
- return $this->config->getUserValue($this->uid, 'settings', 'email', null);
+ $email = $this->config->getUserValue($this->uid, 'settings', 'email', null);
+ return $email ? mb_strtolower(trim($email)) : null;
}
/**
* @inheritDoc
*/
public function getPrimaryEMailAddress(): ?string {
- return $this->config->getUserValue($this->uid, 'settings', 'primary_email', null);
+ $email = $this->config->getUserValue($this->uid, 'settings', 'primary_email', null);
+ return $email ? mb_strtolower(trim($email)) : null;
}
/**