Skip to content

Commit cd5bd11

Browse files
authored
Merge pull request #38448 from nextcloud/fix/carddav/no-sab-guest-users
fix(carddav): Don't show system address book cards to guests
2 parents 9780472 + e524631 commit cd5bd11

2 files changed

Lines changed: 84 additions & 8 deletions

File tree

apps/dav/lib/CardDAV/SystemAddressbook.php

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public function getChildren() {
9292
// Should never happen because we don't allow anonymous access
9393
return [];
9494
}
95-
if (!$shareEnumeration || (!$shareEnumerationGroup && $shareEnumerationPhone)) {
95+
if ($user->getBackendClassName() === 'Guests' || !$shareEnumeration || (!$shareEnumerationGroup && $shareEnumerationPhone)) {
9696
$name = SyncService::getCardUri($user);
9797
try {
9898
return [parent::getChild($name)];
@@ -135,8 +135,8 @@ public function getMultipleChildren($paths): array {
135135
$shareEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
136136
$shareEnumerationGroup = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
137137
$shareEnumerationPhone = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
138-
if (!$shareEnumeration || (!$shareEnumerationGroup && $shareEnumerationPhone)) {
139-
$user = $this->userSession->getUser();
138+
$user = $this->userSession->getUser();
139+
if (($user !== null && $user->getBackendClassName() === 'Guests') || !$shareEnumeration || (!$shareEnumerationGroup && $shareEnumerationPhone)) {
140140
// No user or cards with no access
141141
if ($user === null || !in_array(SyncService::getCardUri($user), $paths, true)) {
142142
return [];
@@ -149,7 +149,6 @@ public function getMultipleChildren($paths): array {
149149
}
150150
}
151151
if ($shareEnumerationGroup) {
152-
$user = $this->userSession->getUser();
153152
if ($this->groupManager === null || $user === null) {
154153
// Group manager or user is not available, so we can't determine which data is safe
155154
return [];
@@ -196,19 +195,18 @@ public function getMultipleChildren($paths): array {
196195
* @throws Forbidden
197196
*/
198197
public function getChild($name): Card {
198+
$user = $this->userSession->getUser();
199199
$shareEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
200200
$shareEnumerationGroup = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
201201
$shareEnumerationPhone = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
202-
if (!$shareEnumeration || (!$shareEnumerationGroup && $shareEnumerationPhone)) {
203-
$currentUser = $this->userSession->getUser();
204-
$ownName = $currentUser !== null ? SyncService::getCardUri($currentUser) : null;
202+
if (($user !== null && $user->getBackendClassName() === 'Guests') || !$shareEnumeration || (!$shareEnumerationGroup && $shareEnumerationPhone)) {
203+
$ownName = $user !== null ? SyncService::getCardUri($user) : null;
205204
if ($ownName === $name) {
206205
return parent::getChild($name);
207206
}
208207
throw new Forbidden();
209208
}
210209
if ($shareEnumerationGroup) {
211-
$user = $this->userSession->getUser();
212210
if ($user === null || $this->groupManager === null) {
213211
// Group manager is not available, so we can't determine which data is safe
214212
throw new Forbidden();

apps/dav/tests/unit/CardDAV/SystemAddressBookTest.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,46 @@ protected function setUp(): void {
9090
);
9191
}
9292

93+
public function testGetChildrenAsGuest(): void {
94+
$this->config->expects(self::exactly(3))
95+
->method('getAppValue')
96+
->willReturnMap([
97+
['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
98+
['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
99+
['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
100+
]);
101+
$user = $this->createMock(IUser::class);
102+
$user->method('getUID')->willReturn('user');
103+
$user->method('getBackendClassName')->willReturn('Guests');
104+
$this->userSession->expects(self::once())
105+
->method('getUser')
106+
->willReturn($user);
107+
$vcfWithScopes = <<<VCF
108+
BEGIN:VCARD
109+
VERSION:3.0
110+
PRODID:-//Sabre//Sabre VObject 4.4.2//EN
111+
UID:admin
112+
FN;X-NC-SCOPE=v2-federated:admin
113+
N;X-NC-SCOPE=v2-federated:admin;;;;
114+
ADR;TYPE=OTHER;X-NC-SCOPE=v2-local:Testing test test test;;;;;;
115+
EMAIL;TYPE=OTHER;X-NC-SCOPE=v2-federated:miau_lalala@gmx.net
116+
TEL;TYPE=OTHER;X-NC-SCOPE=v2-local:+435454454544
117+
CLOUD:admin@http://localhost
118+
END:VCARD
119+
VCF;
120+
$originalCard = [
121+
'carddata' => $vcfWithScopes,
122+
];
123+
$this->cardDavBackend->expects(self::once())
124+
->method('getCard')
125+
->with(123, 'Guests:user.vcf')
126+
->willReturn($originalCard);
127+
128+
$children = $this->addressBook->getChildren();
129+
130+
self::assertCount(1, $children);
131+
}
132+
93133
public function testGetFilteredChildForFederation(): void {
94134
$this->config->expects(self::exactly(3))
95135
->method('getAppValue')
@@ -172,6 +212,24 @@ public function testGetChildWithoutEnumeration(): void {
172212
$this->addressBook->getChild("LDAP:user.vcf");
173213
}
174214

215+
public function testGetChildAsGuest(): void {
216+
$this->config->expects(self::exactly(3))
217+
->method('getAppValue')
218+
->willReturnMap([
219+
['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
220+
['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
221+
['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
222+
]);
223+
$user = $this->createMock(IUser::class);
224+
$user->method('getBackendClassName')->willReturn('Guests');
225+
$this->userSession->expects(self::once())
226+
->method('getUser')
227+
->willReturn($user);
228+
$this->expectException(Forbidden::class);
229+
230+
$this->addressBook->getChild("LDAP:user.vcf");
231+
}
232+
175233
public function testGetChildWithGroupEnumerationRestriction(): void {
176234
$this->config->expects(self::exactly(3))
177235
->method('getAppValue')
@@ -322,6 +380,26 @@ public function testGetMultipleChildrenWithGroupEnumerationRestriction(): void {
322380
self::assertCount(2, $cards);
323381
}
324382

383+
public function testGetMultipleChildrenAsGuest(): void {
384+
$this->config
385+
->method('getAppValue')
386+
->willReturnMap([
387+
['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
388+
['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
389+
['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
390+
]);
391+
$user = $this->createMock(IUser::class);
392+
$user->method('getUID')->willReturn('user');
393+
$user->method('getBackendClassName')->willReturn('Guests');
394+
$this->userSession->expects(self::once())
395+
->method('getUser')
396+
->willReturn($user);
397+
398+
$cards = $this->addressBook->getMultipleChildren(['Database:user1.vcf', 'LDAP:user2.vcf']);
399+
400+
self::assertEmpty($cards);
401+
}
402+
325403
public function testGetMultipleChildren(): void {
326404
$this->config
327405
->method('getAppValue')

0 commit comments

Comments
 (0)