fix: Org admin cannot use system tools.

This commit is contained in:
wangruidong 2025-06-18 15:17:43 +08:00
parent 65f2b92eb3
commit b4e5e107f5
4 changed files with 36 additions and 25 deletions

View File

@ -1,6 +1,5 @@
import asyncio
import os
from http.cookies import SimpleCookie
import aiofiles
from asgiref.sync import sync_to_async
@ -8,6 +7,7 @@ from channels.generic.websocket import AsyncJsonWebsocketConsumer
from common.db.utils import close_old_connections
from common.utils import get_logger
from orgs.mixins.ws import OrgMixin
from orgs.utils import tmp_to_org
from rbac.builtin import BuiltinRole
from .ansible.utils import get_ansible_task_log_path
@ -18,10 +18,8 @@ from .models import CeleryTaskExecution
logger = get_logger(__name__)
class TaskLogWebsocket(AsyncJsonWebsocketConsumer):
class TaskLogWebsocket(AsyncJsonWebsocketConsumer, OrgMixin):
disconnected = False
cookie = None
org = None
user_tasks = (
'ops.tasks.run_ops_job',
'ops.tasks.run_ops_job_execution',
@ -32,19 +30,6 @@ class TaskLogWebsocket(AsyncJsonWebsocketConsumer):
'ansible': get_ansible_task_log_path
}
def get_cookie(self):
try:
headers = self.scope['headers']
headers_dict = {key.decode('utf-8'): value.decode('utf-8') for key, value in headers}
cookie = SimpleCookie(headers_dict.get('cookie', ''))
except Exception as e:
cookie = SimpleCookie()
return cookie
def get_current_org(self):
oid = self.cookie.get('X-JMS-ORG')
return oid.value if oid else None
async def connect(self):
user = self.scope["user"]
if user.is_authenticated:
@ -77,11 +62,6 @@ class TaskLogWebsocket(AsyncJsonWebsocketConsumer):
user_role_ids = set(map(str, roles.values_list('id', flat=True)))
return user_role_ids
@sync_to_async
def has_perms(self, user, perms):
with tmp_to_org(self.org):
return user.has_perms(perms)
async def receive_json(self, content, **kwargs):
task_id = content.get('task')
task = await self.get_task(task_id)

28
apps/orgs/mixins/ws.py Normal file
View File

@ -0,0 +1,28 @@
from http.cookies import SimpleCookie
from asgiref.sync import sync_to_async
from orgs.utils import tmp_to_org
class OrgMixin:
cookie = None
org = None
def get_cookie(self):
try:
headers = self.scope['headers']
headers_dict = {key.decode('utf-8'): value.decode('utf-8') for key, value in headers}
cookie = SimpleCookie(headers_dict.get('cookie', ''))
except Exception as e:
cookie = SimpleCookie()
return cookie
def get_current_org(self):
oid = self.cookie.get('X-JMS-ORG')
return oid.value if oid else None
@sync_to_async
def has_perms(self, user, perms):
with tmp_to_org(self.org):
return user.has_perms(perms)

View File

@ -74,7 +74,7 @@ class SettingsApi(generics.RetrieveUpdateAPIView):
rbac_category_permissions = {
'basic': 'settings.view_setting',
'tool': 'settings.view_setting',
'tool': 'rbac.view_systemtools',
'terminal': 'settings.change_terminal',
'ops': 'settings.change_ops',
'ticket': 'settings.change_ticket',

View File

@ -13,6 +13,7 @@ from django.utils.translation import gettext_lazy as _
from common.db.utils import close_old_connections
from common.utils import get_logger
from orgs.mixins.ws import OrgMixin
from orgs.models import Organization
from orgs.utils import current_org
from settings.serializers import (
@ -38,7 +39,7 @@ CACHE_KEY_LDAP_TEST_CONFIG_TASK_STATUS = 'CACHE_KEY_LDAP_TEST_CONFIG_TASK_STATUS
TASK_STATUS_IS_OVER = 'OVER'
class ToolsWebsocket(AsyncJsonWebsocketConsumer):
class ToolsWebsocket(AsyncJsonWebsocketConsumer, OrgMixin):
is_closed: bool = False
@staticmethod
@ -55,7 +56,9 @@ class ToolsWebsocket(AsyncJsonWebsocketConsumer):
async def connect(self):
user = self.scope["user"]
if user.is_authenticated:
has_perm = await sync_to_async(user.has_perm)('rbac.view_systemtools')
self.cookie = self.get_cookie()
self.org = self.get_current_org()
has_perm = self.has_perms(user, ['rbac.view_systemtools'])
if await self.is_superuser(user) or (settings.TOOL_USER_ENABLED and has_perm):
await self.accept()
else: