Skip to content

Commit 722b921

Browse files
hamza221claude
andcommitted
fix: complete backport of shared trashbin objects access
Restore the hunks missing from the original backport of #60648: - replace the legacy owned-calendars result loop in collectDeletedCalendarObjectsForPrincipal() which clobbered the by-reference accumulator and skipped the delegated-calendar URI logic - add the missing canModify()/isShared() permission helpers and the getSourceCalendarUri()/getCalendarPrincipalUri()/getDelegator() getters used by the trashbin plugin Also adapt fetchAssociative() to fetch() since IResult on stable32 does not expose fetchAssociative(). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Hamza <hamzamahjoubi221@gmail.com>
1 parent 848c0c9 commit 722b921

2 files changed

Lines changed: 35 additions & 17 deletions

File tree

apps/dav/lib/CalDAV/CalDavBackend.php

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,21 +1228,14 @@ private function collectDeletedCalendarObjectsForPrincipal(string $principalUri,
12281228
->andWhere($query->expr()->isNotNull('co.deleted_at'))
12291229
->andWhere($query->expr()->isNull('c.deleted_at'));
12301230
$stmt = $query->executeQuery();
1231-
1232-
$result = [];
12331231
while ($row = $stmt->fetch()) {
1234-
$result[] = [
1235-
'id' => $row['id'],
1236-
'uri' => $row['uri'],
1237-
'lastmodified' => $row['lastmodified'],
1238-
'etag' => '"' . $row['etag'] . '"',
1239-
'calendarid' => $row['calendarid'],
1240-
'calendaruri' => $row['calendaruri'],
1241-
'size' => (int)$row['size'],
1242-
'component' => strtolower($row['componenttype']),
1243-
'classification' => (int)$row['classification'],
1244-
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => $row['deleted_at'] === null ? $row['deleted_at'] : (int)$row['deleted_at'],
1245-
];
1232+
if ($this->resultHasMorePermissiveEntry($result, $row['id'], $proxyOverlay)) {
1233+
continue;
1234+
}
1235+
[, $ownerName] = Uri\split($row['calendarprincipaluri']);
1236+
$isDelegated = $proxyOverlay !== null;
1237+
$calendarUri = $isDelegated ? $row['calendaruri'] . '_delegated_by_' . $ownerName : $row['calendaruri'];
1238+
$result[$row['id']] = $this->rowToDeletedCalendarObject($row, $calendarUri, false, $proxyOverlay, $isDelegated ? $principalUri : null);
12461239
}
12471240
$stmt->closeCursor();
12481241

@@ -1260,7 +1253,7 @@ private function collectDeletedCalendarObjectsForPrincipal(string $principalUri,
12601253
$this->applySharedCalendarFilters($select, $principals, $principalUri);
12611254

12621255
$stmt = $select->executeQuery();
1263-
while ($row = $stmt->fetchAssociative()) {
1256+
while ($row = $stmt->fetch()) {
12641257
$effective = $this->effectiveAccess((int)$row['shareaccess'], $proxyOverlay);
12651258
if ($this->resultHasMorePermissiveEntry($result, $row['id'], $effective)) {
12661259
continue;
@@ -2710,7 +2703,7 @@ private function findDeletedCalendarObjectForPrincipal(int $id, string $principa
27102703
->andWhere($query->expr()->eq('c.principaluri', $query->createNamedParameter($principalUri)))
27112704
->andWhere($query->expr()->isNotNull('co.deleted_at'));
27122705
$stmt = $query->executeQuery();
2713-
$row = $stmt->fetchAssociative();
2706+
$row = $stmt->fetch();
27142707
$stmt->closeCursor();
27152708

27162709
if ($row) {
@@ -2735,7 +2728,7 @@ private function findDeletedCalendarObjectForPrincipal(int $id, string $principa
27352728
$this->applySharedCalendarFilters($select, $principals, $principalUri);
27362729

27372730
$stmt = $select->executeQuery();
2738-
$row = $stmt->fetchAssociative();
2731+
$row = $stmt->fetch();
27392732
$stmt->closeCursor();
27402733

27412734
if (!$row) {

apps/dav/lib/CalDAV/Trashbin/DeletedCalendarObject.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ public function delete() {
4040
);
4141
}
4242

43+
private function isShared(): bool {
44+
$calendarOwner = $this->objectData['calendarprincipaluri'] ?? null;
45+
return $calendarOwner !== null && $calendarOwner !== $this->principalUri;
46+
}
47+
48+
private function canModify(): bool {
49+
if (!$this->isShared()) {
50+
return true;
51+
}
52+
// For shared entries, only write sharees may delete/restore.
53+
return ($this->objectData['shared_access'] ?? null) === Backend::ACCESS_READ_WRITE;
54+
}
55+
4356
public function getName() {
4457
return $this->name;
4558
}
@@ -92,6 +105,18 @@ public function getCalendarUri(): string {
92105
return $this->objectData['calendaruri'];
93106
}
94107

108+
public function getSourceCalendarUri(): string {
109+
return $this->objectData['sourcecalendaruri'] ?? $this->objectData['calendaruri'];
110+
}
111+
112+
public function getCalendarPrincipalUri(): ?string {
113+
return $this->objectData['calendarprincipaluri'] ?? null;
114+
}
115+
116+
public function getDelegator(): ?string {
117+
return $this->objectData['delegator'] ?? null;
118+
}
119+
95120
public function getACL(): array {
96121
$acl = [
97122
[

0 commit comments

Comments
 (0)