Skip to content

Commit 3131714

Browse files
committed
enh(sharing): enable unsharing for sharees for DAV shares (calendars, address books)
Signed-off-by: Anna Larch <anna@nextcloud.com>
1 parent cb43fca commit 3131714

3 files changed

Lines changed: 40 additions & 21 deletions

File tree

apps/dav/lib/CalDAV/Calendar.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -236,14 +236,6 @@ public function delete() {
236236
if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal']) &&
237237
$this->calendarInfo['{http://owncloud.org/ns}owner-principal'] !== $this->calendarInfo['principaluri']) {
238238
$principal = 'principal:' . parent::getOwner();
239-
$shares = $this->caldavBackend->getShares($this->getResourceId());
240-
$shares = array_filter($shares, function ($share) use ($principal) {
241-
return $share['href'] === $principal;
242-
});
243-
if (empty($shares)) {
244-
throw new Forbidden();
245-
}
246-
247239
$this->caldavBackend->updateShares($this, [], [
248240
$principal
249241
]);

apps/dav/lib/Connector/Sabre/DavAclPlugin.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
*/
2727
namespace OCA\DAV\Connector\Sabre;
2828

29+
use OCA\DAV\CalDAV\Calendar;
2930
use OCA\DAV\CardDAV\AddressBook;
3031
use Sabre\CalDAV\Principal\User;
3132
use Sabre\DAV\Exception\NotFound;
@@ -58,6 +59,9 @@ public function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT,
5859
case AddressBook::class:
5960
$type = 'Addressbook';
6061
break;
62+
case Calendar::class:
63+
$type = 'Calendar';
64+
break;
6165
default:
6266
$type = 'Node';
6367
break;

apps/dav/lib/DAV/Sharing/Backend.php

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class Backend {
4848
public const ACCESS_OWNER = 1;
4949
public const ACCESS_READ_WRITE = 2;
5050
public const ACCESS_READ = 3;
51+
// 4 is already in use for public calendars
52+
public const UNSHARE_USER = 5;
5153

5254
private CappedMemoryCache $shareCache;
5355

@@ -160,11 +162,13 @@ private function unshare(IShareable $shareable, string $element): void {
160162
}
161163

162164
$query = $this->db->getQueryBuilder();
163-
$query->delete('dav_shares')
164-
->where($query->expr()->eq('resourceid', $query->createNamedParameter($shareable->getResourceId())))
165-
->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType)))
166-
->andWhere($query->expr()->eq('principaluri', $query->createNamedParameter($parts[1])))
167-
;
165+
$query->insert('dav_shares')
166+
->values([
167+
'principaluri' => $query->createNamedParameter($parts[1]),
168+
'type' => $query->createNamedParameter($this->resourceType),
169+
'access' => $query->createNamedParameter(self::UNSHARE_USER),
170+
'resourceid' => $query->createNamedParameter($shareable->getResourceId())
171+
]);
168172
$query->executeStatement();
169173
}
170174

@@ -181,26 +185,29 @@ private function unshare(IShareable $shareable, string $element): void {
181185
* @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}>
182186
*/
183187
public function getShares(int $resourceId): array {
184-
$cached = $this->shareCache->get($resourceId);
185-
if ($cached) {
186-
return $cached;
187-
}
188+
// $cached = $this->shareCache->get($resourceId);
189+
// if ($cached) {
190+
// return $cached;
191+
// }
188192
$query = $this->db->getQueryBuilder();
189-
$result = $query->select(['principaluri', 'access'])
193+
$result = $query->select(['principaluri', 'access', 'resourceid'])
190194
->from('dav_shares')
191195
->where($query->expr()->eq('resourceid', $query->createNamedParameter($resourceId, IQueryBuilder::PARAM_INT)))
192196
->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType)))
193-
->groupBy(['principaluri', 'access'])
197+
->groupBy(['principaluri', 'access', 'resourceid'])
194198
->executeQuery();
195199

196200
$shares = [];
197-
while ($row = $result->fetch()) {
201+
$rows = $result->fetchAll();
202+
foreach($rows as $row) {
198203
$p = $this->principalBackend->getPrincipalByPath($row['principaluri']);
199204
$shares[] = [
205+
'resourceid' => $row['resourceid'],
200206
'href' => "principal:{$row['principaluri']}",
201207
'commonName' => isset($p['{DAV:}displayname']) ? (string)$p['{DAV:}displayname'] : '',
202208
'status' => 1,
203209
'readOnly' => (int) $row['access'] === self::ACCESS_READ,
210+
'access' => (int) $row['access'],
204211
'{http://owncloud.org/ns}principal' => (string)$row['principaluri'],
205212
'{http://owncloud.org/ns}group-share' => isset($p['uri']) ? str_starts_with($p['uri'], 'principals/groups') : false
206213
];
@@ -254,6 +261,9 @@ public function preloadShares(array $resourceIds): void {
254261
public function applyShareAcl(int $resourceId, array $acl): array {
255262
$shares = $this->getShares($resourceId);
256263
foreach ($shares as $share) {
264+
if($share['access'] === self::UNSHARE_USER) {
265+
continue;
266+
}
257267
$acl[] = [
258268
'privilege' => '{DAV:}read',
259269
'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'],
@@ -275,6 +285,19 @@ public function applyShareAcl(int $resourceId, array $acl): array {
275285
];
276286
}
277287
}
278-
return $acl;
288+
289+
$principalsToRemove = array_map(function (array $unshare) {
290+
return $unshare['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'];
291+
}, array_filter($shares, function (array $share) {
292+
return $share['access'] === self::UNSHARE_USER;
293+
}));
294+
295+
$toRemove = array_filter(array_map(function ($entry) use ($principalsToRemove) {
296+
if(in_array($entry['principal'], $principalsToRemove)) {
297+
return $entry;
298+
}
299+
}, $acl));
300+
301+
return array_diff_key($acl, $toRemove);
279302
}
280303
}

0 commit comments

Comments
 (0)