refac: access controls

This commit is contained in:
Timothy Jaeryang Baek 2025-01-20 23:20:47 -08:00
parent aa442f694b
commit 45f4bc18f8
8 changed files with 59 additions and 20 deletions

View File

@ -188,5 +188,24 @@ class GroupTable:
except Exception: except Exception:
return False return False
def remove_user_from_all_groups(self, user_id: str) -> bool:
with get_db() as db:
try:
groups = self.get_groups_by_member_id(user_id)
for group in groups:
group.user_ids.remove(user_id)
db.query(Group).filter_by(id=group.id).update(
{
"user_ids": group.user_ids,
"updated_at": int(time.time()),
}
)
db.commit()
return True
except Exception:
return False
Groups = GroupTable() Groups = GroupTable()

View File

@ -2,7 +2,12 @@ import time
from typing import Optional from typing import Optional
from open_webui.internal.db import Base, JSONField, get_db from open_webui.internal.db import Base, JSONField, get_db
from open_webui.models.chats import Chats from open_webui.models.chats import Chats
from open_webui.models.groups import Groups
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
from sqlalchemy import BigInteger, Column, String, Text from sqlalchemy import BigInteger, Column, String, Text
@ -268,9 +273,11 @@ class UsersTable:
def delete_user_by_id(self, id: str) -> bool: def delete_user_by_id(self, id: str) -> bool:
try: try:
# Remove User from Groups
Groups.remove_user_from_all_groups(id)
# Delete User Chats # Delete User Chats
result = Chats.delete_chats_by_user_id(id) result = Chats.delete_chats_by_user_id(id)
if result: if result:
with get_db() as db: with get_db() as db:
# Delete User # Delete User

View File

@ -9,6 +9,7 @@
import Cog6 from '$lib/components/icons/Cog6.svelte'; import Cog6 from '$lib/components/icons/Cog6.svelte';
import Wrench from '$lib/components/icons/Wrench.svelte'; import Wrench from '$lib/components/icons/Wrench.svelte';
import ManageOllamaModal from './ManageOllamaModal.svelte'; import ManageOllamaModal from './ManageOllamaModal.svelte';
import ArrowDownTray from '$lib/components/icons/ArrowDownTray.svelte';
export let onDelete = () => {}; export let onDelete = () => {};
export let onSubmit = () => {}; export let onSubmit = () => {};
@ -70,7 +71,7 @@
}} }}
type="button" type="button"
> >
<Wrench /> <ArrowDownTray />
</button> </button>
</Tooltip> </Tooltip>

View File

@ -620,6 +620,7 @@
onChange={() => { onChange={() => {
changeDebounceHandler(); changeDebounceHandler();
}} }}
accessRoles={['read', 'write']}
/> />
<div class="w-full mb-2.5"> <div class="w-full mb-2.5">
<div class=" flex w-full"> <div class=" flex w-full">

View File

@ -68,7 +68,11 @@
}); });
</script> </script>
<AccessControlModal bind:show={showAccessControlModal} bind:accessControl /> <AccessControlModal
bind:show={showAccessControlModal}
bind:accessControl
accessRoles={['read', 'write']}
/>
<div class="w-full max-h-full flex justify-center"> <div class="w-full max-h-full flex justify-center">
<form <form

View File

@ -179,7 +179,11 @@ class Tools:
}; };
</script> </script>
<AccessControlModal bind:show={showAccessControlModal} bind:accessControl /> <AccessControlModal
bind:show={showAccessControlModal}
bind:accessControl
accessRoles={['read', 'write']}
/>
<div class=" flex flex-col justify-between w-full overflow-y-auto h-full"> <div class=" flex flex-col justify-between w-full overflow-y-auto h-full">
<div class="mx-auto w-full md:px-0 h-full"> <div class="mx-auto w-full md:px-0 h-full">

View File

@ -12,6 +12,7 @@
export let onChange: Function = () => {}; export let onChange: Function = () => {};
export let accessRoles = ['read'];
export let accessControl = null; export let accessControl = null;
let selectedGroupId = ''; let selectedGroupId = '';
@ -192,24 +193,25 @@
class="" class=""
type="button" type="button"
on:click={() => { on:click={() => {
if (accessControl.write.group_ids.includes(group.id)) { if (accessRoles.includes('write')) {
accessControl.write.group_ids = accessControl.write.group_ids.filter( if (accessControl.write.group_ids.includes(group.id)) {
(group_id) => group_id !== group.id accessControl.write.group_ids = accessControl.write.group_ids.filter(
); (group_id) => group_id !== group.id
} else { );
accessControl.write.group_ids = [ } else {
...accessControl.write.group_ids, accessControl.write.group_ids = [
group.id ...accessControl.write.group_ids,
]; group.id
];
}
} }
}} }}
> >
<Badge {#if accessControl.write.group_ids.includes(group.id)}
type={accessControl.write.group_ids.includes(group.id) ? 'info' : 'success'} <Badge type={'success'} content={$i18n.t('Write')} />
content={$i18n.t( {:else}
accessControl.write.group_ids.includes(group.id) ? 'Write' : 'Read' <Badge type={'info'} content={$i18n.t('Read')} />
)} {/if}
/>
</button> </button>
<button <button

View File

@ -7,6 +7,7 @@
export let show = false; export let show = false;
export let accessControl = null; export let accessControl = null;
export let accessRoles = ['read'];
export let onChange = () => {}; export let onChange = () => {};
</script> </script>
@ -37,7 +38,7 @@
</div> </div>
<div class="w-full px-5 pb-4 dark:text-white"> <div class="w-full px-5 pb-4 dark:text-white">
<AccessControl bind:accessControl {onChange} /> <AccessControl bind:accessControl {onChange} {accessRoles} />
</div> </div>
</div> </div>
</Modal> </Modal>