Skip to content

Commit edec866

Browse files
authored
Merge pull request #2877 from nextcloud/backport/2871/stable35
[stable35] fix(CurrentUser): Properly get share token from non-legacy public webdav
2 parents 9781f6d + 4de655b commit edec866

2 files changed

Lines changed: 56 additions & 43 deletions

File tree

lib/CurrentUser.php

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
class CurrentUser {
1919

2020
public function __construct(
21-
protected IUserSession $userSession,
22-
protected IRequest $request,
23-
protected IManager $shareManager,
24-
protected IFactory $l10nFactory,
21+
protected readonly IUserSession $userSession,
22+
protected readonly IRequest $request,
23+
protected readonly IManager $shareManager,
24+
protected readonly IFactory $l10nFactory,
2525
) {
2626
}
2727

@@ -31,9 +31,8 @@ public function getUser(): ?IUser {
3131

3232
/**
3333
* Get an identifier for the user, session or token
34-
* @return string
3534
*/
36-
public function getUserIdentifier() {
35+
public function getUserIdentifier(): string {
3736
$uid = $this->getUID();
3837
if ($uid !== null) {
3938
return $uid;
@@ -55,9 +54,8 @@ public function getUserIdentifier() {
5554

5655
/**
5756
* Get the current user id from the session
58-
* @return string|null
5957
*/
60-
public function getUID() {
58+
public function getUID(): ?string {
6159
$user = $this->userSession->getUser();
6260
if ($user instanceof IUser) {
6361
return $user->getUID();
@@ -67,9 +65,8 @@ public function getUID() {
6765

6866
/**
6967
* Get the current user cloud id from the session
70-
* @return string|null
7168
*/
72-
public function getCloudId() {
69+
public function getCloudId(): ?string {
7370
$user = $this->userSession->getUser();
7471
if ($user instanceof IUser) {
7572
return $user->getCloudId();
@@ -82,43 +79,57 @@ public function getCloudId() {
8279
* Check if the current request is via a public share link
8380
*/
8481
public function isPublicShareToken(): bool {
85-
/** @psalm-suppress NoInterfaceProperties */
86-
if (!empty($this->request->server['PHP_AUTH_USER'])) {
87-
$token = $this->request->server['PHP_AUTH_USER'];
88-
try {
89-
$share = $this->shareManager->getShareByToken($token);
90-
return $share->getShareType() === IShare::TYPE_LINK
91-
|| $share->getShareType() === IShare::TYPE_EMAIL;
92-
} catch (ShareNotFound $e) {
93-
// No share found for this token
94-
}
95-
}
96-
97-
return false;
82+
return $this->getPublicShare() !== null;
9883
}
9984

10085
/**
10186
* Get the cloud ID from the sharing token
102-
* @return string|null
10387
*/
104-
protected function getCloudIDFromToken() {
88+
protected function getCloudIDFromToken(): ?string {
89+
$share = $this->getPublicShare();
90+
91+
if ($share === null || $share->getShareType() !== IShare::TYPE_REMOTE) {
92+
return null;
93+
}
94+
95+
return $share->getSharedWith();
96+
}
97+
98+
protected function getPublicShare(): ?IShare {
99+
if (basename($this->request->getScriptName()) !== 'public.php') {
100+
return null;
101+
}
102+
103+
$token = $this->getShareToken();
104+
if ($token === null) {
105+
return null;
106+
}
107+
108+
try {
109+
return $this->shareManager->getShareByToken($token);
110+
} catch (ShareNotFound $e) {
111+
return null;
112+
}
113+
}
114+
115+
protected function getShareToken(): ?string {
116+
// The legacy public endpoint receive the share token in the HTTP basic auth header.
105117
/** @psalm-suppress NoInterfaceProperties */
106-
if (!empty($this->request->server['PHP_AUTH_USER'])) {
107-
$token = $this->request->server['PHP_AUTH_USER'];
108-
/**
109-
* Until https://github.com/nextcloud/server/pull/26681 is merged
110-
* @psalm-suppress InvalidCatch
111-
*/
112-
try {
113-
$share = $this->shareManager->getShareByToken($token);
114-
if ($share->getShareType() === IShare::TYPE_REMOTE) {
115-
return $share->getSharedWith();
116-
}
117-
} catch (ShareNotFound $e) {
118-
// No share, use the fallback
119-
}
118+
$authUser = (string)($this->request->server['PHP_AUTH_USER'] ?? '');
119+
if ($authUser !== '') {
120+
return $authUser;
120121
}
121122

122-
return null;
123+
// The current public endpoint receives the share token in the path.
124+
// Copied from apps/dav/lib/Connector/Sabre/PublicAuth::getToken()
125+
$path = $this->request->getPathInfo() ?: '';
126+
// ['', 'dav', 'files', 'token']
127+
$splittedPath = explode('/', $path);
128+
129+
if (count($splittedPath) < 4 || $splittedPath[3] === '') {
130+
return null;
131+
}
132+
133+
return $splittedPath[3];
123134
}
124135
}

tests/CurrentUserTest.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ protected function setUp(): void {
5757
$this->userSession = $this->createMock(IUserSession::class);
5858
$this->shareManager = $this->createMock(IManager::class);
5959
$this->l10nFactory = $this->createMock(IFactory::class);
60+
61+
$this->request->method('getScriptName')->willReturn('/public.php');
6062
}
6163

6264
protected function getInstance(array $methods = []): CurrentUser|MockObject {
@@ -83,13 +85,13 @@ protected function getInstance(array $methods = []): CurrentUser|MockObject {
8385
public static function dataGetUserIdentifier(): array {
8486
return [
8587
[null, null, null, ''],
86-
[null, 'uid', -1, 'uid'],
88+
[null, 'uid', '-1', 'uid'],
8789
[null, null, 'token', 'token'],
8890
];
8991
}
9092

9193
#[DataProvider('dataGetUserIdentifier')]
92-
public function testGetUserIdentifier(?string $cachedIdentifier, string|int|null $uidResult, string|int|null $tokenResult, string $expected): void {
94+
public function testGetUserIdentifier(?string $cachedIdentifier, string|int|null $uidResult, ?string $tokenResult, string $expected): void {
9395
$instance = $this->getInstance([
9496
'getUID',
9597
'getCloudIDFromToken',
@@ -99,7 +101,7 @@ public function testGetUserIdentifier(?string $cachedIdentifier, string|int|null
99101
->method('getUID')
100102
->willReturn($uidResult);
101103

102-
$instance->expects($tokenResult !== -1 ? $this->once() : $this->never())
104+
$instance->expects($tokenResult !== '-1' ? $this->once() : $this->never())
103105
->method('getCloudIDFromToken')
104106
->willReturn($tokenResult);
105107

0 commit comments

Comments
 (0)