Commit 8a0018c
fix: gate public sharing of calendars behind sharing.public_calendars permission (open-webui#24493)
* fix: gate public sharing of calendars behind sharing.public_calendars permission
The calendar router did not call filter_allowed_access_grants on either the
create or update endpoint, while every other shareable resource in the
codebase (channels, knowledge, models, notes, prompts, skills, tools) does.
A verified non-admin owner could therefore attach
`{"principal_type":"user","principal_id":"*","permission":"read"|"write"}`
to their own calendar in the create or update payload and have it persisted
unfiltered. Any other verified user with the (default-on) features.calendar
permission could then read or, for write grants, write events on it via the
existing /events* endpoints, bypassing the per-user sharing.public_<X>
permission gate the rest of the resource cohort enforces.
Three changes:
- config.py: add USER_PERMISSIONS_CALENDAR_ALLOW_PUBLIC_SHARING (default
False, env-overridable) and surface it in DEFAULT_USER_PERMISSIONS
['sharing']['public_calendars'] so admins can grant it per group via the
same UI used for notes/models/etc.
- routers/calendar.py: import filter_allowed_access_grants and call it in
create_calendar with the new sharing.public_calendars key, identical to
the channel router's pattern.
- routers/calendar.py: call filter_allowed_access_grants in update_calendar
too. The pre-existing owner-only gate at L350 only restricts WHO may
change grants; the new filter restricts WHICH grants they may set, so a
non-admin owner cannot make their own calendar publicly readable or
writable without the corresponding sharing permission.
Same shape as GHSA-7rjh-px4v-5w55 (channels). Reported by Matteo Panzeri.
Co-authored-by: Matteo Panzeri <28739806+matte1782@users.noreply.github.com>
* fix: expose public_calendars + features.calendar through admin permissions surface
The earlier commit added DEFAULT_USER_PERMISSIONS['sharing']['public_calendars']
and the runtime filter call, but the new key was not yet plumbed through the
admin /users/default/permissions endpoint. Without these changes the toggle
would round-trip as silently dropped:
- routers/users.py SharingPermissions: any payload POSTed to
/default/permissions ran through `form_data.model_dump()`, and Pydantic
drops fields not declared on the model. The new public_calendars key
would have been stripped on every save, leaving admins unable to grant
the permission via the UI even though the runtime filter would honor it.
- src/lib/constants/permissions.ts: the frontend's DEFAULT_PERMISSIONS dict
is the seed shape used by the admin Groups Permissions panel; without
the new key it could not bind a Switch component to it.
- Permissions.svelte: add a Calendars Public Sharing toggle alongside the
Notes/Chats Public Sharing toggles, gated on the existing
features.calendar flag (matches the pattern used for notes/chats).
Also closes a pre-existing parity gap on features.calendar: DEFAULT_USER_
PERMISSIONS['features']['calendar'] has existed since the calendar feature
shipped, and Permissions.svelte already renders a Calendar feature toggle,
but FeaturesPermissions Pydantic and the frontend defaults never knew
about it. Adding it everywhere completes the round-trip so admin saves no
longer silently drop the calendar feature flag either.
---------
Co-authored-by: Matteo Panzeri <28739806+matte1782@users.noreply.github.com>1 parent 69270e1 commit 8a0018c
5 files changed
Lines changed: 55 additions & 3 deletions
File tree
- backend/open_webui
- routers
- src/lib
- components/admin/Users/Groups
- constants
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1465 | 1465 | | |
1466 | 1466 | | |
1467 | 1467 | | |
| 1468 | + | |
| 1469 | + | |
| 1470 | + | |
| 1471 | + | |
1468 | 1472 | | |
1469 | 1473 | | |
1470 | 1474 | | |
| |||
1585 | 1589 | | |
1586 | 1590 | | |
1587 | 1591 | | |
| 1592 | + | |
1588 | 1593 | | |
1589 | 1594 | | |
1590 | 1595 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | | - | |
| 25 | + | |
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| |||
112 | 112 | | |
113 | 113 | | |
114 | 114 | | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
115 | 126 | | |
116 | 127 | | |
117 | 128 | | |
| |||
350 | 361 | | |
351 | 362 | | |
352 | 363 | | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
353 | 378 | | |
354 | 379 | | |
355 | 380 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
194 | 194 | | |
195 | 195 | | |
196 | 196 | | |
| 197 | + | |
197 | 198 | | |
198 | 199 | | |
199 | 200 | | |
| |||
235 | 236 | | |
236 | 237 | | |
237 | 238 | | |
| 239 | + | |
238 | 240 | | |
239 | 241 | | |
240 | 242 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
410 | 410 | | |
411 | 411 | | |
412 | 412 | | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
413 | 431 | | |
414 | 432 | | |
415 | 433 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | | - | |
| 28 | + | |
| 29 | + | |
29 | 30 | | |
30 | 31 | | |
31 | 32 | | |
| |||
62 | 63 | | |
63 | 64 | | |
64 | 65 | | |
65 | | - | |
| 66 | + | |
| 67 | + | |
66 | 68 | | |
67 | 69 | | |
68 | 70 | | |
| |||
0 commit comments