mirror of
https://github.com/open-webui/open-webui.git
synced 2026-09-21 13:38:19 -05:00
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:
@@ -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()
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
};
|
||||
|
||||
let oauthConfig: any = null;
|
||||
$: oauthEditable = oauthConfig?.ENABLE_OAUTH_PERSISTENT_CONFIG ?? true;
|
||||
const inputClass =
|
||||
'w-full h-7 rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 text-xs text-gray-700 outline-hidden transition-colors placeholder:text-gray-300 focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:placeholder:text-gray-700 dark:focus:border-blue-500';
|
||||
const textareaClass =
|
||||
@@ -74,7 +75,7 @@
|
||||
};
|
||||
|
||||
const updateOAuthHandler = async () => {
|
||||
if (!oauthConfig) return true;
|
||||
if (!oauthConfig || !oauthEditable) return true;
|
||||
const res = await updateOAuthConfig(localStorage.token, oauthConfig).catch((error) => {
|
||||
toast.error(`${error}`);
|
||||
return null;
|
||||
@@ -526,6 +527,21 @@
|
||||
|
||||
{#if oauthConfig}
|
||||
<AdminSettingSection title={$i18n.t('OAuth / OIDC')}>
|
||||
{#if !oauthEditable}
|
||||
<div
|
||||
class="rounded-lg bg-yellow-500/10 px-2 py-1.5 text-[0.6875rem] text-yellow-700 dark:text-yellow-200"
|
||||
>
|
||||
{$i18n.t(
|
||||
'These settings are read from environment variables and cannot be edited here while {{ENV_VAR}} is disabled.',
|
||||
{ ENV_VAR: 'ENABLE_OAUTH_PERSISTENT_CONFIG' }
|
||||
)}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<fieldset
|
||||
class="flex min-w-0 flex-col gap-2.5 disabled:cursor-not-allowed disabled:opacity-75"
|
||||
disabled={!oauthEditable}
|
||||
>
|
||||
<AdminSettingRow
|
||||
label={$i18n.t('OAuth / OIDC')}
|
||||
description={$i18n.t('Allow users to authenticate with an OAuth / OIDC provider.')}
|
||||
@@ -831,6 +847,7 @@
|
||||
/>
|
||||
</AdminSettingRow>
|
||||
{/if}
|
||||
</fieldset>
|
||||
</AdminSettingSection>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
{id}
|
||||
aria-labelledby={ariaLabelledbyId || undefined}
|
||||
aria-label={ariaLabel || undefined}
|
||||
class="relative h-4 min-h-4 w-7 shrink-0 cursor-pointer rounded-full mx-[0.0625rem] transition-colors duration-150 {($settings?.highContrastMode ??
|
||||
class="relative h-4 min-h-4 w-7 shrink-0 cursor-pointer rounded-full mx-[0.0625rem] transition-colors duration-150 disabled:cursor-not-allowed {($settings?.highContrastMode ??
|
||||
false)
|
||||
? 'focus:outline focus:outline-2 focus:outline-gray-800 focus:dark:outline-gray-200'
|
||||
: 'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-400 dark:focus-visible:outline-gray-500'} {state
|
||||
|
||||
Reference in New Issue
Block a user