enh: access grant level perms
This commit is contained in:
@@ -1433,6 +1433,10 @@ USER_PERMISSIONS_NOTES_ALLOW_PUBLIC_SHARING = (
|
|||||||
== "true"
|
== "true"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
USER_PERMISSIONS_ACCESS_GRANTS_ALLOW_USERS = (
|
||||||
|
os.environ.get("USER_PERMISSIONS_ACCESS_GRANTS_ALLOW_USERS", "True").lower() == "true"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
USER_PERMISSIONS_CHAT_CONTROLS = (
|
USER_PERMISSIONS_CHAT_CONTROLS = (
|
||||||
os.environ.get("USER_PERMISSIONS_CHAT_CONTROLS", "True").lower() == "true"
|
os.environ.get("USER_PERMISSIONS_CHAT_CONTROLS", "True").lower() == "true"
|
||||||
@@ -1590,6 +1594,9 @@ DEFAULT_USER_PERMISSIONS = {
|
|||||||
"notes": USER_PERMISSIONS_NOTES_ALLOW_SHARING,
|
"notes": USER_PERMISSIONS_NOTES_ALLOW_SHARING,
|
||||||
"public_notes": USER_PERMISSIONS_NOTES_ALLOW_PUBLIC_SHARING,
|
"public_notes": USER_PERMISSIONS_NOTES_ALLOW_PUBLIC_SHARING,
|
||||||
},
|
},
|
||||||
|
"access_grants": {
|
||||||
|
"allow_users": USER_PERMISSIONS_ACCESS_GRANTS_ALLOW_USERS,
|
||||||
|
},
|
||||||
"chat": {
|
"chat": {
|
||||||
"controls": USER_PERMISSIONS_CHAT_CONTROLS,
|
"controls": USER_PERMISSIONS_CHAT_CONTROLS,
|
||||||
"valves": USER_PERMISSIONS_CHAT_VALVES,
|
"valves": USER_PERMISSIONS_CHAT_VALVES,
|
||||||
|
|||||||
@@ -204,6 +204,33 @@ def has_public_read_access_grant(access_grants: Optional[list]) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def has_user_access_grant(access_grants: Optional[list]) -> bool:
|
||||||
|
"""
|
||||||
|
Returns True when a direct grant list includes any non-wildcard user grant.
|
||||||
|
"""
|
||||||
|
for grant in normalize_access_grants(access_grants):
|
||||||
|
if grant["principal_type"] == "user" and grant["principal_id"] != "*":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def strip_user_access_grants(access_grants: Optional[list]) -> list:
|
||||||
|
"""
|
||||||
|
Remove all non-wildcard user grants from the list.
|
||||||
|
Keeps group grants and the public wildcard (user:*) intact.
|
||||||
|
"""
|
||||||
|
if not access_grants:
|
||||||
|
return []
|
||||||
|
return [
|
||||||
|
grant
|
||||||
|
for grant in access_grants
|
||||||
|
if not (
|
||||||
|
(grant.get("principal_type") if isinstance(grant, dict) else getattr(grant, "principal_type", None)) == "user"
|
||||||
|
and (grant.get("principal_id") if isinstance(grant, dict) else getattr(grant, "principal_id", None)) != "*"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def grants_to_access_control(grants: list) -> Optional[dict]:
|
def grants_to_access_control(grants: list) -> Optional[dict]:
|
||||||
"""
|
"""
|
||||||
Convert a list of grant objects (AccessGrantModel or AccessGrantResponse)
|
Convert a list of grant objects (AccessGrantModel or AccessGrantResponse)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ from open_webui.storage.provider import Storage
|
|||||||
from open_webui.constants import ERROR_MESSAGES
|
from open_webui.constants import ERROR_MESSAGES
|
||||||
from open_webui.utils.auth import get_verified_user, get_admin_user
|
from open_webui.utils.auth import get_verified_user, get_admin_user
|
||||||
from open_webui.utils.access_control import has_permission
|
from open_webui.utils.access_control import has_permission
|
||||||
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant
|
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant, has_user_access_grant, strip_user_access_grants
|
||||||
|
|
||||||
|
|
||||||
from open_webui.config import BYPASS_ADMIN_ACCESS_CONTROL
|
from open_webui.config import BYPASS_ADMIN_ACCESS_CONTROL
|
||||||
@@ -274,6 +274,18 @@ async def create_new_knowledge(
|
|||||||
):
|
):
|
||||||
form_data.access_grants = []
|
form_data.access_grants = []
|
||||||
|
|
||||||
|
# Strip individual user sharing if user lacks permission
|
||||||
|
if (
|
||||||
|
user.role != "admin"
|
||||||
|
and has_user_access_grant(form_data.access_grants)
|
||||||
|
and not has_permission(
|
||||||
|
user.id,
|
||||||
|
"access_grants.allow_users",
|
||||||
|
request.app.state.config.USER_PERMISSIONS,
|
||||||
|
)
|
||||||
|
):
|
||||||
|
form_data.access_grants = strip_user_access_grants(form_data.access_grants)
|
||||||
|
|
||||||
knowledge = Knowledges.insert_new_knowledge(user.id, form_data)
|
knowledge = Knowledges.insert_new_knowledge(user.id, form_data)
|
||||||
|
|
||||||
if knowledge:
|
if knowledge:
|
||||||
@@ -494,6 +506,18 @@ async def update_knowledge_by_id(
|
|||||||
):
|
):
|
||||||
form_data.access_grants = []
|
form_data.access_grants = []
|
||||||
|
|
||||||
|
# Strip individual user sharing if user lacks permission
|
||||||
|
if (
|
||||||
|
user.role != "admin"
|
||||||
|
and has_user_access_grant(form_data.access_grants)
|
||||||
|
and not has_permission(
|
||||||
|
user.id,
|
||||||
|
"access_grants.allow_users",
|
||||||
|
request.app.state.config.USER_PERMISSIONS,
|
||||||
|
)
|
||||||
|
):
|
||||||
|
form_data.access_grants = strip_user_access_grants(form_data.access_grants)
|
||||||
|
|
||||||
knowledge = Knowledges.update_knowledge_by_id(id=id, form_data=form_data)
|
knowledge = Knowledges.update_knowledge_by_id(id=id, form_data=form_data)
|
||||||
if knowledge:
|
if knowledge:
|
||||||
# Re-embed knowledge base for semantic search
|
# Re-embed knowledge base for semantic search
|
||||||
@@ -573,6 +597,18 @@ async def update_knowledge_access_by_id(
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Strip individual user sharing if user lacks permission
|
||||||
|
if (
|
||||||
|
user.role != "admin"
|
||||||
|
and has_user_access_grant(form_data.access_grants)
|
||||||
|
and not has_permission(
|
||||||
|
user.id,
|
||||||
|
"access_grants.allow_users",
|
||||||
|
request.app.state.config.USER_PERMISSIONS,
|
||||||
|
)
|
||||||
|
):
|
||||||
|
form_data.access_grants = strip_user_access_grants(form_data.access_grants)
|
||||||
|
|
||||||
AccessGrants.set_access_grants("knowledge", id, form_data.access_grants, db=db)
|
AccessGrants.set_access_grants("knowledge", id, form_data.access_grants, db=db)
|
||||||
|
|
||||||
return KnowledgeFilesResponse(
|
return KnowledgeFilesResponse(
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ from open_webui.models.models import (
|
|||||||
ModelAccessResponse,
|
ModelAccessResponse,
|
||||||
Models,
|
Models,
|
||||||
)
|
)
|
||||||
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant
|
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant, has_user_access_grant, strip_user_access_grants
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from open_webui.constants import ERROR_MESSAGES
|
from open_webui.constants import ERROR_MESSAGES
|
||||||
@@ -584,6 +584,18 @@ async def update_model_access_by_id(
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Strip individual user sharing if user lacks permission
|
||||||
|
if (
|
||||||
|
user.role != "admin"
|
||||||
|
and has_user_access_grant(form_data.access_grants)
|
||||||
|
and not has_permission(
|
||||||
|
user.id,
|
||||||
|
"access_grants.allow_users",
|
||||||
|
request.app.state.config.USER_PERMISSIONS,
|
||||||
|
)
|
||||||
|
):
|
||||||
|
form_data.access_grants = strip_user_access_grants(form_data.access_grants)
|
||||||
|
|
||||||
AccessGrants.set_access_grants(
|
AccessGrants.set_access_grants(
|
||||||
"model", form_data.id, form_data.access_grants, db=db
|
"model", form_data.id, form_data.access_grants, db=db
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ from open_webui.constants import ERROR_MESSAGES
|
|||||||
|
|
||||||
from open_webui.utils.auth import get_admin_user, get_verified_user
|
from open_webui.utils.auth import get_admin_user, get_verified_user
|
||||||
from open_webui.utils.access_control import has_permission
|
from open_webui.utils.access_control import has_permission
|
||||||
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant
|
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant, has_user_access_grant, strip_user_access_grants
|
||||||
from open_webui.internal.db import get_session
|
from open_webui.internal.db import get_session
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
@@ -296,6 +296,18 @@ async def update_note_by_id(
|
|||||||
):
|
):
|
||||||
form_data.access_grants = []
|
form_data.access_grants = []
|
||||||
|
|
||||||
|
# Strip individual user sharing if user lacks permission
|
||||||
|
if (
|
||||||
|
user.role != "admin"
|
||||||
|
and has_user_access_grant(form_data.access_grants)
|
||||||
|
and not has_permission(
|
||||||
|
user.id,
|
||||||
|
"access_grants.allow_users",
|
||||||
|
request.app.state.config.USER_PERMISSIONS,
|
||||||
|
)
|
||||||
|
):
|
||||||
|
form_data.access_grants = strip_user_access_grants(form_data.access_grants)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
note = Notes.update_note_by_id(id, form_data, db=db)
|
note = Notes.update_note_by_id(id, form_data, db=db)
|
||||||
await sio.emit(
|
await sio.emit(
|
||||||
@@ -376,6 +388,18 @@ async def update_note_access_by_id(
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Strip individual user sharing if user lacks permission
|
||||||
|
if (
|
||||||
|
user.role != "admin"
|
||||||
|
and has_user_access_grant(form_data.access_grants)
|
||||||
|
and not has_permission(
|
||||||
|
user.id,
|
||||||
|
"access_grants.allow_users",
|
||||||
|
request.app.state.config.USER_PERMISSIONS,
|
||||||
|
)
|
||||||
|
):
|
||||||
|
form_data.access_grants = strip_user_access_grants(form_data.access_grants)
|
||||||
|
|
||||||
AccessGrants.set_access_grants("note", id, form_data.access_grants, db=db)
|
AccessGrants.set_access_grants("note", id, form_data.access_grants, db=db)
|
||||||
|
|
||||||
return Notes.get_note_by_id(id, db=db)
|
return Notes.get_note_by_id(id, db=db)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from open_webui.models.prompts import (
|
|||||||
PromptModel,
|
PromptModel,
|
||||||
Prompts,
|
Prompts,
|
||||||
)
|
)
|
||||||
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant
|
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant, has_user_access_grant, strip_user_access_grants
|
||||||
from open_webui.models.groups import Groups
|
from open_webui.models.groups import Groups
|
||||||
from open_webui.models.prompt_history import (
|
from open_webui.models.prompt_history import (
|
||||||
PromptHistories,
|
PromptHistories,
|
||||||
@@ -492,6 +492,18 @@ async def update_prompt_access_by_id(
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Strip individual user sharing if user lacks permission
|
||||||
|
if (
|
||||||
|
user.role != "admin"
|
||||||
|
and has_user_access_grant(form_data.access_grants)
|
||||||
|
and not has_permission(
|
||||||
|
user.id,
|
||||||
|
"access_grants.allow_users",
|
||||||
|
request.app.state.config.USER_PERMISSIONS,
|
||||||
|
)
|
||||||
|
):
|
||||||
|
form_data.access_grants = strip_user_access_grants(form_data.access_grants)
|
||||||
|
|
||||||
AccessGrants.set_access_grants("prompt", prompt_id, form_data.access_grants, db=db)
|
AccessGrants.set_access_grants("prompt", prompt_id, form_data.access_grants, db=db)
|
||||||
|
|
||||||
return Prompts.get_prompt_by_id(prompt_id, db=db)
|
return Prompts.get_prompt_by_id(prompt_id, db=db)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ from open_webui.models.skills import (
|
|||||||
SkillAccessListResponse,
|
SkillAccessListResponse,
|
||||||
Skills,
|
Skills,
|
||||||
)
|
)
|
||||||
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant
|
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant, has_user_access_grant, strip_user_access_grants
|
||||||
from open_webui.utils.auth import get_admin_user, get_verified_user
|
from open_webui.utils.auth import get_admin_user, get_verified_user
|
||||||
from open_webui.utils.access_control import has_access, has_permission
|
from open_webui.utils.access_control import has_access, has_permission
|
||||||
|
|
||||||
@@ -360,6 +360,18 @@ async def update_skill_access_by_id(
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Strip individual user sharing if user lacks permission
|
||||||
|
if (
|
||||||
|
user.role != "admin"
|
||||||
|
and has_user_access_grant(form_data.access_grants)
|
||||||
|
and not has_permission(
|
||||||
|
user.id,
|
||||||
|
"access_grants.allow_users",
|
||||||
|
request.app.state.config.USER_PERMISSIONS,
|
||||||
|
)
|
||||||
|
):
|
||||||
|
form_data.access_grants = strip_user_access_grants(form_data.access_grants)
|
||||||
|
|
||||||
AccessGrants.set_access_grants("skill", id, form_data.access_grants, db=db)
|
AccessGrants.set_access_grants("skill", id, form_data.access_grants, db=db)
|
||||||
|
|
||||||
return Skills.get_skill_by_id(id, db=db)
|
return Skills.get_skill_by_id(id, db=db)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ from open_webui.models.tools import (
|
|||||||
ToolAccessResponse,
|
ToolAccessResponse,
|
||||||
Tools,
|
Tools,
|
||||||
)
|
)
|
||||||
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant
|
from open_webui.models.access_grants import AccessGrants, has_public_read_access_grant, has_user_access_grant, strip_user_access_grants
|
||||||
from open_webui.utils.plugin import (
|
from open_webui.utils.plugin import (
|
||||||
load_tool_module_by_id,
|
load_tool_module_by_id,
|
||||||
replace_imports,
|
replace_imports,
|
||||||
@@ -595,6 +595,18 @@ async def update_tool_access_by_id(
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Strip individual user sharing if user lacks permission
|
||||||
|
if (
|
||||||
|
user.role != "admin"
|
||||||
|
and has_user_access_grant(form_data.access_grants)
|
||||||
|
and not has_permission(
|
||||||
|
user.id,
|
||||||
|
"access_grants.allow_users",
|
||||||
|
request.app.state.config.USER_PERMISSIONS,
|
||||||
|
)
|
||||||
|
):
|
||||||
|
form_data.access_grants = strip_user_access_grants(form_data.access_grants)
|
||||||
|
|
||||||
AccessGrants.set_access_grants("tool", id, form_data.access_grants, db=db)
|
AccessGrants.set_access_grants("tool", id, form_data.access_grants, db=db)
|
||||||
|
|
||||||
return Tools.get_tool_by_id(id, db=db)
|
return Tools.get_tool_by_id(id, db=db)
|
||||||
|
|||||||
@@ -196,6 +196,10 @@ class SharingPermissions(BaseModel):
|
|||||||
public_notes: bool = True
|
public_notes: bool = True
|
||||||
|
|
||||||
|
|
||||||
|
class AccessGrantsPermissions(BaseModel):
|
||||||
|
allow_users: bool = True
|
||||||
|
|
||||||
|
|
||||||
class ChatPermissions(BaseModel):
|
class ChatPermissions(BaseModel):
|
||||||
controls: bool = True
|
controls: bool = True
|
||||||
valves: bool = True
|
valves: bool = True
|
||||||
@@ -239,6 +243,7 @@ class SettingsPermissions(BaseModel):
|
|||||||
class UserPermissions(BaseModel):
|
class UserPermissions(BaseModel):
|
||||||
workspace: WorkspacePermissions
|
workspace: WorkspacePermissions
|
||||||
sharing: SharingPermissions
|
sharing: SharingPermissions
|
||||||
|
access_grants: AccessGrantsPermissions
|
||||||
chat: ChatPermissions
|
chat: ChatPermissions
|
||||||
features: FeaturesPermissions
|
features: FeaturesPermissions
|
||||||
settings: SettingsPermissions
|
settings: SettingsPermissions
|
||||||
@@ -253,6 +258,9 @@ async def get_default_user_permissions(request: Request, user=Depends(get_admin_
|
|||||||
"sharing": SharingPermissions(
|
"sharing": SharingPermissions(
|
||||||
**request.app.state.config.USER_PERMISSIONS.get("sharing", {})
|
**request.app.state.config.USER_PERMISSIONS.get("sharing", {})
|
||||||
),
|
),
|
||||||
|
"access_grants": AccessGrantsPermissions(
|
||||||
|
**request.app.state.config.USER_PERMISSIONS.get("access_grants", {})
|
||||||
|
),
|
||||||
"chat": ChatPermissions(
|
"chat": ChatPermissions(
|
||||||
**request.app.state.config.USER_PERMISSIONS.get("chat", {})
|
**request.app.state.config.USER_PERMISSIONS.get("chat", {})
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -395,6 +395,28 @@
|
|||||||
|
|
||||||
<hr class=" border-gray-100/30 dark:border-gray-850/30" />
|
<hr class=" border-gray-100/30 dark:border-gray-850/30" />
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class=" mb-2 text-sm font-medium">{$i18n.t('Access Grants')}</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col w-full">
|
||||||
|
<div class="flex w-full justify-between my-1">
|
||||||
|
<div class=" self-center text-xs font-medium">
|
||||||
|
{$i18n.t('Allow Sharing With Users')}
|
||||||
|
</div>
|
||||||
|
<Switch bind:state={permissions.access_grants.allow_users} />
|
||||||
|
</div>
|
||||||
|
{#if defaultPermissions?.access_grants?.allow_users && !permissions.access_grants.allow_users}
|
||||||
|
<div>
|
||||||
|
<div class="text-xs text-gray-500">
|
||||||
|
{$i18n.t('This is a default user permission and will remain enabled.')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class=" border-gray-100/30 dark:border-gray-850/30" />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class=" mb-2 text-sm font-medium">{$i18n.t('Chat Permissions')}</div>
|
<div class=" mb-2 text-sm font-medium">{$i18n.t('Chat Permissions')}</div>
|
||||||
|
|
||||||
|
|||||||
@@ -871,6 +871,9 @@ Provide the enhanced notes in markdown format. Use markdown syntax for headings,
|
|||||||
bind:show={showAccessControlModal}
|
bind:show={showAccessControlModal}
|
||||||
bind:accessGrants={note.access_grants}
|
bind:accessGrants={note.access_grants}
|
||||||
accessRoles={['read', 'write']}
|
accessRoles={['read', 'write']}
|
||||||
|
share={$user?.permissions?.sharing?.notes || $user?.role === 'admin'}
|
||||||
|
sharePublic={$user?.permissions?.sharing?.public_notes || $user?.role === 'admin'}
|
||||||
|
shareUsers={$user?.permissions?.access_grants?.allow_users || $user?.role === 'admin'}
|
||||||
onChange={async () => {
|
onChange={async () => {
|
||||||
if (id) {
|
if (id) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -115,6 +115,7 @@
|
|||||||
accessRoles={['read', 'write']}
|
accessRoles={['read', 'write']}
|
||||||
share={$user?.permissions?.sharing?.knowledge || $user?.role === 'admin'}
|
share={$user?.permissions?.sharing?.knowledge || $user?.role === 'admin'}
|
||||||
sharePublic={$user?.permissions?.sharing?.public_knowledge || $user?.role === 'admin'}
|
sharePublic={$user?.permissions?.sharing?.public_knowledge || $user?.role === 'admin'}
|
||||||
|
shareUsers={$user?.permissions?.access_grants?.allow_users || $user?.role === "admin"}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -837,6 +837,7 @@
|
|||||||
bind:accessGrants={knowledge.access_grants}
|
bind:accessGrants={knowledge.access_grants}
|
||||||
share={$user?.permissions?.sharing?.knowledge || $user?.role === 'admin'}
|
share={$user?.permissions?.sharing?.knowledge || $user?.role === 'admin'}
|
||||||
sharePublic={$user?.permissions?.sharing?.public_knowledge || $user?.role === 'admin'}
|
sharePublic={$user?.permissions?.sharing?.public_knowledge || $user?.role === 'admin'}
|
||||||
|
shareUsers={$user?.permissions?.access_grants?.allow_users || $user?.role === "admin"}
|
||||||
onChange={async () => {
|
onChange={async () => {
|
||||||
try {
|
try {
|
||||||
await updateKnowledgeAccessGrants(localStorage.token, id, knowledge.access_grants ?? []);
|
await updateKnowledgeAccessGrants(localStorage.token, id, knowledge.access_grants ?? []);
|
||||||
|
|||||||
@@ -332,6 +332,7 @@
|
|||||||
accessRoles={preset ? ['read', 'write'] : ['read']}
|
accessRoles={preset ? ['read', 'write'] : ['read']}
|
||||||
share={$user?.permissions?.sharing?.models || $user?.role === 'admin'}
|
share={$user?.permissions?.sharing?.models || $user?.role === 'admin'}
|
||||||
sharePublic={$user?.permissions?.sharing?.public_models || $user?.role === 'admin'}
|
sharePublic={$user?.permissions?.sharing?.public_models || $user?.role === 'admin'}
|
||||||
|
shareUsers={$user?.permissions?.access_grants?.allow_users || $user?.role === "admin"}
|
||||||
onChange={async () => {
|
onChange={async () => {
|
||||||
if (edit && model?.id) {
|
if (edit && model?.id) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -283,6 +283,7 @@
|
|||||||
accessRoles={['read', 'write']}
|
accessRoles={['read', 'write']}
|
||||||
share={$user?.permissions?.sharing?.prompts || $user?.role === 'admin'}
|
share={$user?.permissions?.sharing?.prompts || $user?.role === 'admin'}
|
||||||
sharePublic={$user?.permissions?.sharing?.public_prompts || $user?.role === 'admin'}
|
sharePublic={$user?.permissions?.sharing?.public_prompts || $user?.role === 'admin'}
|
||||||
|
shareUsers={$user?.permissions?.access_grants?.allow_users || $user?.role === 'admin'}
|
||||||
onChange={async () => {
|
onChange={async () => {
|
||||||
if (edit && prompt?.id) {
|
if (edit && prompt?.id) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -114,6 +114,7 @@
|
|||||||
accessRoles={['read', 'write']}
|
accessRoles={['read', 'write']}
|
||||||
share={$user?.permissions?.sharing?.skills || $user?.role === 'admin'}
|
share={$user?.permissions?.sharing?.skills || $user?.role === 'admin'}
|
||||||
sharePublic={$user?.permissions?.sharing?.public_skills || $user?.role === 'admin'}
|
sharePublic={$user?.permissions?.sharing?.public_skills || $user?.role === 'admin'}
|
||||||
|
shareUsers={$user?.permissions?.access_grants?.allow_users || $user?.role === 'admin'}
|
||||||
onChange={async () => {
|
onChange={async () => {
|
||||||
if (edit && skill?.id) {
|
if (edit && skill?.id) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -193,6 +193,7 @@ class Tools:
|
|||||||
accessRoles={['read', 'write']}
|
accessRoles={['read', 'write']}
|
||||||
share={$user?.permissions?.sharing?.tools || $user?.role === 'admin'}
|
share={$user?.permissions?.sharing?.tools || $user?.role === 'admin'}
|
||||||
sharePublic={$user?.permissions?.sharing?.public_tools || $user?.role === 'admin'}
|
sharePublic={$user?.permissions?.sharing?.public_tools || $user?.role === 'admin'}
|
||||||
|
shareUsers={$user?.permissions?.access_grants?.allow_users || $user?.role === 'admin'}
|
||||||
onChange={async () => {
|
onChange={async () => {
|
||||||
if (edit && id) {
|
if (edit && id) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
export let share = true;
|
export let share = true;
|
||||||
export let sharePublic = true;
|
export let sharePublic = true;
|
||||||
|
export let shareUsers = true;
|
||||||
|
|
||||||
let groups: any[] = [];
|
let groups: any[] = [];
|
||||||
const resolvingGroupIds = new Set<string>();
|
const resolvingGroupIds = new Set<string>();
|
||||||
@@ -419,7 +420,7 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<AddAccessModal bind:show={showAddAccessModal} onAdd={handleAddAccess} />
|
<AddAccessModal bind:show={showAddAccessModal} {shareUsers} onAdd={handleAddAccess} />
|
||||||
|
|
||||||
<div class=" rounded-lg flex flex-col gap-1">
|
<div class=" rounded-lg flex flex-col gap-1">
|
||||||
<div class="py-2">
|
<div class="py-2">
|
||||||
@@ -562,6 +563,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
<!-- Users -->
|
<!-- Users -->
|
||||||
|
{#if shareUsers}
|
||||||
{#each selectedUsers as user}
|
{#each selectedUsers as user}
|
||||||
<div
|
<div
|
||||||
class="flex items-center gap-3 justify-between text-sm w-full transition border-b border-gray-50 dark:border-gray-850 pb-2 last:border-0"
|
class="flex items-center gap-3 justify-between text-sm w-full transition border-b border-gray-50 dark:border-gray-850 pb-2 last:border-0"
|
||||||
@@ -607,6 +609,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if !hasPublicReadGrant(accessGrants ?? []) && accessGroups.length === 0 && selectedUsers.length === 0}
|
{#if !hasPublicReadGrant(accessGrants ?? []) && accessGroups.length === 0 && selectedUsers.length === 0}
|
||||||
<div class="text-xs text-gray-500 text-center py-4">
|
<div class="text-xs text-gray-500 text-center py-4">
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
export let share = true;
|
export let share = true;
|
||||||
export let sharePublic = true;
|
export let sharePublic = true;
|
||||||
|
export let shareUsers = true;
|
||||||
|
|
||||||
export let onChange = () => {};
|
export let onChange = () => {};
|
||||||
</script>
|
</script>
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
{accessRoles}
|
{accessRoles}
|
||||||
{share}
|
{share}
|
||||||
{sharePublic}
|
{sharePublic}
|
||||||
|
{shareUsers}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
import MemberSelector from '$lib/components/workspace/common/MemberSelector.svelte';
|
import MemberSelector from '$lib/components/workspace/common/MemberSelector.svelte';
|
||||||
|
|
||||||
export let show = false;
|
export let show = false;
|
||||||
|
export let shareUsers = true;
|
||||||
export let onAdd = (payload: { userIds: string[]; groupIds: string[] }) => {};
|
export let onAdd = (payload: { userIds: string[]; groupIds: string[] }) => {};
|
||||||
|
|
||||||
let userIds: string[] = [];
|
let userIds: string[] = [];
|
||||||
@@ -51,7 +52,7 @@
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="flex flex-col w-full h-full pb-2">
|
<div class="flex flex-col w-full h-full pb-2">
|
||||||
<MemberSelector bind:userIds bind:groupIds includeGroups={true} />
|
<MemberSelector bind:userIds bind:groupIds includeGroups={true} includeUsers={shareUsers} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end pt-3 text-sm font-medium gap-1.5">
|
<div class="flex justify-end pt-3 text-sm font-medium gap-1.5">
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
import { getGroups } from '$lib/apis/groups';
|
import { getGroups } from '$lib/apis/groups';
|
||||||
|
|
||||||
export let includeGroups = true;
|
export let includeGroups = true;
|
||||||
|
export let includeUsers = true;
|
||||||
export let pagination = false;
|
export let pagination = false;
|
||||||
|
|
||||||
export let groupIds = [];
|
export let groupIds = [];
|
||||||
@@ -237,6 +238,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if includeUsers}
|
||||||
<div class="text-xs text-gray-500 mb-1 mx-1">
|
<div class="text-xs text-gray-500 mb-1 mx-1">
|
||||||
{$i18n.t('Users')}
|
{$i18n.t('Users')}
|
||||||
</div>
|
</div>
|
||||||
@@ -295,6 +297,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ export const DEFAULT_PERMISSIONS = {
|
|||||||
notes: false,
|
notes: false,
|
||||||
public_notes: false
|
public_notes: false
|
||||||
},
|
},
|
||||||
|
access_grants: {
|
||||||
|
allow_users: true
|
||||||
|
},
|
||||||
chat: {
|
chat: {
|
||||||
controls: true,
|
controls: true,
|
||||||
valves: true,
|
valves: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user