Commit graph

93 commits

Author SHA1 Message Date
Timothy Jaeryang Baek
9866a02863 refac 2026-07-01 02:08:34 -05:00
Timothy Jaeryang Baek
517cd8d102 refac 2026-06-29 13:03:14 -05:00
G30
6fdf9b4340
perf(auth): make password hashing non-blocking and batch CSV user import (#25804)
Co-authored-by: Tim Baek <tim@openwebui.com>
2026-06-29 02:45:39 -05:00
G30
3c67774eb3
fix(auth): enforce settings.interface permission on /user/settings/update endpoint (#25996) 2026-06-29 01:53:20 -05:00
G30
677e164f29
feat(permissions): add workspace.skills_import and workspace.skills_export permissions (#25921) 2026-06-29 01:36:27 -05:00
Timothy Jaeryang Baek
b5c43968db refac 2026-06-25 03:31:45 +01:00
Timothy Jaeryang Baek
5cdcdbaeec refac 2026-06-17 02:52:35 +02:00
G30
57a5e43696
feat(permissions): add per-group features.user_webhooks permission (#25923) 2026-06-17 00:47:44 +02:00
Timothy Jaeryang Baek
edf3ae9209 refac 2026-06-17 00:33:30 +02:00
G30
6b2d962cd6
feat(permissions): add reset to defaults button in permissions modals (#25931)
Adds a 'Reset to Defaults' button to both the Edit Default Permissions
modal and the Edit User Group permissions modal.

- Default permissions modal: resets to stock/env-var configuration
- User group modal: resets to current global default permissions

Backend: new GET /api/v1/users/default/permissions/defaults endpoint
that returns DEFAULT_USER_PERMISSIONS (env-var-based initial defaults).
2026-06-17 00:25:20 +02:00
Timothy Jaeryang Baek
6fce92aa12 chore: format 2026-06-01 13:56:55 -07:00
Timothy Jaeryang Baek
d8b5b9fa79 refac 2026-05-21 15:29:49 +04:00
Timothy Jaeryang Baek
260ead64da refac 2026-05-21 14:01:57 +04:00
Timothy Jaeryang Baek
9c14740ffb refac 2026-05-14 13:12:59 +09:00
Timothy Jaeryang Baek
6d0295588e refac: modernize type annotations (PEP 604 / PEP 585) 2026-05-12 17:10:15 +09:00
Timothy Jaeryang Baek
15e696691c refac 2026-05-11 02:25:11 +09:00
Classic298
8a0018cf96
fix: gate public sharing of calendars behind sharing.public_calendars permission (#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>
2026-05-09 23:18:51 +09:00
Classic298
cfd2888545
fix:image url validation and signout post (#24420)
* refac(routers): reject external URLs in profile/model image handlers

* refac(ui): centralize image URL validation in safeImageUrl helper

* refac(auths): make signout POST-only

* refac: gate external profile image redirect behind ENABLE_PROFILE_IMAGE_URL_FORWARDING

Restore the 302 redirect for external http(s) profile image URLs in
the user and model profile-image endpoints, but gate it behind a new
ENABLE_PROFILE_IMAGE_URL_FORWARDING env flag (default: True).

Existing deployments that rely on external profile image forwarding
continue to work unchanged.  Operators who want to suppress the
redirect (to prevent client-side IP/UA/Referer leaks) can set the
flag to False.
2026-05-09 07:33:31 +09:00
Timothy Jaeryang Baek
fd3368c0bf refac 2026-05-09 01:55:51 +09:00
Timothy Jaeryang Baek
678c44c7cd refac 2026-04-24 16:17:46 +09:00
Timothy Jaeryang Baek
e29d145a1c refac 2026-04-20 08:48:35 +09:00
Classic298
5eae0a5cdd
perf(users): drop redundant get_user_by_id refetch in session-user endpoints (#23794)
* perf(users): drop redundant get_user_by_id refetch in session-user endpoints

Five /user/* handlers refetched the user row via Users.get_user_by_id(user.id)
immediately after receiving an identical UserModel from Depends(get_verified_user).
Since get_verified_user already populated the user within the same request
microseconds earlier, the refetch is pure overhead. The dead else branches
(unreachable — get_verified_user raises 401 on missing user) are removed as
a natural consequence.

Affected endpoints:
- GET  /user/settings
- GET  /user/status
- POST /user/status/update
- GET  /user/info
- POST /user/info/update

Eliminates one SELECT per request to each of these endpoints with no behavioral
change.

* fix(users): preserve USER_NOT_FOUND error on status update failure

update_user_status_by_id returns None when the target user is missing or
the update raises. The previous commit removed the pre-update existence
gate (get_user_by_id) and returned the update result directly, which
turned not-found/failure cases into 200 OK with a null body instead of
the expected 400 USER_NOT_FOUND.

Guard the update result explicitly to preserve the original API contract,
matching the equivalent pattern already applied in /user/info/update.

* docs(users): note lost-update tradeoff on /user/info/update

Make the concurrency tradeoff explicit: merging against the auth-time
snapshot slightly widens the lost-update window compared to the previous
pre-merge refetch, but the refetch only narrowed (did not eliminate) that
window. Real safety requires row locking or a version column.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-17 11:23:08 +09:00
Timothy Jaeryang Baek
3c2c611ba9 refac 2026-04-12 18:49:34 -05:00
Timothy Jaeryang Baek
25898116ea chore: format 2026-04-12 18:12:59 -05:00
Classic298
977d638afe
fix: invalidate stale Socket.IO sessions on role change and user deletion (#23642)
SESSION_POOL caches user.role at connection time and never refreshes it. When an admin demotes or deletes a user, their socket sessions retain the old cached role until voluntary disconnect, allowing continued use of admin-gated socket features (ydoc editing, channel access).

Adds disconnect_user_sessions() helper that disconnects all sockets for a user ID. Called from update_user_by_id (on role change) and delete_user_by_id. The client auto-reconnects and re-authenticates with fresh DB data.
2026-04-12 16:19:38 -05:00
Timothy Jaeryang Baek
27169124f2 refac: async db 2026-04-12 14:22:11 -05:00
Timothy Jaeryang Baek
5a2ff8b2e5 refac 2026-04-01 01:21:21 -05:00
Timothy Jaeryang Baek
ade617efa8 refac 2026-03-24 04:49:48 -05:00
Timothy Jaeryang Baek
de3317e26b refac 2026-03-17 17:58:01 -05:00
Timothy Jaeryang Baek
3d99de6771 enh: access grant level perms 2026-02-23 15:49:05 -06:00
Timothy Jaeryang Baek
2558fe1a3b refac 2026-02-22 19:16:35 -06:00
Timothy Jaeryang Baek
88401e91c7 refac 2026-02-15 23:28:47 -06:00
Timothy Jaeryang Baek
59afbd6f92 refac 2026-02-12 17:35:22 -06:00
Timothy Jaeryang Baek
f376d4f378 chore: format 2026-02-11 16:24:11 -06:00
Timothy Jaeryang Baek
c2f5cb542e refac 2026-02-09 14:03:35 -06:00
Timothy Jaeryang Baek
f7406ff576 refac 2026-02-09 13:28:14 -06:00
Timothy Jaeryang Baek
7da37b4f66 refac 2026-01-12 21:41:23 +04:00
Timothy Jaeryang Baek
b377e5ff4c chore: format 2026-01-09 02:46:04 +04:00
Classic298
9451b13dc6
feat: add ENABLE_USER_STATUS toggle for admin-controlled user status visibility (#20488)
* feat: add ENABLE_USER_STATUS toggle for admin-controlled user status visibility

feat: add ENABLE_USER_STATUS toggle for admin-controlled user status visibility

Add a new admin panel toggle (Admin > Settings > General) called "User Status" that allows administrators to globally enable or disable user status functionality.

When disabled:
- User status API endpoints return 403 Forbidden
- Status emoji, message, and "Update your status" button are hidden from the user menu

The setting:
- Defaults to True (enabled)
- Can be overridden via ENABLE_USER_STATUS environment variable
- Persists across restarts using PersistentConfig

Files modified:
- backend/open_webui/config.py - Added ENABLE_USER_STATUS PersistentConfig
- backend/open_webui/main.py - App state init and features dict
- backend/open_webui/routers/auths.py - AdminConfig model and endpoints
- backend/open_webui/routers/users.py - 403 guards on status endpoints
- src/lib/components/admin/Settings/General.svelte - Toggle UI
- src/lib/components/layout/Sidebar/UserMenu.svelte - Conditional status display

* Update UserMenu.svelte

feat: add ENABLE_USER_STATUS toggle for admin-controlled user status visibility

Add a new admin panel toggle (Admin > Settings > General) called "User Status" that allows administrators to globally enable or disable user status functionality.

When disabled:
- User status API endpoints return 403 Forbidden
- Active/Away indicator with blinking dot is hidden from the user menu
- Status emoji, message, and "Update your status" button are hidden from the user menu

The setting:
- Defaults to True (enabled)
- Can be overridden via ENABLE_USER_STATUS environment variable
- Persists across restarts using PersistentConfig

Files modified:
- backend/open_webui/config.py - Added ENABLE_USER_STATUS PersistentConfig
- backend/open_webui/main.py - App state init and features dict
- backend/open_webui/routers/auths.py - AdminConfig model and endpoints
- backend/open_webui/routers/users.py - 403 guards on status endpoints
- src/lib/components/admin/Settings/General.svelte - Toggle UI
- src/lib/components/layout/Sidebar/UserMenu.svelte - Conditional status display

* nuke the indicator

* fix
2026-01-09 00:55:57 +04:00
G30
b73d30b6df
feat: implement global memories toggle and permissions (#20462) 2026-01-07 23:50:04 +04:00
Classic298
732d9b484d
fix: resolve N+1 query pattern in users endpoint (#20427)
## Summary

Fixed N+1 query pattern in the `/api/v1/users` endpoint where groups were being fetched for each user individually.

### Problem

The `GET /api/v1/users` endpoint called `Groups.get_groups_by_member_id()` for each user, resulting in:
- 1 query for users
- N queries for groups (one per user)

### Solution

Added a new `Groups.get_groups_by_member_ids()` method that fetches groups for multiple users in a single query using SQL `IN` clause and `JOIN`.

### Changes

- **[groups.py](open_webui/models/groups.py)**: Added `get_groups_by_member_ids()` method
- **[users.py](open_webui/routers/users.py)**: Updated endpoint to use bulk method

### Result

- Before: 1 + N queries
- After: 2 queries total (1 for users, 1 for all groups)
2026-01-06 21:26:14 +04:00
Classic298
cc046695e6
feat: add interface user permission (#20424)
* feat: add interface user permission

Adds admin configurable user / group permissions for the interface settings section

* rename
2026-01-06 20:23:46 +04:00
Classic298
2c0ebbcced
fix: prevent null crashes in users and notes routers (#20279)
Add null checks for ui settings in update_user_settings_by_session_user() and for user in get_notes(). Prevents AttributeError when ui dict is None or when note's user has been deleted.
2025-12-31 02:30:14 -05:00
Timothy Jaeryang Baek
b1d0f00d8c refac/enh: db session sharing 2025-12-29 00:21:18 +04:00
landerrosette
d29271184e
fix: extract correct MIME type from base64 profile images (#20171) 2025-12-26 18:27:18 +04:00
Classic298
823b9a6dd9
chore/perf: Remove old SRC level log env vars with no impact (#20045)
* Update openai.py

* Update env.py

* Merge pull request open-webui#19030 from open-webui/dev (#119)

Co-authored-by: Tim Baek <tim@openwebui.com>
Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Tim Baek <tim@openwebui.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-20 08:16:14 -05:00
Timothy Jaeryang Baek
2b1a29d44b enh: display user groups in user preview 2025-12-08 12:45:52 -05:00
Timothy Jaeryang Baek
51621ba91a feat/enh: user status 2025-12-01 13:18:59 -05:00
Timothy Jaeryang Baek
f589b7c189 feat/enh: group channel 2025-11-30 08:24:27 -05:00
Timothy Jaeryang Baek
70948f8803 enh/refac: deprecate USER_POOL 2025-11-28 07:39:02 -05:00