Skip to content

Commit ca55418

Browse files
authored
Merge branch 'master' into master
2 parents c0ad41d + 8c90d4f commit ca55418

File tree

3 files changed

+99
-39
lines changed

3 files changed

+99
-39
lines changed

lib/private/Files/Type/Detection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ private function loadCustomDefinitions(string $fileName, array $definitions): ar
9797
if (file_exists($this->customConfigDir . '/' . $fileName)) {
9898
$custom = json_decode(file_get_contents($this->customConfigDir . '/' . $fileName), true);
9999
if (json_last_error() === JSON_ERROR_NONE) {
100-
$definitions = array_merge($definitions, $custom);
100+
$definitions = array_replace($definitions, $custom);
101101
} else {
102102
$this->logger->warning('Failed to parse ' . $fileName . ': ' . json_last_error_msg());
103103
}

lib/public/IUserSession.php

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,94 @@
11
<?php
22

33
/**
4-
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
4+
* SPDX-FileCopyrightText: 2016-2025 Nextcloud GmbH and Nextcloud contributors
55
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
66
* SPDX-License-Identifier: AGPL-3.0-only
77
*/
8-
// use OCP namespace for all classes that are considered public.
9-
// This means that they should be used by apps instead of the internal Nextcloud classes
108

119
namespace OCP;
1210

1311
/**
14-
* User session
12+
* Interface for managing and querying user session state.
13+
*
14+
* Provides methods for authenticating users, accessing the active user,
15+
* and handling login/logout functionality in a Nextcloud server session.
1516
* @since 6.0.0
1617
*/
1718
interface IUserSession {
1819
/**
19-
* Do a user login
20+
* Attempts to authenticate the given user and start a session.
2021
*
21-
* @param string $uid the username
22-
* @param string $password the password
23-
* @return bool true if successful
22+
* @param string $uid The user's unique identifier (username).
23+
* @param string $password The user's plain-text password.
24+
* @return bool True on successful login, false otherwise.
2425
* @since 6.0.0
2526
*/
2627
public function login($uid, $password);
2728

2829
/**
29-
* Logs the user out including all the session data
30-
* Logout, destroys session
30+
* Logs out the current user and terminates their session.
31+
*
32+
* Clears authentication tokens and user-related session data.
3133
*
3234
* @return void
3335
* @since 6.0.0
3436
*/
3537
public function logout();
3638

3739
/**
38-
* set the currently active user
40+
* Sets the current active user for this session.
41+
*
42+
* Pass null to clear the active user and log out any existing session.
3943
*
40-
* @param \OCP\IUser|null $user
44+
* @param \OCP\IUser|null $user The user to set as active, or null to unset.
4145
* @since 8.0.0
4246
*/
4347
public function setUser($user);
4448

4549
/**
46-
* Temporarily set the currently active user without persisting in the session
50+
* Temporarily sets the active user for this session without persisting it in the session storage.
51+
*
52+
* Useful for request-scoped user overrides that do not affect the actual session state.
4753
*
48-
* @param IUser|null $user
54+
* @param \OCP\IUser|null $user The user to set as active, or null to clear.
4955
* @since 29.0.0
5056
*/
5157
public function setVolatileActiveUser(?IUser $user): void;
5258

5359
/**
54-
* get the current active user
60+
* Returns the currently authenticated user for this session, or null if the session has no active user.
5561
*
56-
* @return \OCP\IUser|null Current user, otherwise null
62+
* @return \OCP\IUser|null The active user, or null if the session is anonymous, expired, or in incognito mode.
5763
* @since 8.0.0
5864
*/
5965
public function getUser();
6066

6167
/**
62-
* Checks whether the user is logged in
68+
* Checks whether a user is currently logged in for this session.
6369
*
64-
* @return bool if logged in
70+
* @return bool True if a user is authenticated and enabled, false otherwise.
6571
* @since 8.0.0
6672
*/
6773
public function isLoggedIn();
6874

6975
/**
70-
* get getImpersonatingUserID
76+
* Returns the user ID of the impersonator if another user is being impersonated.
7177
*
72-
* @return string|null
78+
* @return string|null The impersonating user's ID, or null if not impersonating.
7379
* @since 18.0.0
7480
*/
7581
public function getImpersonatingUserID(): ?string;
7682

7783
/**
78-
* set setImpersonatingUserID
84+
* Sets or clears the impersonator's user ID in the current session.
85+
*
86+
* Note: This does not initiate impersonation, but only records the identity of the impersonator in the session.
87+
*
88+
* If $useCurrentUser is true (default), records the current user's ID as the impersonator.
89+
* If false, removes any impersonator information from the session.
7990
*
91+
* @param bool $useCurrentUser Whether to assign the current user as the impersonator or to clear it.
8092
* @since 18.0.0
8193
*/
8294
public function setImpersonatingUserID(bool $useCurrentUser = true): void;

tests/lib/Files/Type/DetectionTest.php

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -117,24 +117,72 @@ public static function dataMimeTypeCustom(): array {
117117
*/
118118
#[\PHPUnit\Framework\Attributes\DataProvider('dataMimeTypeCustom')]
119119
public function testDetectMimeTypeCustom(string $ext, string $mime): void {
120-
$confDir = sys_get_temp_dir();
121-
file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([]));
122-
123-
/** @var IURLGenerator $urlGenerator */
124-
$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
125-
->disableOriginalConstructor()
126-
->getMock();
127-
128-
/** @var LoggerInterface $logger */
129-
$logger = $this->createMock(LoggerInterface::class);
130-
131-
// Create new mapping file
132-
file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([$ext => [$mime]]));
120+
$tmpDir = sys_get_temp_dir() . '/nc-detect-' . uniqid('', true);
121+
mkdir($tmpDir, 0700);
122+
123+
try {
124+
// Create a default / shipped mapping file (dist)
125+
file_put_contents($tmpDir . '/mimetypemapping.dist.json', json_encode([]));
126+
127+
// Create new custom mapping file that should be picked up by Detection
128+
file_put_contents($tmpDir . '/mimetypemapping.json', json_encode([$ext => [$mime]]));
129+
130+
/** @var IURLGenerator $urlGenerator */
131+
$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
132+
->disableOriginalConstructor()
133+
->getMock();
134+
135+
/** @var LoggerInterface $logger */
136+
$logger = $this->createMock(LoggerInterface::class);
137+
138+
$detection = new Detection($urlGenerator, $logger, $tmpDir, $tmpDir);
139+
$mappings = $detection->getAllMappings();
140+
141+
$this->assertArrayHasKey($ext, $mappings);
142+
$this->assertEquals($mime, $detection->detectPath('foo.' . $ext));
143+
} finally {
144+
// cleanup
145+
@unlink($tmpDir . '/mimetypemapping.json');
146+
@unlink($tmpDir . '/mimetypemapping.dist.json');
147+
@rmdir($tmpDir);
148+
}
149+
}
133150

134-
$detection = new Detection($urlGenerator, $logger, $confDir, $confDir);
135-
$mappings = $detection->getAllMappings();
136-
$this->assertArrayHasKey($ext, $mappings);
137-
$this->assertEquals($mime, $detection->detectPath('foo.' . $ext));
151+
public function testDetectMimeTypePreservesLeadingZeroKeys(): void {
152+
$tmpDir = sys_get_temp_dir() . '/nc-detect-' . uniqid();
153+
mkdir($tmpDir, 0700);
154+
try {
155+
// Create a default / shipped mapping file (dist)
156+
file_put_contents($tmpDir . '/mimetypemapping.dist.json', json_encode([]));
157+
158+
// Create new custom mapping file with potentially problematic keys
159+
$mappings = [
160+
'001' => ['application/x-zeroone', null],
161+
'1' => ['application/x-one', null],
162+
];
163+
file_put_contents($tmpDir . '/mimetypemapping.json', json_encode($mappings));
164+
165+
/** @var IURLGenerator $urlGenerator */
166+
$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
167+
->disableOriginalConstructor()
168+
->getMock();
169+
170+
/** @var LoggerInterface $logger */
171+
$logger = $this->createMock(LoggerInterface::class);
172+
173+
$detection = new Detection($urlGenerator, $logger, $tmpDir, $tmpDir);
174+
$mappings = $detection->getAllMappings();
175+
176+
$this->assertArrayHasKey('001', $mappings, 'Expected mapping to contain key "001"');
177+
$this->assertArrayHasKey('1', $mappings, 'Expected mapping to contain key "1"');
178+
179+
$this->assertEquals('application/x-zeroone', $detection->detectPath('foo.001'));
180+
$this->assertEquals('application/x-one', $detection->detectPath('foo.1'));
181+
} finally {
182+
@unlink($tmpDir . '/mimetypemapping.json');
183+
@unlink($tmpDir . '/mimetypemapping.dist.json');
184+
@rmdir($tmpDir);
185+
}
138186
}
139187

140188
public static function dataGetSecureMimeType(): array {

0 commit comments

Comments
 (0)