mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-08-31 15:11:27 +00:00
fix: fix rbac to dev (#7636)
* feat: 添加 RBAC 应用模块 * feat: 添加 RBAC Model、API * feat: 添加 RBAC Model、API 2 * feat: 添加 RBAC Model、API 3 * feat: 添加 RBAC Model、API 4 * feat: RBAC * feat: RBAC * feat: RBAC * feat: RBAC * feat: RBAC * feat: RBAC 整理权限位 * feat: RBAC 整理权限位2 * feat: RBAC 整理权限位2 * feat: RBAC 整理权限位 * feat: RBAC 添加默认角色 * feat: RBAC 添加迁移文件;迁移用户角色->用户角色绑定 * feat: RBAC 添加迁移文件;迁移用户角色->用户角色绑定 * feat: RBAC 修改用户模块API * feat: RBAC 添加组织模块迁移文件 & 修改组织模块API * feat: RBAC 添加组织模块迁移文件 & 修改组织模块API * feat: RBAC 修改用户角色属性的使用 * feat: RBAC No.1 * xxx * perf: 暂存 * perf: ... * perf(rbac): 添加 perms 到 profile serializer 中 * stash * perf: 使用init * perf: 修改migrations * perf: rbac * stash * stash * pref: 修改rbac * stash it * stash: 先去修复其他bug * perf: 修改 role 添加 users * pref: 修改 RBAC Model * feat: 添加权限的 tree api * stash: 暂存一下 * stash: 暂存一下 * perf: 修改 model verbose name * feat: 添加model各种 verbose name * perf: 生成 migrations * perf: 优化权限位 * perf: 添加迁移脚本 * feat: 添加组织角色迁移 * perf: 添加迁移脚本 * stash * perf: 添加migrateion * perf: 暂存一下 * perf: 修改rbac * perf: stash it * fix: 迁移冲突 * fix: 迁移冲突 * perf: 暂存一下 * perf: 修改 rbac 逻辑 * stash: 暂存一下 * perf: 修改内置角色 * perf: 解决 root 组织的问题 * perf: stash it * perf: 优化 rbac * perf: 优化 rolebinding 处理 * perf: 完成用户离开组织的问题 * perf: 暂存一下 * perf: 修改翻译 * perf: 去掉了 IsSuperUser * perf: IsAppUser 去掉完成 * perf: 修改 connection token 的权限 * perf: 去掉导入的问题 * perf: perms define 格式,修改 app 用户 的全新啊 * perf: 修改 permission * perf: 去掉一些 org admin * perf: 去掉部分 org admin * perf: 再去掉点 org admin role * perf: 再去掉部分 org admin * perf: user 角色搜索 * perf: 去掉很多 js * perf: 添加权限位 * perf: 修改权限 * perf: 去掉一个 todo * merge: with dev * fix: 修复冲突 Co-authored-by: Bai <bugatti_it@163.com> Co-authored-by: Michael Bai <baijiangjie@gmail.com> Co-authored-by: ibuler <ibuler@qq.com>
This commit is contained in:
@@ -9,10 +9,9 @@ from rest_framework.fields import DateTimeField
|
||||
from rest_framework.response import Response
|
||||
from django.template import loader
|
||||
|
||||
from terminal.models import CommandStorage, Session
|
||||
from terminal.models import CommandStorage, Session, Command
|
||||
from terminal.filters import CommandFilter
|
||||
from orgs.utils import current_org
|
||||
from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor, IsAppUser
|
||||
from common.drf.api import JMSBulkModelViewSet
|
||||
from common.utils import get_logger
|
||||
from terminal.serializers import InsecureCommandAlertSerializer
|
||||
@@ -29,7 +28,6 @@ __all__ = ['CommandViewSet', 'CommandExportApi', 'InsecureCommandAlertAPI']
|
||||
|
||||
class CommandQueryMixin:
|
||||
command_store = get_command_storage()
|
||||
permission_classes = [IsOrgAdminOrAppUser | IsOrgAuditor]
|
||||
filterset_fields = [
|
||||
"asset", "system_user", "user", "session", "risk_level",
|
||||
"input"
|
||||
@@ -105,9 +103,9 @@ class CommandViewSet(JMSBulkModelViewSet):
|
||||
|
||||
"""
|
||||
command_store = get_command_storage()
|
||||
permission_classes = [IsOrgAdminOrAppUser | IsOrgAuditor]
|
||||
serializer_class = SessionCommandSerializer
|
||||
filterset_class = CommandFilter
|
||||
model = Command
|
||||
ordering_fields = ('timestamp', )
|
||||
|
||||
def merge_all_storage_list(self, request, *args, **kwargs):
|
||||
@@ -191,6 +189,9 @@ class CommandViewSet(JMSBulkModelViewSet):
|
||||
|
||||
class CommandExportApi(CommandQueryMixin, generics.ListAPIView):
|
||||
serializer_class = SessionCommandSerializer
|
||||
rbac_perms = {
|
||||
'list': 'terminal.view_command'
|
||||
}
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
@@ -210,8 +211,10 @@ class CommandExportApi(CommandQueryMixin, generics.ListAPIView):
|
||||
|
||||
|
||||
class InsecureCommandAlertAPI(generics.CreateAPIView):
|
||||
permission_classes = [IsAppUser]
|
||||
serializer_class = InsecureCommandAlertSerializer
|
||||
rbac_perms = {
|
||||
'POST': 'terminal.add_command'
|
||||
}
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
serializer = InsecureCommandAlertSerializer(data=request.data, many=True)
|
||||
|
@@ -13,16 +13,15 @@ from rest_framework.response import Response
|
||||
from rest_framework.decorators import action
|
||||
|
||||
from common.utils import data_to_json
|
||||
from .. import utils
|
||||
from common.const.http import GET
|
||||
from common.utils import get_logger, get_object_or_none
|
||||
from common.mixins.api import AsyncApiMixin
|
||||
from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor, IsAppUser
|
||||
from common.drf.filters import DatetimeRangeFilter
|
||||
from common.drf.renders import PassthroughRenderer
|
||||
from orgs.mixins.api import OrgBulkModelViewSet
|
||||
from orgs.utils import tmp_to_root_org, tmp_to_org
|
||||
from users.models import User
|
||||
from .. import utils
|
||||
from ..utils import find_session_replay_local, download_session_replay
|
||||
from ..models import Session
|
||||
from .. import serializers
|
||||
@@ -41,15 +40,18 @@ class SessionViewSet(OrgBulkModelViewSet):
|
||||
'default': serializers.SessionSerializer,
|
||||
'display': serializers.SessionDisplaySerializer,
|
||||
}
|
||||
permission_classes = (IsOrgAdminOrAppUser,)
|
||||
search_fields = [
|
||||
"user", "asset", "system_user", "remote_addr", "protocol", "is_finished", 'login_from',
|
||||
"user", "asset", "system_user", "remote_addr",
|
||||
"protocol", "is_finished", 'login_from',
|
||||
]
|
||||
filterset_fields = search_fields + ['terminal']
|
||||
date_range_filter_fields = [
|
||||
('date_start', ('date_from', 'date_to'))
|
||||
]
|
||||
extra_filter_backends = [DatetimeRangeFilter]
|
||||
rbac_perms = {
|
||||
'download': ['terminal.download_sessionreplay']
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def prepare_offline_file(session, local_path):
|
||||
@@ -103,17 +105,15 @@ class SessionViewSet(OrgBulkModelViewSet):
|
||||
serializer.validated_data["terminal"] = self.request.user.terminal
|
||||
return super().perform_create(serializer)
|
||||
|
||||
def get_permissions(self):
|
||||
if self.request.method.lower() in ['get', 'options']:
|
||||
self.permission_classes = (IsOrgAdminOrAppUser | IsOrgAuditor,)
|
||||
return super().get_permissions()
|
||||
|
||||
|
||||
class SessionReplayViewSet(AsyncApiMixin, viewsets.ViewSet):
|
||||
serializer_class = serializers.ReplaySerializer
|
||||
permission_classes = (IsOrgAdminOrAppUser | IsOrgAuditor,)
|
||||
session = None
|
||||
download_cache_key = "SESSION_REPLAY_DOWNLOAD_{}"
|
||||
session = None
|
||||
rbac_perms = {
|
||||
'create': 'terminal.upload_session',
|
||||
'retrieve': 'terminal.download_session',
|
||||
}
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
session_id = kwargs.get('pk')
|
||||
@@ -175,8 +175,13 @@ class SessionReplayViewSet(AsyncApiMixin, viewsets.ViewSet):
|
||||
|
||||
|
||||
class SessionJoinValidateAPI(views.APIView):
|
||||
permission_classes = (IsAppUser,)
|
||||
"""
|
||||
监控用
|
||||
"""
|
||||
serializer_class = serializers.SessionJoinValidateSerializer
|
||||
rbac_perms = {
|
||||
'POST': 'terminal.validate_sessionactionperm'
|
||||
}
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
@@ -199,11 +204,12 @@ class SessionJoinValidateAPI(views.APIView):
|
||||
if not user:
|
||||
msg = _('User does not exist: {}'.format(user_id))
|
||||
return Response({'ok': False, 'msg': msg}, status=401)
|
||||
|
||||
with tmp_to_org(session.org):
|
||||
if is_session_approver(session_id, user_id):
|
||||
return Response({'ok': True, 'msg': ''}, status=200)
|
||||
|
||||
if not user.admin_or_audit_orgs:
|
||||
if not user.has_perm('terminal.monitor_session'):
|
||||
msg = _('User does not have permission')
|
||||
return Response({'ok': False, 'msg': msg}, status=401)
|
||||
|
||||
|
@@ -3,8 +3,9 @@ from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from common.permissions import IsAppUser, IsSuperUser
|
||||
|
||||
from common.const.http import PATCH
|
||||
from common.permissions import IsValidUser
|
||||
from orgs.mixins.api import OrgModelViewSet
|
||||
from .. import serializers, models
|
||||
|
||||
@@ -13,21 +14,22 @@ __all__ = ['SessionSharingViewSet', 'SessionJoinRecordsViewSet']
|
||||
|
||||
class SessionSharingViewSet(OrgModelViewSet):
|
||||
serializer_class = serializers.SessionSharingSerializer
|
||||
permission_classes = (IsAppUser | IsSuperUser, )
|
||||
search_fields = ('session', 'creator', 'is_active', 'expired_time')
|
||||
filterset_fields = search_fields
|
||||
model = models.SessionSharing
|
||||
rbac_perms = {
|
||||
'create': 'terminal.add_supersessionsharing',
|
||||
}
|
||||
|
||||
def get_permissions(self):
|
||||
if self.request.method.lower() in ['post']:
|
||||
self.permission_classes = (IsAppUser,)
|
||||
return super().get_permissions()
|
||||
def get_queryset(self):
|
||||
queryset = models.SessionSharing.objects.filter(creator=self.request.user)
|
||||
return queryset
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not settings.SECURITY_SESSION_SHARE:
|
||||
detail = _('Secure session sharing settings is disabled')
|
||||
raise MethodNotAllowed(self.action, detail=detail)
|
||||
return super().create(request, *args, **kwargs)
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
raise MethodNotAllowed(self.action)
|
||||
@@ -35,7 +37,6 @@ class SessionSharingViewSet(OrgModelViewSet):
|
||||
|
||||
class SessionJoinRecordsViewSet(OrgModelViewSet):
|
||||
serializer_class = serializers.SessionJoinRecordSerializer
|
||||
permission_classes = (IsAppUser | IsSuperUser, )
|
||||
search_fields = (
|
||||
'sharing', 'session', 'joiner', 'date_joined', 'date_left',
|
||||
'login_from', 'is_success', 'is_finished'
|
||||
@@ -43,11 +44,6 @@ class SessionJoinRecordsViewSet(OrgModelViewSet):
|
||||
filterset_fields = search_fields
|
||||
model = models.SessionJoinRecord
|
||||
|
||||
def get_permissions(self):
|
||||
if self.request.method.lower() in ['post']:
|
||||
self.permission_classes = (IsAppUser,)
|
||||
return super().get_permissions()
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
try:
|
||||
response = super().create(request, *args, **kwargs)
|
||||
|
@@ -4,10 +4,9 @@
|
||||
import logging
|
||||
from django.shortcuts import get_object_or_404
|
||||
from rest_framework import viewsets, generics
|
||||
from rest_framework.views import Response
|
||||
from rest_framework.views import Response
|
||||
from rest_framework import status
|
||||
|
||||
from common.permissions import IsAppUser, IsOrgAdminOrAppUser, IsSuperUser
|
||||
from ..models import Terminal, Status, Session
|
||||
from .. import serializers
|
||||
from ..utils import TypedComponentsStatusMetricsUtil
|
||||
@@ -15,16 +14,12 @@ from ..utils import TypedComponentsStatusMetricsUtil
|
||||
logger = logging.getLogger(__file__)
|
||||
|
||||
|
||||
__all__ = [
|
||||
'StatusViewSet',
|
||||
'ComponentsMetricsAPIView',
|
||||
]
|
||||
__all__ = ['StatusViewSet', 'ComponentsMetricsAPIView']
|
||||
|
||||
|
||||
class StatusViewSet(viewsets.ModelViewSet):
|
||||
queryset = Status.objects.all()
|
||||
serializer_class = serializers.StatusSerializer
|
||||
permission_classes = (IsOrgAdminOrAppUser,)
|
||||
session_serializer_class = serializers.SessionSerializer
|
||||
task_serializer_class = serializers.TaskSerializer
|
||||
|
||||
@@ -53,15 +48,12 @@ class StatusViewSet(viewsets.ModelViewSet):
|
||||
serializer.validated_data["terminal"] = self.request.user.terminal
|
||||
return super().perform_create(serializer)
|
||||
|
||||
def get_permissions(self):
|
||||
if self.action == "create":
|
||||
self.permission_classes = (IsAppUser,)
|
||||
return super().get_permissions()
|
||||
|
||||
|
||||
class ComponentsMetricsAPIView(generics.GenericAPIView):
|
||||
""" 返回汇总组件指标数据 """
|
||||
permission_classes = (IsSuperUser,)
|
||||
rbac_perms = {
|
||||
'GET': 'terminal.view_terminal'
|
||||
}
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
util = TypedComponentsStatusMetricsUtil()
|
||||
|
@@ -10,7 +10,6 @@ from django_filters import utils
|
||||
|
||||
from terminal import const
|
||||
from common.const.http import GET
|
||||
from common.permissions import IsSuperUser, IsOrgAuditor
|
||||
from terminal.filters import CommandStorageFilter, CommandFilter, CommandFilterForStorageTree
|
||||
from ..models import CommandStorage, ReplayStorage
|
||||
from ..serializers import CommandStorageSerializer, ReplayStorageSerializer
|
||||
@@ -39,10 +38,12 @@ class CommandStorageViewSet(BaseStorageViewSetMixin, viewsets.ModelViewSet):
|
||||
search_fields = ('name', 'type')
|
||||
queryset = CommandStorage.objects.all()
|
||||
serializer_class = CommandStorageSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
filterset_class = CommandStorageFilter
|
||||
rbac_perms = {
|
||||
'tree': 'terminal.view_commandstorage'
|
||||
}
|
||||
|
||||
@action(methods=[GET], detail=False, permission_classes=(IsOrgAuditor, ), filterset_class=CommandFilterForStorageTree)
|
||||
@action(methods=[GET], detail=False, filterset_class=CommandFilterForStorageTree)
|
||||
def tree(self, request: Request):
|
||||
storage_qs = self.get_queryset().exclude(name='null')
|
||||
storages_with_count = []
|
||||
@@ -107,12 +108,9 @@ class ReplayStorageViewSet(BaseStorageViewSetMixin, viewsets.ModelViewSet):
|
||||
search_fields = filterset_fields
|
||||
queryset = ReplayStorage.objects.all()
|
||||
serializer_class = ReplayStorageSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class BaseStorageTestConnectiveMixin:
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
def retrieve(self, request, *args, **kwargs):
|
||||
instance = self.get_object()
|
||||
try:
|
||||
|
@@ -7,7 +7,6 @@ from rest_framework import status
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
|
||||
from common.utils import get_object_or_none
|
||||
from common.permissions import IsOrgAdminOrAppUser
|
||||
from ..models import Session, Task
|
||||
from .. import serializers
|
||||
from terminal.utils import is_session_approver
|
||||
@@ -22,7 +21,6 @@ class TaskViewSet(BulkModelViewSet):
|
||||
queryset = Task.objects.all()
|
||||
serializer_class = serializers.TaskSerializer
|
||||
filterset_fields = ('is_finished',)
|
||||
permission_classes = (IsOrgAdminOrAppUser,)
|
||||
|
||||
|
||||
def kill_sessions(session_ids, user):
|
||||
@@ -42,13 +40,10 @@ def kill_sessions(session_ids, user):
|
||||
|
||||
|
||||
class KillSessionAPI(APIView):
|
||||
permission_classes = (IsOrgAdminOrAppUser,)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
session_ids = request.data
|
||||
user = request.user
|
||||
validated_session = kill_sessions(session_ids, user)
|
||||
return Response({"ok": validated_session})
|
||||
model = Task
|
||||
rbac_perms = {
|
||||
'POST': 'terminal.terminate_session'
|
||||
}
|
||||
|
||||
|
||||
class KillSessionForTicketAPI(APIView):
|
||||
|
@@ -8,13 +8,12 @@ from rest_framework import generics
|
||||
from rest_framework.views import APIView, Response
|
||||
from rest_framework import status
|
||||
from django.conf import settings
|
||||
from django_filters import rest_framework as filters
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from common.exceptions import JMSException
|
||||
from common.drf.api import JMSBulkModelViewSet
|
||||
from common.utils import get_object_or_none
|
||||
from common.permissions import IsAppUser, IsSuperUser, WithBootstrapToken
|
||||
from common.permissions import WithBootstrapToken
|
||||
from ..models import Terminal
|
||||
from .. import serializers
|
||||
from .. import exceptions
|
||||
@@ -29,7 +28,6 @@ logger = logging.getLogger(__file__)
|
||||
class TerminalViewSet(JMSBulkModelViewSet):
|
||||
queryset = Terminal.objects.filter(is_deleted=False)
|
||||
serializer_class = serializers.TerminalSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
filterset_fields = ['name', 'remote_addr', 'type']
|
||||
custom_filter_fields = ['status']
|
||||
|
||||
@@ -86,7 +84,9 @@ class TerminalViewSet(JMSBulkModelViewSet):
|
||||
|
||||
|
||||
class TerminalConfig(APIView):
|
||||
permission_classes = (IsAppUser,)
|
||||
rbac_perms = {
|
||||
'GET': 'view_terminalconfig'
|
||||
}
|
||||
|
||||
def get(self, request):
|
||||
config = request.user.terminal.config
|
||||
|
Reference in New Issue
Block a user