fix: enforce public sharing permission checks across all resource types (#21358)

The sharePublic prop in editor components (Knowledge, Tools, Skills,
Prompts, Models) incorrectly included an "|| edit" / "|| write_access"
condition, allowing users with write access to see and use the "Public"
sharing option regardless of their actual public sharing permission.
Additionally, all backend access/update endpoints only verified write
authorization but did not check the corresponding sharing.public_*
permission, allowing direct API calls to bypass frontend restrictions
entirely.
Frontend: removed the edit/write_access bypass from sharePublic in all
five editor components so visibility is gated solely by the user's
sharing.public_* permission or admin role.
Backend: added has_public_read_access_grant checks to the access/update
endpoints in knowledge.py, tools.py, prompts.py, skills.py, models.py,
and notes.py. Public grants are silently stripped when the user lacks
the corresponding permission.
Fixes #21356
This commit is contained in:
Classic298
2026-02-13 11:22:32 -06:00
committed by GitHub
parent 7bda6bf767
commit 73776d54b8
11 changed files with 122 additions and 10 deletions
+20 -1
View File
@@ -9,7 +9,7 @@ from open_webui.models.prompts import (
PromptModel,
Prompts,
)
from open_webui.models.access_grants import AccessGrants
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant
from open_webui.models.groups import Groups
from open_webui.models.prompt_history import (
PromptHistories,
@@ -436,6 +436,7 @@ class PromptAccessGrantsForm(BaseModel):
@router.post("/id/{prompt_id}/access/update", response_model=Optional[PromptModel])
async def update_prompt_access_by_id(
request: Request,
prompt_id: str,
form_data: PromptAccessGrantsForm,
user=Depends(get_verified_user),
@@ -464,6 +465,24 @@ async def update_prompt_access_by_id(
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
)
# Strip public sharing if user lacks permission
if (
user.role != "admin"
and has_public_read_access_grant(form_data.access_grants)
and not has_permission(
user.id,
"sharing.public_prompts",
request.app.state.config.USER_PERMISSIONS,
)
):
form_data.access_grants = [
g for g in form_data.access_grants
if not (
g.get("principal_type") == "user"
and g.get("principal_id") == "*"
)
]
AccessGrants.set_access_grants("prompt", prompt_id, form_data.access_grants, db=db)
return Prompts.get_prompt_by_id(prompt_id, db=db)