Skip to content

Commit a402a84

Browse files
committed
fix: revive always storing lowercased email addresses
Signed-off-by: Richard Steinmetz <[email protected]>
1 parent 9fbda3e commit a402a84

File tree

8 files changed

+70
-1
lines changed

8 files changed

+70
-1
lines changed

build/integration/features/provisioning-v1.feature

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,18 @@ Feature: provisioning
187187
| timezoneOffset | 0 |
188188
| pronouns | NULL |
189189

190+
Scenario: Edit a user with mixed case emails
191+
Given As an "admin"
192+
And user "brand-new-user" exists
193+
And sending "PUT" to "/cloud/users/brand-new-user" with
194+
| key | email |
195+
| value | mixed-CASE@Nextcloud.com |
196+
And the OCS status code should be "100"
197+
And the HTTP status code should be "200"
198+
Then user "brand-new-user" has
199+
| id | brand-new-user |
200+
| email | mixed-case@nextcloud.com |
201+
190202
Scenario: Edit a user account properties scopes
191203
Given user "brand-new-user" exists
192204
And As an "brand-new-user"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OC\Core\Migrations;
11+
12+
/**
13+
* Run the old migration Version24000Date20211210141942 again.
14+
*/
15+
class Version32000Date20250620081925 extends Version24000Date20211210141942 {
16+
}

lib/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,7 @@
14591459
'OC\\Core\\Migrations\\Version31000Date20240101084401' => $baseDir . '/core/Migrations/Version31000Date20240101084401.php',
14601460
'OC\\Core\\Migrations\\Version31000Date20240814184402' => $baseDir . '/core/Migrations/Version31000Date20240814184402.php',
14611461
'OC\\Core\\Migrations\\Version31000Date20250213102442' => $baseDir . '/core/Migrations/Version31000Date20250213102442.php',
1462+
'OC\\Core\\Migrations\\Version32000Date20250620081925' => $baseDir . '/core/Migrations/Version32000Date20250620081925.php',
14621463
'OC\\Core\\Notification\\CoreNotifier' => $baseDir . '/core/Notification/CoreNotifier.php',
14631464
'OC\\Core\\ResponseDefinitions' => $baseDir . '/core/ResponseDefinitions.php',
14641465
'OC\\Core\\Service\\LoginFlowV2Service' => $baseDir . '/core/Service/LoginFlowV2Service.php',

lib/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,6 +1508,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
15081508
'OC\\Core\\Migrations\\Version31000Date20240101084401' => __DIR__ . '/../../..' . '/core/Migrations/Version31000Date20240101084401.php',
15091509
'OC\\Core\\Migrations\\Version31000Date20240814184402' => __DIR__ . '/../../..' . '/core/Migrations/Version31000Date20240814184402.php',
15101510
'OC\\Core\\Migrations\\Version31000Date20250213102442' => __DIR__ . '/../../..' . '/core/Migrations/Version31000Date20250213102442.php',
1511+
'OC\\Core\\Migrations\\Version32000Date20250620081925' => __DIR__ . '/../../..' . '/core/Migrations/Version32000Date20250620081925.php',
15111512
'OC\\Core\\Notification\\CoreNotifier' => __DIR__ . '/../../..' . '/core/Notification/CoreNotifier.php',
15121513
'OC\\Core\\ResponseDefinitions' => __DIR__ . '/../../..' . '/core/ResponseDefinitions.php',
15131514
'OC\\Core\\Service\\LoginFlowV2Service' => __DIR__ . '/../../..' . '/core/Service/LoginFlowV2Service.php',

lib/private/Config/UserConfig.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,11 @@ private function setTypedValue(
10581058
int $flags,
10591059
ValueType $type,
10601060
): bool {
1061+
// Primary email addresses are always(!) expected to be lowercase
1062+
if ($app === 'settings' && $key === 'email') {
1063+
$value = strtolower($value);
1064+
}
1065+
10611066
$this->assertParams($userId, $app, $key);
10621067
if (!$this->matchAndApplyLexiconDefinition($userId, $app, $key, $lazy, $type, $flags)) {
10631068
// returns false as database is not updated

tests/lib/AllConfigTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,27 @@ public function testSetUserValue(): void {
9191
$config->deleteUserValue('userSet', 'appSet', 'keySet');
9292
}
9393

94+
/**
95+
* This test needs to stay! Emails are expected to be lowercase due to performance reasons.
96+
* This way we can skip the expensive casing change on the database.
97+
*/
98+
public function testSetUserValueSettingsEmail(): void {
99+
$selectAllSQL = 'SELECT `userid`, `appid`, `configkey`, `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ?';
100+
$config = $this->getConfig();
101+
102+
$config->setUserValue('userSet', 'settings', 'email', '[email protected]');
103+
104+
$result = $this->connection->executeQuery($selectAllSQL, ['userSet'])->fetchAll();
105+
106+
$this->assertEquals(1, count($result));
107+
$this->assertEquals([
108+
'userid' => 'userSet',
109+
'appid' => 'settings',
110+
'configkey' => 'email',
111+
'configvalue' => '[email protected]'
112+
], $result[0]);
113+
}
114+
94115
public function testSetUserValueWithPreCondition(): void {
95116
$config = $this->getConfig();
96117

tests/lib/Config/UserConfigTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,6 +1249,19 @@ public function testSetValueMixed(
12491249
}
12501250
}
12511251

1252+
/**
1253+
* This test needs to stay! Emails are expected to be lowercase due to performance reasons.
1254+
* This way we can skip the expensive casing change on the database.
1255+
*/
1256+
public function testSetValueMixedWithSettingsEmail(): void {
1257+
$userConfig = $this->generateUserConfig();
1258+
1259+
$edited = $userConfig->setValueMixed('user1', 'settings', 'email', '[email protected]');
1260+
$this->assertTrue($edited);
1261+
1262+
$actual = $userConfig->getValueMixed('user1', 'settings', 'email');
1263+
$this->assertEquals('[email protected]', $actual);
1264+
}
12521265

12531266
public function providerSetValueString(): array {
12541267
return [

version.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patch level
1010
// when updating major/minor version number.
1111

12-
$OC_Version = [31, 0, 6, 2];
12+
$OC_Version = [31, 0, 6, 3];
1313

1414
// The human-readable string
1515
$OC_VersionString = '31.0.6';

0 commit comments

Comments
 (0)