Skip to content

Commit 8403d6d

Browse files
authored
Merge pull request #2879 from nextcloud/backport/2871/stable33
[stable33] fix(CurrentUser): Properly get share token from non-legacy public webdav
2 parents cf7e158 + 3a8d8ad commit 8403d6d

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
@@ -25,10 +25,10 @@ class CurrentUser {
2525
protected $sessionUser = false;
2626

2727
public function __construct(
28-
protected IUserSession $userSession,
29-
protected IRequest $request,
30-
protected IManager $shareManager,
31-
protected IFactory $l10nFactory,
28+
protected readonly IUserSession $userSession,
29+
protected readonly IRequest $request,
30+
protected readonly IManager $shareManager,
31+
protected readonly IFactory $l10nFactory,
3232
) {
3333
}
3434

@@ -38,9 +38,8 @@ public function getUser(): ?IUser {
3838

3939
/**
4040
* Get an identifier for the user, session or token
41-
* @return string
4241
*/
43-
public function getUserIdentifier() {
42+
public function getUserIdentifier(): string {
4443
if ($this->identifier !== null) {
4544
return $this->identifier;
4645
}
@@ -70,9 +69,8 @@ public function getUserIdentifier() {
7069

7170
/**
7271
* Get the current user id from the session
73-
* @return string|null
7472
*/
75-
public function getUID() {
73+
public function getUID(): ?string {
7674
if ($this->sessionUser === false) {
7775
$user = $this->userSession->getUser();
7876
if ($user instanceof IUser) {
@@ -87,9 +85,8 @@ public function getUID() {
8785

8886
/**
8987
* Get the current user cloud id from the session
90-
* @return string|null
9188
*/
92-
public function getCloudId() {
89+
public function getCloudId(): ?string {
9390
if ($this->cloudId === false) {
9491
$user = $this->userSession->getUser();
9592
if ($user instanceof IUser) {
@@ -106,43 +103,57 @@ public function getCloudId() {
106103
* Check if the current request is via a public share link
107104
*/
108105
public function isPublicShareToken(): bool {
109-
/** @psalm-suppress NoInterfaceProperties */
110-
if (!empty($this->request->server['PHP_AUTH_USER'])) {
111-
$token = $this->request->server['PHP_AUTH_USER'];
112-
try {
113-
$share = $this->shareManager->getShareByToken($token);
114-
return $share->getShareType() === IShare::TYPE_LINK
115-
|| $share->getShareType() === IShare::TYPE_EMAIL;
116-
} catch (ShareNotFound $e) {
117-
// No share found for this token
118-
}
119-
}
120-
121-
return false;
106+
return $this->getPublicShare() !== null;
122107
}
123108

124109
/**
125110
* Get the cloud ID from the sharing token
126-
* @return string|null
127111
*/
128-
protected function getCloudIDFromToken() {
112+
protected function getCloudIDFromToken(): ?string {
113+
$share = $this->getPublicShare();
114+
115+
if ($share === null || $share->getShareType() !== IShare::TYPE_REMOTE) {
116+
return null;
117+
}
118+
119+
return $share->getSharedWith();
120+
}
121+
122+
protected function getPublicShare(): ?IShare {
123+
if (basename($this->request->getScriptName()) !== 'public.php') {
124+
return null;
125+
}
126+
127+
$token = $this->getShareToken();
128+
if ($token === null) {
129+
return null;
130+
}
131+
132+
try {
133+
return $this->shareManager->getShareByToken($token);
134+
} catch (ShareNotFound $e) {
135+
return null;
136+
}
137+
}
138+
139+
protected function getShareToken(): ?string {
140+
// The legacy public endpoint receive the share token in the HTTP basic auth header.
129141
/** @psalm-suppress NoInterfaceProperties */
130-
if (!empty($this->request->server['PHP_AUTH_USER'])) {
131-
$token = $this->request->server['PHP_AUTH_USER'];
132-
/**
133-
* Until https://github.com/nextcloud/server/pull/26681 is merged
134-
* @psalm-suppress InvalidCatch
135-
*/
136-
try {
137-
$share = $this->shareManager->getShareByToken($token);
138-
if ($share->getShareType() === IShare::TYPE_REMOTE) {
139-
return $share->getSharedWith();
140-
}
141-
} catch (ShareNotFound $e) {
142-
// No share, use the fallback
143-
}
142+
$authUser = (string)($this->request->server['PHP_AUTH_USER'] ?? '');
143+
if ($authUser !== '') {
144+
return $authUser;
145+
}
146+
147+
// The current public endpoint receives the share token in the path.
148+
// Copied from apps/dav/lib/Connector/Sabre/PublicAuth::getToken()
149+
$path = $this->request->getPathInfo() ?: '';
150+
// ['', 'dav', 'files', 'token']
151+
$splittedPath = explode('/', $path);
152+
153+
if (count($splittedPath) < 4 || $splittedPath[3] === '') {
154+
return null;
144155
}
145156

146-
return null;
157+
return $splittedPath[3];
147158
}
148159
}

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,14 +85,14 @@ 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
['cached', -1, -1, 'cached'],
8991
];
9092
}
9193

9294
#[DataProvider('dataGetUserIdentifier')]
93-
public function testGetUserIdentifier(?string $cachedIdentifier, string|int|null $uidResult, string|int|null $tokenResult, string $expected): void {
95+
public function testGetUserIdentifier(?string $cachedIdentifier, string|int|null $uidResult, ?string $tokenResult, string $expected): void {
9496
$instance = $this->getInstance([
9597
'getUID',
9698
'getCloudIDFromToken',
@@ -102,7 +104,7 @@ public function testGetUserIdentifier(?string $cachedIdentifier, string|int|null
102104
->method('getUID')
103105
->willReturn($uidResult);
104106

105-
$instance->expects($tokenResult !== -1 ? $this->once() : $this->never())
107+
$instance->expects($tokenResult !== '-1' ? $this->once() : $this->never())
106108
->method('getCloudIDFromToken')
107109
->willReturn($tokenResult);
108110

0 commit comments

Comments
 (0)