feat: make OAuth admin settings read-only when ENABLE_OAUTH_PERSISTENT_CONFIG is off (#28276)

When ENABLE_OAUTH_PERSISTENT_CONFIG is off (the default), oauth.* config is
never persisted and is read from environment variables, but the admin panel
still let admins edit the OAuth/OIDC fields and silently dropped every save on
restart, which kept confusing users who missed the docs warning
(open-webui/open-webui#28247).

The OAuth/OIDC section is now read-only in that case: the admin oauth config
endpoint reports the flag and the UI wraps the section in a disabled fieldset,
slightly dimmed with every control inert but all values still visible, plus a
note naming the env var. Saving skips the OAuth POST since nothing can change.
With the flag enabled the section behaves exactly as before.

Known limits: the guard is UI-side only (the POST endpoint keeps accepting
writes, unchanged), and disabled fields mean values cannot be selected and the
masked client secret cannot be revealed while read-only. Switch.svelte gains a
disabled:cursor-not-allowed style that applies to any disabled switch app-wide.

Co-authored-by: Tim Baek <tim@openwebui.com>
This commit is contained in:
Classic298
2026-08-10 21:41:07 -06:00
committed by GitHub
co-authored by Tim Baek
parent a3e5d0b362
commit a680f21e12
3 changed files with 291 additions and 268 deletions
+9 -3
View File
@@ -1428,11 +1428,13 @@ def _parse_oauth_update_value(field: str, value):
async def get_oauth_config_values() -> dict:
values = await Config.get_many(*OAUTH_CONFIG_KEYS.values())
return {
form_values = {
field: _format_oauth_form_value(field, values[storage_key])
for field, storage_key in OAUTH_CONFIG_KEYS.items()
if storage_key in values
}
form_values['ENABLE_OAUTH_PERSISTENT_CONFIG'] = Config.OAUTH_PERSISTENT_ENABLED
return form_values
def oauth_config_updates(data: dict) -> dict:
@@ -1443,12 +1445,16 @@ def oauth_config_updates(data: dict) -> dict:
}
@router.get('/admin/config/oauth', response_model=OAuthConfigForm)
class OAuthConfigResponse(OAuthConfigForm):
ENABLE_OAUTH_PERSISTENT_CONFIG: bool
@router.get('/admin/config/oauth', response_model=OAuthConfigResponse)
async def get_oauth_config(request: Request, user=Depends(get_admin_user)):
return await get_oauth_config_values()
@router.post('/admin/config/oauth', response_model=OAuthConfigForm)
@router.post('/admin/config/oauth', response_model=OAuthConfigResponse)
async def update_oauth_config(request: Request, form_data: OAuthConfigForm, user=Depends(get_admin_user)):
await Config.upsert(oauth_config_updates(form_data.model_dump(exclude_none=True)))
return await get_oauth_config_values()