Skip to content

Commit d30428a

Browse files
pringelmannbackportbot[bot]
authored andcommitted
fix(core): accept deprecated IANA timezone aliases
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
1 parent e9508ea commit d30428a

5 files changed

Lines changed: 116 additions & 7 deletions

File tree

apps/provisioning_api/lib/Controller/UsersController.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,8 @@ public function editUser(string $userId, string $key, string $value): DataRespon
11321132
$this->config->setUserValue($targetUser->getUID(), 'core', 'locale', $value);
11331133
break;
11341134
case self::USER_FIELD_TIMEZONE:
1135-
if (!in_array($value, \DateTimeZone::listIdentifiers())) {
1135+
// Older browsers still report deprecated aliases like Europe/Kiev.
1136+
if (!in_array($value, \DateTimeZone::listIdentifiers(\DateTimeZone::ALL_WITH_BC))) {
11361137
throw new OCSException($this->l10n->t('Invalid timezone'), 101);
11371138
}
11381139
$this->config->setUserValue($targetUser->getUID(), 'core', 'timezone', $value);

apps/provisioning_api/tests/Controller/UsersControllerTest.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2618,6 +2618,92 @@ public function testEditUserAdminEditChangeLanguageInvalidLanguage(): void {
26182618
$this->assertEquals([], $this->api->editUser('UserToEdit', 'language', 'ru')->getData());
26192619
}
26202620

2621+
public static function dataEditUserSelfEditChangeTimezone(): array {
2622+
return [
2623+
'primary identifier' => ['Europe/Kyiv'],
2624+
'backward compatible alias' => ['Europe/Kiev'],
2625+
'legacy region alias' => ['US/Eastern'],
2626+
];
2627+
}
2628+
2629+
#[\PHPUnit\Framework\Attributes\DataProvider('dataEditUserSelfEditChangeTimezone')]
2630+
public function testEditUserSelfEditChangeTimezone(string $timezone): void {
2631+
$loggedInUser = $this->createMock(IUser::class);
2632+
$loggedInUser
2633+
->expects($this->any())
2634+
->method('getUID')
2635+
->willReturn('UserToEdit');
2636+
$targetUser = $this->createMock(IUser::class);
2637+
$this->config->expects($this->once())
2638+
->method('setUserValue')
2639+
->with('UserToEdit', 'core', 'timezone', $timezone);
2640+
$this->userSession
2641+
->expects($this->once())
2642+
->method('getUser')
2643+
->willReturn($loggedInUser);
2644+
$this->userManager
2645+
->expects($this->once())
2646+
->method('get')
2647+
->with('UserToEdit')
2648+
->willReturn($targetUser);
2649+
$this->groupManager
2650+
->expects($this->atLeastOnce())
2651+
->method('isAdmin')
2652+
->with('UserToEdit')
2653+
->willReturn(false);
2654+
$targetUser
2655+
->expects($this->any())
2656+
->method('getUID')
2657+
->willReturn('UserToEdit');
2658+
2659+
$backend = $this->createMock(UserInterface::class);
2660+
$targetUser
2661+
->expects($this->any())
2662+
->method('getBackend')
2663+
->willReturn($backend);
2664+
2665+
$this->assertEquals([], $this->api->editUser('UserToEdit', 'timezone', $timezone)->getData());
2666+
}
2667+
2668+
public function testEditUserSelfEditChangeTimezoneInvalid(): void {
2669+
$this->expectException(OCSException::class);
2670+
2671+
$loggedInUser = $this->createMock(IUser::class);
2672+
$loggedInUser
2673+
->expects($this->any())
2674+
->method('getUID')
2675+
->willReturn('UserToEdit');
2676+
$targetUser = $this->createMock(IUser::class);
2677+
$this->config->expects($this->never())
2678+
->method('setUserValue');
2679+
$this->userSession
2680+
->expects($this->once())
2681+
->method('getUser')
2682+
->willReturn($loggedInUser);
2683+
$this->userManager
2684+
->expects($this->once())
2685+
->method('get')
2686+
->with('UserToEdit')
2687+
->willReturn($targetUser);
2688+
$this->groupManager
2689+
->expects($this->atLeastOnce())
2690+
->method('isAdmin')
2691+
->with('UserToEdit')
2692+
->willReturn(false);
2693+
$targetUser
2694+
->expects($this->any())
2695+
->method('getUID')
2696+
->willReturn('UserToEdit');
2697+
2698+
$backend = $this->createMock(UserInterface::class);
2699+
$targetUser
2700+
->expects($this->any())
2701+
->method('getBackend')
2702+
->willReturn($backend);
2703+
2704+
$this->api->editUser('UserToEdit', 'timezone', 'Mars/Olympus_Mons');
2705+
}
2706+
26212707
public function testEditUserSubadminUserAccessible(): void {
26222708
$this->config
26232709
->expects($this->once())

lib/private/Authentication/Login/SetUserTimezoneCommand.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public function process(LoginData $loginData): LoginResult {
4242
}
4343

4444
private function isValidTimezone(?string $value): bool {
45-
return $value && in_array($value, \DateTimeZone::listIdentifiers());
45+
// Older browsers still report deprecated aliases like Europe/Kiev.
46+
return $value && in_array($value, \DateTimeZone::listIdentifiers(\DateTimeZone::ALL_WITH_BC));
4647
}
4748
}

tests/lib/Authentication/Login/ALoginTestCommand.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,14 @@ protected function getLoggedInLoginDataWithRedirectUrl(): LoginData {
9090
return $data;
9191
}
9292

93-
protected function getLoggedInLoginDataWithTimezone(): LoginData {
93+
protected function getLoggedInLoginDataWithTimezone(?string $timezone = null): LoginData {
9494
$data = new LoginData(
9595
$this->request,
9696
$this->username,
9797
$this->password,
9898
true,
9999
null,
100-
$this->timezone,
100+
$timezone ?? $this->timezone,
101101
$this->timeZoneOffset
102102
);
103103
$data->setUser($this->user);

tests/lib/Authentication/Login/SetUserTimezoneCommandTest.php

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,17 @@ public function testProcessNoTimezoneSet(): void {
4444
$this->assertTrue($result->isSuccess());
4545
}
4646

47-
public function testProcess(): void {
48-
$data = $this->getLoggedInLoginDataWithTimezone();
47+
public static function dataAcceptedTimezone(): array {
48+
return [
49+
'primary identifier' => ['Europe/Vienna'],
50+
'backward compatible alias' => ['Europe/Kiev'],
51+
'legacy region alias' => ['US/Eastern'],
52+
];
53+
}
54+
55+
#[\PHPUnit\Framework\Attributes\DataProvider('dataAcceptedTimezone')]
56+
public function testProcess(string $timezone): void {
57+
$data = $this->getLoggedInLoginDataWithTimezone($timezone);
4958
$this->user->expects($this->once())
5059
->method('getUID')
5160
->willReturn($this->username);
@@ -64,7 +73,7 @@ public function testProcess(): void {
6473
$this->username,
6574
'core',
6675
'timezone',
67-
$this->timezone
76+
$timezone
6877
);
6978
$this->session->expects($this->once())
7079
->method('set')
@@ -78,6 +87,18 @@ public function testProcess(): void {
7887
$this->assertTrue($result->isSuccess());
7988
}
8089

90+
public function testProcessUnknownTimezone(): void {
91+
$data = $this->getLoggedInLoginDataWithTimezone('Mars/Olympus_Mons');
92+
$this->config->expects($this->never())
93+
->method('setUserValue');
94+
$this->session->expects($this->never())
95+
->method('set');
96+
97+
$result = $this->cmd->process($data);
98+
99+
$this->assertTrue($result->isSuccess());
100+
}
101+
81102
public function testProcessAlreadySet(): void {
82103
$data = $this->getLoggedInLoginDataWithTimezone();
83104
$this->user->expects($this->once())

0 commit comments

Comments
 (0)