nextcloud / nextcloud/server

group_restrictions not enforced in getPrincipalsByPrefix/getPrincipalByPath: restricted rooms stay visible in Calendar's "Show rooms" dialog

Open
#63,681 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

0. Needs triage 34-feedback bug feature: caldav privacy
Dominant language
PHP
Stars
36.9k
Forks
5.2k
Avg merge
2d 3h
Merged PRs (30d)
713

Description

⚠️ This issue respects the following points: ⚠️
  • This is a bug, not a question or a configuration issue.
  • This issue is not already reported on GitHub (I've searched it).
Bug description

group_restrictions on a calendar room or resource are enforced in some of AbstractPrincipalBackend's read paths but not in others. As a result a restricted room stays visible to users outside the allowed group in Nextcloud Calendar's "Show rooms" dialog, while the attendee type-ahead correctly hides it.

isAllowedToAccessResource() is called from searchPrincipals() and findByUri(), but not from getPrincipalsByPrefix() or getPrincipalByPath() — those two do not even select the group_restrictions column:

Method Selects group_restrictions Calls isAllowedToAccessResource()
getPrincipalsByPrefix() (L70) no no
getPrincipalByPath() (L121) no no
searchPrincipals() (L204) yes yes
findByUri() (L400) yes yes

Calendar fills the "Show rooms" dialog via fetchRoomAndResourcePrincipals(), which does a PROPFIND on dav/principals/calendar-rooms/ — i.e. straight through getPrincipalsByPrefix().

Only the room's name, email and metadata leak; booking is still rejected server-side. But room names and locations can reveal organisational structure, which is exactly what the restriction is meant to prevent.

Steps to reproduce
  1. Have a room backend providing at least one room (any app implementing IRoomBackend).
  2. Give that room a group_restrictions value, e.g. ["test"], and let the hourly UpdateCalendarResourcesRoomsBackgroundJob write it to oc_calendar_rooms.
  3. Log in as a user who is not in that group.
  4. Create an event in Calendar → ResourcesShow rooms.
Expected behaviour

The restricted room is not listed, consistent with the attendee type-ahead.

Actual behaviour

The room is listed with its name, email and metadata.

Measured directly against the backend on a live NC 34 instance, with two test accounts differing only in group membership:

user            groups     searchPrincipals   getPrincipalsByPrefix
roomtest-in     [test]     1                  1
roomtest-uit    []         0                  1     <-- should be 0

Setting the restriction back to [] makes both users see the room again through both paths, which confirms the restriction itself is stored and evaluated correctly — one of the two read paths simply skips the check.

Note for whoever picks this up

AbstractPrincipalBackendTestCase::testGetPrincipalsByPrefix() currently asserts that all six fixtures are returned, including res5 (["foo", "bar"]) and res6 (["group1", "bar"]), and it does not mock a user session. So the present behaviour is pinned by a test — fixing this means deciding that the test encodes a bug rather than an intent, which felt like a call for a maintainer rather than something to settle in a drive-by PR.

There is also a question I could not answer from the outside: searchPrincipals() and findByUri() both bail out when there is no session (return [] / return null), but getPrincipalsByPrefix() has no such guard, and the backend is used both by the principal collection and by CalendarRoot in RootCollection.php. If some path reaches it without a session, adding a filter there would hide every room instead of the restricted ones — a worse regression than the bug.

Happy to prepare a PR once you indicate the preferred direction (filter in the backend vs. filter in the Calendar dialog).

Nextcloud Server version

34

Operating system

Other

PHP engine version

PHP 8.4

Web server

Apache (supported)

Database engine version

PostgreSQL

Is this bug present after an update or on a fresh install?

Updated to a major version (ex. 32.0.9 to 33.0.4)

Are you using the Nextcloud Server Encryption module?

Encryption is Disabled

Are you using an external user-backend, if yes which one?
  • LDAP/ Active Directory
  • SSO - SAML
  • Other
Server configuration detail

Calendar app 6.5.4. Room provided by a third-party IRoomBackend implementation; the same code path applies to any room backend.

Nextcloud Signing status

No response

Nextcloud Logs

No response

Additional info

Related: the same dialog also renders the literal string undefined inside busy blocks — that one is a Calendar-side issue and is being fixed separately in nextcloud/calendar#8780.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with getPrincipalsByPrefix() and getPrincipalByPath() in AbstractPrincipalBackend, then compare their session handling with searchPrincipals() and findByUri(). Run AbstractPrincipalBackendTestCase::testGetPrincipalsByPrefix(), which currently expects all six fixtures, and inspect CalendarRoot in RootCollection.php for callers without a session. Done means restricted rooms are absent for unauthorized users without hiding unrestricted rooms or breaking session-less callers.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
authorization, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.