aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Steinmetz <richard@steinmetz.cloud>2025-06-24 14:19:12 +0200
committerGitHub <noreply@github.com>2025-06-24 14:19:12 +0200
commitabced23a0939929008d1a4e464cbe8f668caa1c0 (patch)
treef4fe91e3954efa34310de821bafc5ef1d0acc7bb
parent8ee06edffc8469c3de6597b4e8d379657c533264 (diff)
parentb6af06d2e08b7e546fc30c9cb88d8a3d446abc2f (diff)
downloadnextcloud-server-abced23a0939929008d1a4e464cbe8f668caa1c0.tar.gz
nextcloud-server-abced23a0939929008d1a4e464cbe8f668caa1c0.zip
Merge pull request #53615 from nextcloud/fix/revive-lowercase-email
fix: revive always storing lowercased email addresses
-rw-r--r--build/integration/features/provisioning-v1.feature12
-rw-r--r--core/Migrations/Version32000Date20250620081925.php16
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/private/Config/UserConfig.php5
-rw-r--r--tests/lib/AllConfigTest.php21
-rw-r--r--tests/lib/Config/UserConfigTest.php13
-rw-r--r--version.php2
8 files changed, 70 insertions, 1 deletions
diff --git a/build/integration/features/provisioning-v1.feature b/build/integration/features/provisioning-v1.feature
index 6ace70a25be..6c35e5a68f1 100644
--- a/build/integration/features/provisioning-v1.feature
+++ b/build/integration/features/provisioning-v1.feature
@@ -187,6 +187,18 @@ Feature: provisioning
| timezoneOffset | 0 |
| pronouns | NULL |
+ Scenario: Edit a user with mixed case emails
+ Given As an "admin"
+ And user "brand-new-user" exists
+ And sending "PUT" to "/cloud/users/brand-new-user" with
+ | key | email |
+ | value | mixed-CASE@Nextcloud.com |
+ And the OCS status code should be "100"
+ And the HTTP status code should be "200"
+ Then user "brand-new-user" has
+ | id | brand-new-user |
+ | email | mixed-case@nextcloud.com |
+
Scenario: Edit a user account properties scopes
Given user "brand-new-user" exists
And As an "brand-new-user"
diff --git a/core/Migrations/Version32000Date20250620081925.php b/core/Migrations/Version32000Date20250620081925.php
new file mode 100644
index 00000000000..13e1ac0f87d
--- /dev/null
+++ b/core/Migrations/Version32000Date20250620081925.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OC\Core\Migrations;
+
+/**
+ * Run the old migration Version24000Date20211210141942 again.
+ */
+class Version32000Date20250620081925 extends Version24000Date20211210141942 {
+}
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 3bf63efce0f..c97549e395f 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -1472,6 +1472,7 @@ return array(
'OC\\Core\\Migrations\\Version31000Date20240101084401' => $baseDir . '/core/Migrations/Version31000Date20240101084401.php',
'OC\\Core\\Migrations\\Version31000Date20240814184402' => $baseDir . '/core/Migrations/Version31000Date20240814184402.php',
'OC\\Core\\Migrations\\Version31000Date20250213102442' => $baseDir . '/core/Migrations/Version31000Date20250213102442.php',
+ 'OC\\Core\\Migrations\\Version32000Date20250620081925' => $baseDir . '/core/Migrations/Version32000Date20250620081925.php',
'OC\\Core\\Notification\\CoreNotifier' => $baseDir . '/core/Notification/CoreNotifier.php',
'OC\\Core\\ResponseDefinitions' => $baseDir . '/core/ResponseDefinitions.php',
'OC\\Core\\Service\\LoginFlowV2Service' => $baseDir . '/core/Service/LoginFlowV2Service.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index f076aaca783..39880f3366f 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -1513,6 +1513,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Core\\Migrations\\Version31000Date20240101084401' => __DIR__ . '/../../..' . '/core/Migrations/Version31000Date20240101084401.php',
'OC\\Core\\Migrations\\Version31000Date20240814184402' => __DIR__ . '/../../..' . '/core/Migrations/Version31000Date20240814184402.php',
'OC\\Core\\Migrations\\Version31000Date20250213102442' => __DIR__ . '/../../..' . '/core/Migrations/Version31000Date20250213102442.php',
+ 'OC\\Core\\Migrations\\Version32000Date20250620081925' => __DIR__ . '/../../..' . '/core/Migrations/Version32000Date20250620081925.php',
'OC\\Core\\Notification\\CoreNotifier' => __DIR__ . '/../../..' . '/core/Notification/CoreNotifier.php',
'OC\\Core\\ResponseDefinitions' => __DIR__ . '/../../..' . '/core/ResponseDefinitions.php',
'OC\\Core\\Service\\LoginFlowV2Service' => __DIR__ . '/../../..' . '/core/Service/LoginFlowV2Service.php',
diff --git a/lib/private/Config/UserConfig.php b/lib/private/Config/UserConfig.php
index 77a86a5e1c7..1fdcfaa53a7 100644
--- a/lib/private/Config/UserConfig.php
+++ b/lib/private/Config/UserConfig.php
@@ -1045,6 +1045,11 @@ class UserConfig implements IUserConfig {
int $flags,
ValueType $type,
): bool {
+ // Primary email addresses are always(!) expected to be lowercase
+ if ($app === 'settings' && $key === 'email') {
+ $value = strtolower($value);
+ }
+
$this->assertParams($userId, $app, $key);
if (!$this->matchAndApplyLexiconDefinition($userId, $app, $key, $lazy, $type, $flags)) {
// returns false as database is not updated
diff --git a/tests/lib/AllConfigTest.php b/tests/lib/AllConfigTest.php
index ba48a078713..9d204754d96 100644
--- a/tests/lib/AllConfigTest.php
+++ b/tests/lib/AllConfigTest.php
@@ -93,6 +93,27 @@ class AllConfigTest extends \Test\TestCase {
$config->deleteUserValue('userSet', 'appSet', 'keySet');
}
+ /**
+ * This test needs to stay! Emails are expected to be lowercase due to performance reasons.
+ * This way we can skip the expensive casing change on the database.
+ */
+ public function testSetUserValueSettingsEmail(): void {
+ $selectAllSQL = 'SELECT `userid`, `appid`, `configkey`, `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ?';
+ $config = $this->getConfig();
+
+ $config->setUserValue('userSet', 'settings', 'email', 'mixed.CASE@domain.COM');
+
+ $result = $this->connection->executeQuery($selectAllSQL, ['userSet'])->fetchAll();
+
+ $this->assertEquals(1, count($result));
+ $this->assertEquals([
+ 'userid' => 'userSet',
+ 'appid' => 'settings',
+ 'configkey' => 'email',
+ 'configvalue' => 'mixed.case@domain.com'
+ ], $result[0]);
+ }
+
public function testSetUserValueWithPreCondition(): void {
$config = $this->getConfig();
diff --git a/tests/lib/Config/UserConfigTest.php b/tests/lib/Config/UserConfigTest.php
index 865575374d8..e27e831f425 100644
--- a/tests/lib/Config/UserConfigTest.php
+++ b/tests/lib/Config/UserConfigTest.php
@@ -1241,6 +1241,19 @@ class UserConfigTest extends TestCase {
}
}
+ /**
+ * This test needs to stay! Emails are expected to be lowercase due to performance reasons.
+ * This way we can skip the expensive casing change on the database.
+ */
+ public function testSetValueMixedWithSettingsEmail(): void {
+ $userConfig = $this->generateUserConfig();
+
+ $edited = $userConfig->setValueMixed('user1', 'settings', 'email', 'mixed.CASE@Nextcloud.com');
+ $this->assertTrue($edited);
+
+ $actual = $userConfig->getValueMixed('user1', 'settings', 'email');
+ $this->assertEquals('mixed.case@nextcloud.com', $actual);
+ }
public static function providerSetValueString(): array {
return [
diff --git a/version.php b/version.php
index 0b7a87cc96b..bb36c6f5831 100644
--- a/version.php
+++ b/version.php
@@ -9,7 +9,7 @@
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patch level
// when updating major/minor version number.
-$OC_Version = [32, 0, 0, 0];
+$OC_Version = [32, 0, 0, 1];
// The human-readable string
$OC_VersionString = '32.0.0 dev';