mirror of
https://github.com/open-webui/open-webui
synced 2024-11-21 23:57:51 +00:00
refac
This commit is contained in:
parent
dff85c733d
commit
b80ec76435
@ -739,12 +739,12 @@ DEFAULT_USER_ROLE = PersistentConfig(
|
||||
os.getenv("DEFAULT_USER_ROLE", "pending"),
|
||||
)
|
||||
|
||||
USER_PERMISSIONS_CHAT_DELETION = (
|
||||
os.environ.get("USER_PERMISSIONS_CHAT_DELETION", "True").lower() == "true"
|
||||
USER_PERMISSIONS_CHAT_DELETE = (
|
||||
os.environ.get("USER_PERMISSIONS_CHAT_DELETE", "True").lower() == "true"
|
||||
)
|
||||
|
||||
USER_PERMISSIONS_CHAT_EDITING = (
|
||||
os.environ.get("USER_PERMISSIONS_CHAT_EDITING", "True").lower() == "true"
|
||||
USER_PERMISSIONS_CHAT_EDIT = (
|
||||
os.environ.get("USER_PERMISSIONS_CHAT_EDIT", "True").lower() == "true"
|
||||
)
|
||||
|
||||
USER_PERMISSIONS_CHAT_TEMPORARY = (
|
||||
@ -753,11 +753,11 @@ USER_PERMISSIONS_CHAT_TEMPORARY = (
|
||||
|
||||
USER_PERMISSIONS = PersistentConfig(
|
||||
"USER_PERMISSIONS",
|
||||
"ui.user_permissions",
|
||||
"user.permissions",
|
||||
{
|
||||
"chat": {
|
||||
"deletion": USER_PERMISSIONS_CHAT_DELETION,
|
||||
"editing": USER_PERMISSIONS_CHAT_EDITING,
|
||||
"deletion": USER_PERMISSIONS_CHAT_DELETE,
|
||||
"editing": USER_PERMISSIONS_CHAT_EDIT,
|
||||
"temporary": USER_PERMISSIONS_CHAT_TEMPORARY,
|
||||
}
|
||||
},
|
||||
@ -785,18 +785,6 @@ DEFAULT_ARENA_MODEL = {
|
||||
},
|
||||
}
|
||||
|
||||
ENABLE_MODEL_FILTER = PersistentConfig(
|
||||
"ENABLE_MODEL_FILTER",
|
||||
"model_filter.enable",
|
||||
os.environ.get("ENABLE_MODEL_FILTER", "False").lower() == "true",
|
||||
)
|
||||
MODEL_FILTER_LIST = os.environ.get("MODEL_FILTER_LIST", "")
|
||||
MODEL_FILTER_LIST = PersistentConfig(
|
||||
"MODEL_FILTER_LIST",
|
||||
"model_filter.list",
|
||||
[model.strip() for model in MODEL_FILTER_LIST.split(";")],
|
||||
)
|
||||
|
||||
WEBHOOK_URL = PersistentConfig(
|
||||
"WEBHOOK_URL", "webhook_url", os.environ.get("WEBHOOK_URL", "")
|
||||
)
|
||||
|
@ -70,13 +70,11 @@ from open_webui.config import (
|
||||
DEFAULT_LOCALE,
|
||||
ENABLE_ADMIN_CHAT_ACCESS,
|
||||
ENABLE_ADMIN_EXPORT,
|
||||
ENABLE_MODEL_FILTER,
|
||||
ENABLE_OLLAMA_API,
|
||||
ENABLE_OPENAI_API,
|
||||
ENABLE_TAGS_GENERATION,
|
||||
ENV,
|
||||
FRONTEND_BUILD_DIR,
|
||||
MODEL_FILTER_LIST,
|
||||
OAUTH_PROVIDERS,
|
||||
ENABLE_SEARCH_QUERY,
|
||||
SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE,
|
||||
@ -194,9 +192,6 @@ app.state.config = AppConfig()
|
||||
app.state.config.ENABLE_OPENAI_API = ENABLE_OPENAI_API
|
||||
app.state.config.ENABLE_OLLAMA_API = ENABLE_OLLAMA_API
|
||||
|
||||
app.state.config.ENABLE_MODEL_FILTER = ENABLE_MODEL_FILTER
|
||||
app.state.config.MODEL_FILTER_LIST = MODEL_FILTER_LIST
|
||||
|
||||
app.state.config.WEBHOOK_URL = WEBHOOK_URL
|
||||
|
||||
app.state.config.TASK_MODEL = TASK_MODEL
|
||||
|
@ -48,69 +48,38 @@
|
||||
let showCreateGroupModal = false;
|
||||
let showDefaultPermissionsModal = false;
|
||||
|
||||
const setGroups = async () => {
|
||||
groups = await getGroups(localStorage.token);
|
||||
};
|
||||
|
||||
const addGroupHandler = async (group) => {
|
||||
const res = await createNewGroup(localStorage.token, group).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (res) {
|
||||
toast.success($i18n.t('Group created successfully'));
|
||||
groups = await getGroups(localStorage.token);
|
||||
}
|
||||
};
|
||||
|
||||
const updateDefaultPermissionsHandler = async (permissions) => {
|
||||
console.log(permissions);
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
if ($user?.role !== 'admin') {
|
||||
await goto('/');
|
||||
} else {
|
||||
groups = await getGroups(localStorage.token);
|
||||
|
||||
// [
|
||||
// {
|
||||
// id: '1',
|
||||
// name: 'Group A',
|
||||
// description: 'Group A description',
|
||||
// permissions: {
|
||||
// model: {
|
||||
// enable_filter: false, // boolean
|
||||
// ids: [], // array of strings
|
||||
// default_id: null // null or string
|
||||
// },
|
||||
// workspace: {
|
||||
// models: false, // boolean
|
||||
// knowledge: false, // boolean
|
||||
// prompts: false // boolean
|
||||
// },
|
||||
// chat: {
|
||||
// delete: true, // boolean
|
||||
// edit: true, // boolean
|
||||
// temporary: true // boolean
|
||||
// }
|
||||
// },
|
||||
// user_ids: ['1', '2', '3'], // array of strings
|
||||
// admin_ids: ['1'] // array of strings
|
||||
// },
|
||||
// {
|
||||
// id: '2',
|
||||
// name: 'Moderators',
|
||||
// description: 'Moderators description',
|
||||
// permissions: {
|
||||
// model: {
|
||||
// enable_filter: false, // boolean
|
||||
// ids: [], // array of strings
|
||||
// default_id: null // null or string
|
||||
// },
|
||||
// workspace: {
|
||||
// models: false, // boolean
|
||||
// knowledge: false, // boolean
|
||||
// prompts: false // boolean
|
||||
// },
|
||||
// chat: {
|
||||
// delete: true, // boolean
|
||||
// edit: true, // boolean
|
||||
// temporary: true // boolean
|
||||
// }
|
||||
// },
|
||||
// user_ids: ['1', '5', '6'], // array of strings
|
||||
// admin_ids: ['1'] // array of strings
|
||||
// }
|
||||
// ];
|
||||
await setGroups();
|
||||
}
|
||||
loaded = true;
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if loaded}
|
||||
<AddGroupModal bind:show={showCreateGroupModal} />
|
||||
<AddGroupModal bind:show={showCreateGroupModal} onSubmit={addGroupHandler} />
|
||||
<div class="mt-0.5 mb-2 gap-1 flex flex-col md:flex-row justify-between">
|
||||
<div class="flex md:self-center text-lg font-medium px-0.5">
|
||||
{$i18n.t('Groups')}
|
||||
@ -196,7 +165,7 @@
|
||||
|
||||
{#each filteredGroups as group}
|
||||
<div class="my-2">
|
||||
<GroupItem {group} {users} />
|
||||
<GroupItem {group} {users} {setGroups} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
@ -204,7 +173,12 @@
|
||||
|
||||
<hr class="mb-2 border-gray-50 dark:border-gray-850" />
|
||||
|
||||
<GroupModal bind:show={showDefaultPermissionsModal} tabs={['permissions']} custom={false} />
|
||||
<GroupModal
|
||||
bind:show={showDefaultPermissionsModal}
|
||||
tabs={['permissions']}
|
||||
custom={false}
|
||||
onSubmit={updateDefaultPermissionsHandler}
|
||||
/>
|
||||
|
||||
<button
|
||||
class="flex items-center justify-between rounded-lg w-full transition pt-1"
|
||||
|
@ -4,16 +4,9 @@
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
import Modal from '$lib/components/common/Modal.svelte';
|
||||
import Plus from '$lib/components/icons/Plus.svelte';
|
||||
import Minus from '$lib/components/icons/Minus.svelte';
|
||||
import PencilSolid from '$lib/components/icons/PencilSolid.svelte';
|
||||
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
|
||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||
import Switch from '$lib/components/common/Switch.svelte';
|
||||
import Display from './Display.svelte';
|
||||
import Permissions from './Permissions.svelte';
|
||||
import Users from './Users.svelte';
|
||||
import UsersSolid from '$lib/components/icons/UsersSolid.svelte';
|
||||
import UserPlusSolid from '$lib/components/icons/UserPlusSolid.svelte';
|
||||
import WrenchSolid from '$lib/components/icons/WrenchSolid.svelte';
|
||||
|
||||
@ -31,15 +24,25 @@
|
||||
export let tabs = ['general', 'permissions', 'users'];
|
||||
|
||||
let selectedTab = 'general';
|
||||
let loading = false;
|
||||
|
||||
let name = '';
|
||||
let description = '';
|
||||
|
||||
let permissions = {};
|
||||
let permissions = {
|
||||
workspace: {
|
||||
models: false,
|
||||
knowledge: false,
|
||||
prompts: false,
|
||||
tools: false
|
||||
},
|
||||
chat: {
|
||||
delete: true,
|
||||
edit: true,
|
||||
temporary: true
|
||||
}
|
||||
};
|
||||
let userIds = [];
|
||||
let adminIds = [];
|
||||
|
||||
let loading = false;
|
||||
|
||||
const submitHandler = async () => {
|
||||
loading = true;
|
||||
@ -65,7 +68,19 @@
|
||||
if (group) {
|
||||
name = group.name;
|
||||
description = group.description;
|
||||
permissions = group?.permissions ?? {};
|
||||
permissions = group?.permissions ?? {
|
||||
workspace: {
|
||||
models: false,
|
||||
knowledge: false,
|
||||
prompts: false,
|
||||
tools: false
|
||||
},
|
||||
chat: {
|
||||
delete: true,
|
||||
edit: true,
|
||||
temporary: true
|
||||
}
|
||||
};
|
||||
userIds = group?.user_ids ?? [];
|
||||
}
|
||||
};
|
||||
@ -200,9 +215,9 @@
|
||||
{#if selectedTab == 'general'}
|
||||
<Display bind:name bind:description />
|
||||
{:else if selectedTab == 'permissions'}
|
||||
<Permissions bind:permissions {custom} />
|
||||
<Permissions bind:permissions />
|
||||
{:else if selectedTab == 'users'}
|
||||
<Users bind:userIds bind:adminIds {users} />
|
||||
<Users bind:userIds {users} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,13 @@
|
||||
<script>
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { getContext } from 'svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
import { deleteGroupById, updateGroupById } from '$lib/apis/groups';
|
||||
|
||||
import Pencil from '$lib/components/icons/Pencil.svelte';
|
||||
import User from '$lib/components/icons/User.svelte';
|
||||
|
||||
import UserCircleSolid from '$lib/components/icons/UserCircleSolid.svelte';
|
||||
import GroupModal from './EditGroupModal.svelte';
|
||||
|
||||
@ -11,10 +17,43 @@
|
||||
user_ids: [1, 2, 3]
|
||||
};
|
||||
|
||||
export let setGroups = () => {};
|
||||
|
||||
let showEdit = false;
|
||||
|
||||
const updateHandler = async (_group) => {
|
||||
const res = await updateGroupById(localStorage.token, group.id, _group).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (res) {
|
||||
toast.success($i18n.t('Group updated successfully'));
|
||||
setGroups();
|
||||
}
|
||||
};
|
||||
|
||||
const deleteHandler = async () => {
|
||||
const res = await deleteGroupById(localStorage.token, group.id).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (res) {
|
||||
toast.success($i18n.t('Group deleted successfully'));
|
||||
setGroups();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<GroupModal bind:show={showEdit} edit {group} {users} />
|
||||
<GroupModal
|
||||
bind:show={showEdit}
|
||||
edit
|
||||
{users}
|
||||
{group}
|
||||
onSubmit={updateHandler}
|
||||
onDelete={deleteHandler}
|
||||
/>
|
||||
|
||||
<div class="flex items-center gap-3 justify-between px-1 text-xs w-full transition">
|
||||
<div class="flex items-center gap-1.5 w-full font-medium">
|
||||
|
@ -3,34 +3,25 @@
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
import Switch from '$lib/components/common/Switch.svelte';
|
||||
import { models } from '$lib/stores';
|
||||
import Minus from '$lib/components/icons/Minus.svelte';
|
||||
import Plus from '$lib/components/icons/Plus.svelte';
|
||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||
|
||||
export let permissions = {};
|
||||
export let custom = true;
|
||||
|
||||
let defaultModelId = '';
|
||||
|
||||
let selectedModelId = '';
|
||||
|
||||
let filterEnabled = false;
|
||||
let filterMode = 'include';
|
||||
let filterModelIds = [];
|
||||
|
||||
let workspaceModelsAccess = false;
|
||||
let workspaceKnowledgeAccess = false;
|
||||
let workspacePromptsAccess = false;
|
||||
let workspaceToolsAccess = false;
|
||||
let workspaceFunctionsAccess = false;
|
||||
|
||||
let chatDeletion = true;
|
||||
let chatEdit = true;
|
||||
let chatTemporary = true;
|
||||
export let permissions = {
|
||||
workspace: {
|
||||
models: false,
|
||||
knowledge: false,
|
||||
prompts: false,
|
||||
tools: false
|
||||
},
|
||||
chat: {
|
||||
delete: true,
|
||||
edit: true,
|
||||
temporary: true
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<!-- <div>
|
||||
<div class=" mb-2 text-sm font-medium">{$i18n.t('Model Permissions')}</div>
|
||||
|
||||
<div class="mb-2">
|
||||
@ -130,52 +121,46 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class=" border-gray-50 dark:border-gray-850 my-2" />
|
||||
<hr class=" border-gray-50 dark:border-gray-850 my-2" /> -->
|
||||
|
||||
<div>
|
||||
<div class=" mb-2 text-sm font-medium">{$i18n.t('Workspace Permissions')}</div>
|
||||
|
||||
<div class=" flex w-full justify-between my-2 pr-2">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{#if custom}
|
||||
{$i18n.t('Admins')}:
|
||||
{/if}
|
||||
{$i18n.t('Models Access')}
|
||||
</div>
|
||||
<Switch bind:state={workspaceModelsAccess} />
|
||||
<Switch bind:state={permissions.workspace.models} />
|
||||
</div>
|
||||
|
||||
<div class=" flex w-full justify-between my-2 pr-2">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{#if custom}
|
||||
{$i18n.t('Admins')}:
|
||||
{/if}
|
||||
|
||||
{$i18n.t('Knowledge Access')}
|
||||
</div>
|
||||
<Switch bind:state={workspaceKnowledgeAccess} />
|
||||
<Switch bind:state={permissions.workspace.knowledge} />
|
||||
</div>
|
||||
|
||||
<div class=" flex w-full justify-between my-2 pr-2">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{#if custom}
|
||||
{$i18n.t('Admins')}:
|
||||
{/if}
|
||||
|
||||
{$i18n.t('Prompts Access')}
|
||||
</div>
|
||||
<Switch bind:state={workspacePromptsAccess} />
|
||||
<Switch bind:state={permissions.workspace.prompts} />
|
||||
</div>
|
||||
|
||||
<!-- <div class=" flex w-full justify-between my-2 pr-2">
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Allow Tools Access')}</div>
|
||||
<Switch bind:state={workspaceToolsAccess} />
|
||||
<div class=" ">
|
||||
<Tooltip
|
||||
className=" flex w-full justify-between my-2 pr-2"
|
||||
content={$i18n.t(
|
||||
'Warning: Enabling this will allow users to upload arbitrary code on the server.'
|
||||
)}
|
||||
placement="top-start"
|
||||
>
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{$i18n.t('Tools Access')}
|
||||
</div>
|
||||
<Switch bind:state={permissions.workspace.tools} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<div class=" flex w-full justify-between my-2 pr-2">
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Allow Functions Access')}</div>
|
||||
<Switch bind:state={workspaceFunctionsAccess} />
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<hr class=" border-gray-50 dark:border-gray-850 my-2" />
|
||||
@ -185,35 +170,26 @@
|
||||
|
||||
<div class=" flex w-full justify-between my-2 pr-2">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{#if custom}
|
||||
{$i18n.t('Members')}:
|
||||
{/if}
|
||||
{$i18n.t('Allow Chat Deletion')}
|
||||
{$i18n.t('Allow Chat Delete')}
|
||||
</div>
|
||||
|
||||
<Switch bind:state={chatDeletion} />
|
||||
<Switch bind:state={permissions.chat.delete} />
|
||||
</div>
|
||||
|
||||
<div class=" flex w-full justify-between my-2 pr-2">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{#if custom}
|
||||
{$i18n.t('Members')}:
|
||||
{/if}
|
||||
{$i18n.t('Allow Chat Editing')}
|
||||
{$i18n.t('Allow Chat Edit')}
|
||||
</div>
|
||||
|
||||
<Switch bind:state={chatEdit} />
|
||||
<Switch bind:state={permissions.chat.edit} />
|
||||
</div>
|
||||
|
||||
<div class=" flex w-full justify-between my-2 pr-2">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{#if custom}
|
||||
{$i18n.t('Members')}:
|
||||
{/if}
|
||||
{$i18n.t('Allow Temporary Chat')}
|
||||
</div>
|
||||
|
||||
<Switch bind:state={chatTemporary} />
|
||||
<Switch bind:state={permissions.chat.temporary} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
export let users = [];
|
||||
export let userIds = [];
|
||||
export let adminIds = [];
|
||||
|
||||
let filteredUsers = [];
|
||||
|
||||
@ -30,16 +29,10 @@
|
||||
);
|
||||
})
|
||||
.sort((a, b) => {
|
||||
const aIsAdmin = adminIds.includes(a.id);
|
||||
const bIsAdmin = adminIds.includes(b.id);
|
||||
const aUserIndex = userIds.indexOf(a.id);
|
||||
const bUserIndex = userIds.indexOf(b.id);
|
||||
|
||||
// Admin users should come first
|
||||
if (aIsAdmin && !bIsAdmin) return -1; // Place 'a' first if it's admin
|
||||
if (!aIsAdmin && bIsAdmin) return 1; // Place 'b' first if it's admin
|
||||
|
||||
// Neither are admin, compare based on userIds or fall back to alphabetical order
|
||||
// Compare based on userIds or fall back to alphabetical order
|
||||
if (aUserIndex !== -1 && bUserIndex === -1) return -1; // 'a' has valid userId -> prioritize
|
||||
if (bUserIndex !== -1 && aUserIndex === -1) return 1; // 'b' has valid userId -> prioritize
|
||||
|
||||
@ -114,20 +107,7 @@
|
||||
</Tooltip>
|
||||
|
||||
{#if userIds.includes(user.id)}
|
||||
<button
|
||||
on:click={() => {
|
||||
adminIds = adminIds.includes(user.id)
|
||||
? adminIds.filter((id) => id !== user.id)
|
||||
: [...adminIds, user.id];
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
{#if adminIds.includes(user.id)}
|
||||
<Badge type="info" content="admin" />
|
||||
{:else}
|
||||
<Badge type="success" content="member" />
|
||||
{/if}
|
||||
</button>
|
||||
<Badge type="success" content="member" />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user