diff --git a/backend/open_webui/models/prompts.py b/backend/open_webui/models/prompts.py index eefb74de5..89c49ccc8 100644 --- a/backend/open_webui/models/prompts.py +++ b/backend/open_webui/models/prompts.py @@ -64,6 +64,10 @@ class PromptUserResponse(PromptModel): user: Optional[UserResponse] = None +class PromptAccessResponse(PromptUserResponse): + write_access: Optional[bool] = False + + class PromptForm(BaseModel): command: str title: str diff --git a/backend/open_webui/routers/prompts.py b/backend/open_webui/routers/prompts.py index 70f9f71e5..645cfe83a 100644 --- a/backend/open_webui/routers/prompts.py +++ b/backend/open_webui/routers/prompts.py @@ -4,6 +4,7 @@ from fastapi import APIRouter, Depends, HTTPException, status, Request from open_webui.models.prompts import ( PromptForm, PromptUserResponse, + PromptAccessResponse, PromptModel, Prompts, ) @@ -31,14 +32,24 @@ async def get_prompts(user=Depends(get_verified_user), db: Session = Depends(get return prompts -@router.get("/list", response_model=list[PromptUserResponse]) +@router.get("/list", response_model=list[PromptAccessResponse]) async def get_prompt_list(user=Depends(get_verified_user), db: Session = Depends(get_session)): if user.role == "admin" and BYPASS_ADMIN_ACCESS_CONTROL: prompts = Prompts.get_prompts(db=db) else: - prompts = Prompts.get_prompts_by_user_id(user.id, "write", db=db) + prompts = Prompts.get_prompts_by_user_id(user.id, "read", db=db) - return prompts + return [ + PromptAccessResponse( + **prompt.model_dump(), + write_access=( + (user.role == "admin" and BYPASS_ADMIN_ACCESS_CONTROL) + or user.id == prompt.user_id + or has_access(user.id, "write", prompt.access_control, db=db) + ), + ) + for prompt in prompts + ] ############################ @@ -87,7 +98,7 @@ async def create_new_prompt( ############################ -@router.get("/command/{command}", response_model=Optional[PromptModel]) +@router.get("/command/{command}", response_model=Optional[PromptAccessResponse]) async def get_prompt_by_command(command: str, user=Depends(get_verified_user), db: Session = Depends(get_session)): prompt = Prompts.get_prompt_by_command(f"/{command}", db=db) @@ -97,15 +108,17 @@ async def get_prompt_by_command(command: str, user=Depends(get_verified_user), d or prompt.user_id == user.id or has_access(user.id, "read", prompt.access_control, db=db) ): - return prompt - else: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + return PromptAccessResponse( + **prompt.model_dump(), + write_access=( + (user.role == "admin" and BYPASS_ADMIN_ACCESS_CONTROL) + or user.id == prompt.user_id + or has_access(user.id, "write", prompt.access_control, db=db) + ), ) else: raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND, ) diff --git a/src/lib/components/workspace/Prompts.svelte b/src/lib/components/workspace/Prompts.svelte index 446c29f7e..c95dd1dba 100644 --- a/src/lib/components/workspace/Prompts.svelte +++ b/src/lib/components/workspace/Prompts.svelte @@ -26,6 +26,7 @@ import XMark from '../icons/XMark.svelte'; import GarbageBin from '../icons/GarbageBin.svelte'; import ViewSelector from './common/ViewSelector.svelte'; + import Badge from '$lib/components/common/Badge.svelte'; let shiftKey = false; @@ -327,11 +328,16 @@ href={`/workspace/prompts/edit?command=${encodeURIComponent(prompt.command)}`} >
-
-
{prompt.title}
-
- {prompt.command} +
+
+
{prompt.title}
+
+ {prompt.command} +
+ {#if !prompt.write_access} + + {/if}
diff --git a/src/lib/components/workspace/Prompts/PromptEditor.svelte b/src/lib/components/workspace/Prompts/PromptEditor.svelte index 806beacaa..379dc6c76 100644 --- a/src/lib/components/workspace/Prompts/PromptEditor.svelte +++ b/src/lib/components/workspace/Prompts/PromptEditor.svelte @@ -15,6 +15,7 @@ export let edit = false; export let prompt = null; export let clone = false; + export let write_access = true; const i18n = getContext('i18n'); @@ -40,6 +41,10 @@ } const submitHandler = async () => { + if (!write_access) { + toast.error($i18n.t('You do not have permission to edit this prompt.')); + return; + } loading = true; if (validateCommandString(command)) { @@ -111,23 +116,30 @@ placeholder={$i18n.t('Title')} bind:value={title} required + disabled={!write_access} /> -
- -
+
+ {$i18n.t('Access')} +
+ +
+ {:else} +
+ {$i18n.t('Read Only')} +
+ {/if}
@@ -138,7 +150,7 @@ bind:value={command} on:input={handleCommandInput} required - disabled={edit} + disabled={edit || !write_access} />
@@ -158,6 +170,7 @@ bind:value={content} rows={6} required + disabled={!write_access} />
@@ -181,21 +194,22 @@
- + + +
diff --git a/src/routes/(app)/workspace/prompts/edit/+page.svelte b/src/routes/(app)/workspace/prompts/edit/+page.svelte index 9a317cc7c..7148b4a30 100644 --- a/src/routes/(app)/workspace/prompts/edit/+page.svelte +++ b/src/routes/(app)/workspace/prompts/edit/+page.svelte @@ -12,6 +12,8 @@ import PromptEditor from '$lib/components/workspace/Prompts/PromptEditor.svelte'; let prompt = null; + let write_access = true; + const onSubmit = async (_prompt) => { console.log(_prompt); const prompt = await updatePromptByCommand(localStorage.token, _prompt).catch((error) => { @@ -38,6 +40,7 @@ }); if (_prompt) { + write_access = _prompt.write_access ?? true; prompt = { title: _prompt.title, command: _prompt.command, @@ -54,5 +57,5 @@ {#if prompt} - + {/if}