fix(dav): ignore calendars in the trash bin for free-busy and user status - #62667
Open
ndo84bw wants to merge 2 commits into
Open
fix(dav): ignore calendars in the trash bin for free-busy and user status#62667ndo84bw wants to merge 2 commits into
ndo84bw wants to merge 2 commits into
Conversation
Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Nico Donath <ndo84bw@gmx.de>
Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Nico Donath <ndo84bw@gmx.de>
ndo84bw
requested review from
ChristophWurst,
SebastianKrupinski and
tcitworld
as code owners
July 29, 2026 13:28
SebastianKrupinski
requested changes
Jul 29, 2026
SebastianKrupinski
left a comment
Contributor
There was a problem hiding this comment.
Hi,
I am going to block this PR.
calendarQuery() and search() are used by other parts of our code to find objects both in and outside of the trash bin.
Not sure doing this here is the best idea
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
If a calendar holds events that count as busy and you delete that calendar, the events in it are still evaluated for free/busy lookups and for the automatic user status.
The reason is that deleting a calendar only marks the calendar as deleted, not the events inside it. Trashed calendars are hidden from clients purely through their resourcetype, but Sabre's free/busy code picks the calendars to query by PHP class, so that masking never applies there.
This patch filters out calendars in the trash bin in both cases.
What the fix does
Calendar::calendarQuery()returns[]when the calendar is in the trash bin. This covers the scheduling outbox free/busy request (Sabre'sSchedule\Plugin::getFreeBusyForEmail),OCA\DAV\CalDAV\Schedule\Plugin::isAvailableAtTime(room and resource auto-reply),OC\Calendar\Manager::checkAvailability, and thecalendar-queryandfree-busy-queryREPORTs.CalendarImpl::search()returns[]when the calendar is in the trash bin. This coversManager::searchForPrincipal()andManager::search(), and with themStatusService(the "In a meeting" user status) andUpcomingEventsService(dashboard and upcoming events).What the fix does not touch
PROPFINDDepth:1 on a trashed calendar still lists its objects, andGETstill serves them with 200.PROPFINDon/public-calendars/<token>/still answers 207 and lists the object, while acalendar-queryREPORT on the same link now comes back empty.CalDavBackend::getCalendarObjectByUID()filtersco.deleted_atbut notc.deleted_at, so an incoming iTIP reply can still be applied to an event inside a trashed calendar. Skipping it would duplicate the event instead: Sabre would treat it as unknown and create a new copy in the default calendar, next to the old one in the trashed calendar.One consequence I could not verify:
scheduleLocalDeliveryauto-replies for rooms and resources based on the same availability query, so a room whose own calendar sits in the trash bin should now reply ACCEPTED instead of DECLINED, because the bookings in that calendar no longer count as busy. Reproducing this needs a room or resource principal, which only exists if an app provides one.Tests
Manual, live (docker dev container, NC 35.0.0 dev, PHP 8.5):
DELETEof the calendar still returnedFREEBUSY:20260729T100000Z/20260729T110000Z; with the fix the VFREEBUSY comes back empty. Restoring from the trash bin (MOVEtotrashbin/restore/file) still works, and the slot is busy again afterwards.calendar-queryREPORT on the trashed calendar: empty multistatus.GET /ocs/v2.php/apps/dav/api/v1/events/upcoming), A/B with and without theCalendarImplguard: without it the event from the trashed calendar appears, with it the list is empty.busywithmessage_id = meeting, so the calendar icon shows on the avatar; with the patchrevertUserStatus()restores the previousonlinestatus and the icon disappears. Two things to keep in mind when reproducing: the calendar status result is cached per user for 5 minutes (StatusService, where the cache lives depends onmemcache.local), and a manually set status suppresses events that started before it, otherwise the test comes out falsely negative.Unit tests:
CalendarTestcoverscalendarQuery()for a live, a trashed and a shared calendar (PublicCalendarTestinherits them)CalendarImplTestcoverssearch()for a trashed calendarphpunit --filter "CalendarTest|CalendarImplTest"- 143 tests greenChecklist
3. to review, feature component)stable32)AI (if applicable)