mirror of
https://github.com/open-webui/open-webui.git
synced 2026-10-05 02:41:34 +00:00
Merge 9d83914323 into b6dfa3799d
This commit is contained in:
commit
77c6af0756
6 changed files with 77 additions and 0 deletions
|
|
@ -515,6 +515,22 @@ class AccessGrantsTable:
|
|||
grants = result.scalars().all()
|
||||
return [AccessGrantModel.model_validate(g) for g in grants]
|
||||
|
||||
async def get_grants_by_group_id(
|
||||
self,
|
||||
group_id: str,
|
||||
db: Optional[AsyncSession] = None,
|
||||
) -> list[AccessGrantModel]:
|
||||
"""Get all grants given to a specific group."""
|
||||
async with get_async_db_context(db) as db:
|
||||
result = await db.execute(
|
||||
select(AccessGrant).filter_by(
|
||||
principal_type=PRINCIPAL_TYPE_GROUP,
|
||||
principal_id=group_id,
|
||||
)
|
||||
)
|
||||
grants = result.scalars().all()
|
||||
return [AccessGrantModel.model_validate(g) for g in grants]
|
||||
|
||||
async def get_grants_by_resources(
|
||||
self,
|
||||
resource_type: str,
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ from open_webui.models.users import (
|
|||
Users,
|
||||
UserStatus,
|
||||
)
|
||||
from open_webui.socket.main import leave_group_rooms_for_users
|
||||
from open_webui.utils.access_control import get_permissions, has_permission
|
||||
from open_webui.utils.auth import (
|
||||
create_api_key,
|
||||
|
|
@ -695,7 +696,13 @@ async def ldap_auth(
|
|||
try:
|
||||
if ENABLE_LDAP_GROUP_CREATION:
|
||||
await Groups.create_groups_by_group_names(user.id, user_groups, db=db)
|
||||
previous_group_ids = {
|
||||
group.id for group in await Groups.get_groups_by_member_id(user.id, db=db)
|
||||
}
|
||||
await Groups.sync_groups_by_group_names(user.id, user_groups, db=db)
|
||||
current_group_ids = {group.id for group in await Groups.get_groups_by_member_id(user.id, db=db)}
|
||||
for group_id in previous_group_ids - current_group_ids:
|
||||
await leave_group_rooms_for_users(group_id, [user.id])
|
||||
log.info('Successfully synced groups for user %s: %s', user.id, user_groups)
|
||||
except Exception as e:
|
||||
log.error(f'Failed to sync groups for user {user.id}: {e}')
|
||||
|
|
@ -766,7 +773,11 @@ async def signin(
|
|||
group_names = [name.strip() for name in group_names if name.strip()]
|
||||
|
||||
if group_names:
|
||||
previous_group_ids = {group.id for group in await Groups.get_groups_by_member_id(user.id, db=db)}
|
||||
await Groups.sync_groups_by_group_names(user.id, group_names, db=db)
|
||||
current_group_ids = {group.id for group in await Groups.get_groups_by_member_id(user.id, db=db)}
|
||||
for group_id in previous_group_ids - current_group_ids:
|
||||
await leave_group_rooms_for_users(group_id, [user.id])
|
||||
|
||||
if WEBUI_AUTH_TRUSTED_ROLE_HEADER:
|
||||
trusted_role = request.headers.get(WEBUI_AUTH_TRUSTED_ROLE_HEADER, '').lower().strip()
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ from open_webui.models.knowledge import Knowledges
|
|||
from open_webui.models.models import Models
|
||||
from open_webui.models.tools import Tools
|
||||
from open_webui.models.users import UserInfoResponse, Users
|
||||
from open_webui.socket.main import leave_group_rooms_for_users
|
||||
from open_webui.utils.auth import get_admin_user, get_verified_user
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
|
|
@ -270,6 +271,7 @@ async def remove_users_from_group(
|
|||
try:
|
||||
group = await Groups.remove_users_from_group(id, form_data.user_ids, db=db)
|
||||
if group:
|
||||
await leave_group_rooms_for_users(id, form_data.user_ids)
|
||||
await publish_event(
|
||||
request,
|
||||
EVENTS.GROUP_MEMBER_REMOVED,
|
||||
|
|
@ -306,8 +308,10 @@ async def delete_group_by_id(
|
|||
request: Request, id: str, user=Depends(get_admin_user), db: AsyncSession = Depends(get_async_session)
|
||||
):
|
||||
try:
|
||||
user_ids = await Groups.get_group_user_ids_by_id(id, db=db)
|
||||
result = await Groups.delete_group_by_id(id, db=db)
|
||||
if result:
|
||||
await leave_group_rooms_for_users(id, user_ids)
|
||||
await publish_event(
|
||||
request,
|
||||
EVENTS.GROUP_DELETED,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ from open_webui.env import SCIM_AUTH_PROVIDER
|
|||
from open_webui.internal.db import get_async_session
|
||||
from open_webui.models.groups import GroupModel, Groups
|
||||
from open_webui.models.users import UserModel, Users
|
||||
from open_webui.socket.main import leave_group_rooms_for_users
|
||||
from open_webui.utils.auth import (
|
||||
decode_token,
|
||||
get_admin_user,
|
||||
|
|
@ -1064,6 +1065,7 @@ async def update_group(
|
|||
data={'member_ids': added_member_ids, 'count': len(added_member_ids)},
|
||||
)
|
||||
if removed_member_ids:
|
||||
await leave_group_rooms_for_users(group_id, removed_member_ids)
|
||||
await publish_event(
|
||||
request,
|
||||
EVENTS.GROUP_MEMBER_REMOVED,
|
||||
|
|
@ -1156,6 +1158,7 @@ async def patch_group(
|
|||
data={'member_ids': sorted(set(added_member_ids)), 'count': len(set(added_member_ids))},
|
||||
)
|
||||
if removed_member_ids:
|
||||
await leave_group_rooms_for_users(group_id, removed_member_ids)
|
||||
await publish_event(
|
||||
request,
|
||||
EVENTS.GROUP_MEMBER_REMOVED,
|
||||
|
|
@ -1182,12 +1185,14 @@ async def delete_group(
|
|||
detail=f'Group {group_id} not found',
|
||||
)
|
||||
|
||||
member_ids = await Groups.get_group_user_ids_by_id(group_id, db=db)
|
||||
success = await Groups.delete_group_by_id(group_id, db=db)
|
||||
if not success:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail='Failed to delete group',
|
||||
)
|
||||
await leave_group_rooms_for_users(group_id, member_ids)
|
||||
|
||||
await publish_event(
|
||||
request,
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ from open_webui.models.channels import Channels
|
|||
from open_webui.models.chats import Chats
|
||||
from open_webui.models.config import Config
|
||||
from open_webui.models.folders import Folders
|
||||
from open_webui.models.groups import Groups
|
||||
from open_webui.models.notes import Notes, NoteUpdateForm
|
||||
from open_webui.models.users import UserNameResponse, Users
|
||||
from open_webui.socket.redis_room_channels import AsyncRedisRoomChannelManager
|
||||
|
|
@ -414,6 +415,44 @@ async def leave_room_for_users(room: str, user_ids: list[str]):
|
|||
log.debug('Failed to make session %s leave room %s: %s', sid, room, e)
|
||||
|
||||
|
||||
async def leave_group_rooms_for_users(group_id: str, user_ids: list[str]):
|
||||
"""Make users leave the note and channel rooms they could only read through a group."""
|
||||
users = await Users.get_users_by_user_ids(user_ids)
|
||||
non_admin_user_ids = [user.id for user in users if user.role != 'admin']
|
||||
group_ids_by_user_id = {
|
||||
user_id: {group.id for group in groups}
|
||||
for user_id, groups in (await Groups.get_groups_by_member_ids(non_admin_user_ids)).items()
|
||||
}
|
||||
|
||||
for grant in await AccessGrants.get_grants_by_group_id(group_id):
|
||||
if grant.permission != 'read':
|
||||
continue
|
||||
if grant.resource_type == 'note':
|
||||
resource = await Notes.get_note_by_id(grant.resource_id)
|
||||
rooms = [f'note:{grant.resource_id}', f'doc_note:{grant.resource_id}']
|
||||
elif grant.resource_type == 'channel':
|
||||
resource = await Channels.get_channel_by_id(grant.resource_id)
|
||||
# Group and DM channels use membership instead of access grants.
|
||||
if resource and resource.type in ['group', 'dm']:
|
||||
continue
|
||||
rooms = [f'channel:{grant.resource_id}']
|
||||
else:
|
||||
continue
|
||||
if not resource:
|
||||
continue
|
||||
|
||||
revoked_user_ids = [
|
||||
user_id
|
||||
for user_id in non_admin_user_ids
|
||||
if user_id != resource.user_id
|
||||
and not await AccessGrants.has_access(
|
||||
user_id, grant.resource_type, grant.resource_id, user_group_ids=group_ids_by_user_id[user_id]
|
||||
)
|
||||
]
|
||||
for room in rooms:
|
||||
await leave_room_for_users(room, revoked_user_ids)
|
||||
|
||||
|
||||
async def disconnect_user_sessions(user_id: str):
|
||||
"""Disconnect all Socket.IO sessions belonging to a user.
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ from open_webui.models.groups import GroupForm, GroupModel, Groups, GroupUpdateF
|
|||
from open_webui.models.oauth_sessions import OAuthSessions
|
||||
from open_webui.models.users import Users
|
||||
from open_webui.retrieval.web.utils import get_ssrf_safe_session, validate_url
|
||||
from open_webui.socket.main import leave_group_rooms_for_users
|
||||
from open_webui.utils.auth import (
|
||||
create_token,
|
||||
get_password_hash,
|
||||
|
|
@ -1746,6 +1747,7 @@ class OAuthManager:
|
|||
# Remove group from user
|
||||
log.debug('Removing user from group %s as it is no longer in their oauth groups', group_model.name)
|
||||
if await Groups.remove_users_from_group(group_model.id, [user.id], db=db):
|
||||
await leave_group_rooms_for_users(group_model.id, [user.id])
|
||||
await publish_event(
|
||||
request,
|
||||
EVENTS.GROUP_MEMBER_REMOVED,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue