diff --git a/apps/assets/api/admin_user.py b/apps/assets/api/admin_user.py index 968cd6594..7048ce461 100644 --- a/apps/assets/api/admin_user.py +++ b/apps/assets/api/admin_user.py @@ -20,7 +20,7 @@ from rest_framework_bulk import BulkModelViewSet from common.mixins import IDInFilterMixin from common.utils import get_logger -from ..hands import IsSuperUser +from ..hands import IsOrgAdmin from ..models import AdminUser, Asset from .. import serializers from ..tasks import test_admin_user_connectability_manual @@ -39,19 +39,19 @@ class AdminUserViewSet(IDInFilterMixin, BulkModelViewSet): """ queryset = AdminUser.objects.all() serializer_class = serializers.AdminUserSerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) class AdminUserAuthApi(generics.UpdateAPIView): queryset = AdminUser.objects.all() serializer_class = serializers.AdminUserAuthSerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) class ReplaceNodesAdminUserApi(generics.UpdateAPIView): queryset = AdminUser.objects.all() serializer_class = serializers.ReplaceNodeAdminUserSerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) def update(self, request, *args, **kwargs): admin_user = self.get_object() @@ -75,7 +75,7 @@ class AdminUserTestConnectiveApi(generics.RetrieveAPIView): Test asset admin user connectivity """ queryset = AdminUser.objects.all() - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) def retrieve(self, request, *args, **kwargs): admin_user = self.get_object() diff --git a/apps/assets/api/asset.py b/apps/assets/api/asset.py index 8c1f3d726..f32a0cb61 100644 --- a/apps/assets/api/asset.py +++ b/apps/assets/api/asset.py @@ -13,7 +13,7 @@ from django.db.models import Q from common.mixins import IDInFilterMixin from common.utils import get_logger -from ..hands import IsSuperUser, IsValidUser, IsSuperUserOrAppUser +from common.permissions import IsOrgAdmin, IsAppUser, IsOrgAdminOrAppUser from ..models import Asset, SystemUser, AdminUser, Node from .. import serializers from ..tasks import update_asset_hardware_info_manual, \ @@ -39,7 +39,7 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet): queryset = Asset.objects.all() serializer_class = serializers.AssetSerializer pagination_class = LimitOffsetPagination - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) def get_queryset(self): queryset = super().get_queryset()\ @@ -79,7 +79,7 @@ class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView): """ queryset = Asset.objects.all() serializer_class = serializers.AssetSerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) class AssetRefreshHardwareApi(generics.RetrieveAPIView): @@ -88,7 +88,7 @@ class AssetRefreshHardwareApi(generics.RetrieveAPIView): """ queryset = Asset.objects.all() serializer_class = serializers.AssetSerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) def retrieve(self, request, *args, **kwargs): asset_id = kwargs.get('pk') @@ -102,7 +102,7 @@ class AssetAdminUserTestApi(generics.RetrieveAPIView): Test asset admin user connectivity """ queryset = Asset.objects.all() - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) def retrieve(self, request, *args, **kwargs): asset_id = kwargs.get('pk') @@ -113,7 +113,7 @@ class AssetAdminUserTestApi(generics.RetrieveAPIView): class AssetGatewayApi(generics.RetrieveAPIView): queryset = Asset.objects.all() - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) def retrieve(self, request, *args, **kwargs): asset_id = kwargs.get('pk') diff --git a/apps/assets/api/domain.py b/apps/assets/api/domain.py index 5114b5561..b6cd07c79 100644 --- a/apps/assets/api/domain.py +++ b/apps/assets/api/domain.py @@ -2,12 +2,12 @@ from rest_framework_bulk import BulkModelViewSet from rest_framework.views import APIView, Response -from rest_framework.generics import RetrieveAPIView +from rest_condition import Or from django.views.generic.detail import SingleObjectMixin from common.utils import get_logger -from ..hands import IsSuperUser, IsSuperUserOrAppUser +from common.permissions import IsOrgAdmin, IsAppUser from ..models import Domain, Gateway from ..utils import test_gateway_connectability from .. import serializers @@ -19,7 +19,7 @@ __all__ = ['DomainViewSet', 'GatewayViewSet', "GatewayTestConnectionApi"] class DomainViewSet(BulkModelViewSet): queryset = Domain.objects.all() - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = serializers.DomainSerializer def get_serializer_class(self): @@ -29,7 +29,7 @@ class DomainViewSet(BulkModelViewSet): def get_permissions(self): if self.request.query_params.get('gateway'): - self.permission_classes = (IsSuperUserOrAppUser,) + self.permission_classes = (IsOrgAdminOrAppUser,) return super().get_permissions() @@ -37,12 +37,12 @@ class GatewayViewSet(BulkModelViewSet): filter_fields = ("domain",) search_fields = filter_fields queryset = Gateway.objects.all() - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = serializers.GatewaySerializer class GatewayTestConnectionApi(SingleObjectMixin, APIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) model = Gateway object = None diff --git a/apps/assets/api/label.py b/apps/assets/api/label.py index 858834d0a..3466c3ec3 100644 --- a/apps/assets/api/label.py +++ b/apps/assets/api/label.py @@ -17,7 +17,7 @@ from rest_framework_bulk import BulkModelViewSet from django.db.models import Count from common.utils import get_logger -from ..hands import IsSuperUser +from ..hands import IsOrgAdmin from ..models import Label from .. import serializers @@ -28,7 +28,7 @@ __all__ = ['LabelViewSet'] class LabelViewSet(BulkModelViewSet): queryset = Label.objects.annotate(asset_count=Count("assets")) - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = serializers.LabelSerializer def list(self, request, *args, **kwargs): diff --git a/apps/assets/api/node.py b/apps/assets/api/node.py index 30887ff22..ff04ee492 100644 --- a/apps/assets/api/node.py +++ b/apps/assets/api/node.py @@ -22,7 +22,7 @@ from django.utils.translation import ugettext_lazy as _ from django.shortcuts import get_object_or_404 from common.utils import get_logger, get_object_or_none -from ..hands import IsSuperUser +from ..hands import IsOrgAdmin from ..models import Node from ..tasks import update_assets_hardware_info_util, test_asset_connectability_util from .. import serializers @@ -39,7 +39,7 @@ __all__ = [ class NodeViewSet(viewsets.ModelViewSet): queryset = Node.objects.all() - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = serializers.NodeSerializer def get_queryset(self): @@ -56,7 +56,7 @@ class NodeViewSet(viewsets.ModelViewSet): # class NodeWithAssetsApi(generics.ListAPIView): -# permission_classes = (IsSuperUser,) +# permission_classes = (IsOrgAdmin,) # serializers = serializers.NodeSerializer # # def get_node(self): @@ -85,7 +85,7 @@ class NodeViewSet(viewsets.ModelViewSet): class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView): queryset = Node.objects.all() - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = serializers.NodeSerializer instance = None @@ -157,7 +157,7 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView): class NodeAssetsApi(generics.ListAPIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = serializers.AssetSerializer def get_queryset(self): @@ -172,7 +172,7 @@ class NodeAssetsApi(generics.ListAPIView): class NodeAddChildrenApi(generics.UpdateAPIView): queryset = Node.objects.all() - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = serializers.NodeAddChildrenSerializer instance = None @@ -190,7 +190,7 @@ class NodeAddChildrenApi(generics.UpdateAPIView): class NodeAddAssetsApi(generics.UpdateAPIView): serializer_class = serializers.NodeAssetsSerializer queryset = Node.objects.all() - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) instance = None def perform_update(self, serializer): @@ -202,7 +202,7 @@ class NodeAddAssetsApi(generics.UpdateAPIView): class NodeRemoveAssetsApi(generics.UpdateAPIView): serializer_class = serializers.NodeAssetsSerializer queryset = Node.objects.all() - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) instance = None def perform_update(self, serializer): @@ -218,7 +218,7 @@ class NodeRemoveAssetsApi(generics.UpdateAPIView): class NodeReplaceAssetsApi(generics.UpdateAPIView): serializer_class = serializers.NodeAssetsSerializer queryset = Node.objects.all() - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) instance = None def perform_update(self, serializer): @@ -229,7 +229,7 @@ class NodeReplaceAssetsApi(generics.UpdateAPIView): class RefreshNodeHardwareInfoApi(APIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) model = Node def get(self, request, *args, **kwargs): @@ -242,7 +242,7 @@ class RefreshNodeHardwareInfoApi(APIView): class TestNodeConnectiveApi(APIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) model = Node def get(self, request, *args, **kwargs): diff --git a/apps/assets/api/system_user.py b/apps/assets/api/system_user.py index 66d62232d..f44c60f5b 100644 --- a/apps/assets/api/system_user.py +++ b/apps/assets/api/system_user.py @@ -16,8 +16,9 @@ from rest_framework import generics from rest_framework.response import Response from rest_framework_bulk import BulkModelViewSet + from common.utils import get_logger -from ..hands import IsSuperUser, IsSuperUserOrAppUser +from common.permissions import IsOrgAdmin, IsOrgAdminOrAppUser from ..models import SystemUser from .. import serializers from ..tasks import push_system_user_to_assets_manual, \ @@ -37,7 +38,7 @@ class SystemUserViewSet(BulkModelViewSet): """ queryset = SystemUser.objects.all() serializer_class = serializers.SystemUserSerializer - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) class SystemUserAuthInfoApi(generics.RetrieveUpdateDestroyAPIView): @@ -45,7 +46,7 @@ class SystemUserAuthInfoApi(generics.RetrieveUpdateDestroyAPIView): Get system user auth info """ queryset = SystemUser.objects.all() - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) serializer_class = serializers.SystemUserAuthSerializer def destroy(self, request, *args, **kwargs): @@ -59,7 +60,7 @@ class SystemUserPushApi(generics.RetrieveAPIView): Push system user to cluster assets api """ queryset = SystemUser.objects.all() - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) def retrieve(self, request, *args, **kwargs): system_user = self.get_object() @@ -75,7 +76,7 @@ class SystemUserTestConnectiveApi(generics.RetrieveAPIView): Push system user to cluster assets api """ queryset = SystemUser.objects.all() - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) def retrieve(self, request, *args, **kwargs): system_user = self.get_object() diff --git a/apps/assets/hands.py b/apps/assets/hands.py index c788ee632..ffe1e35c5 100644 --- a/apps/assets/hands.py +++ b/apps/assets/hands.py @@ -12,5 +12,5 @@ from common.permissions import AdminUserRequiredMixin -from common.permissions import IsAppUser, IsSuperUser, IsValidUser, IsSuperUserOrAppUser +from common.permissions import IsAppUser, IsOrgAdmin, IsValidUser, IsOrgAdminOrAppUser from users.models import User, UserGroup diff --git a/apps/audits/api.py b/apps/audits/api.py index 0d583d246..83c75e243 100644 --- a/apps/audits/api.py +++ b/apps/audits/api.py @@ -3,7 +3,7 @@ from rest_framework import viewsets -from common.permissions import IsSuperUserOrAppUser +from common.permissions import IsOrgAdminOrAppUser from .models import FTPLog from .serializers import FTPLogSerializer @@ -11,4 +11,4 @@ from .serializers import FTPLogSerializer class FTPLogViewSet(viewsets.ModelViewSet): queryset = FTPLog.objects.all() serializer_class = FTPLogSerializer - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) diff --git a/apps/common/api.py b/apps/common/api.py index 63ed9723d..0f440b7ab 100644 --- a/apps/common/api.py +++ b/apps/common/api.py @@ -8,12 +8,12 @@ from django.core.mail import get_connection, send_mail from django.utils.translation import ugettext_lazy as _ from django.conf import settings -from .permissions import IsSuperUser +from .permissions import IsOrgAdmin from .serializers import MailTestSerializer, LDAPTestSerializer class MailTestingAPI(APIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = MailTestSerializer success_message = _("Test mail sent to {}, please check") @@ -37,7 +37,7 @@ class MailTestingAPI(APIView): class LDAPTestingAPI(APIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = LDAPTestSerializer success_message = _("Test ldap success") diff --git a/apps/common/mixins.py b/apps/common/mixins.py index 1973eaa8f..a287391c9 100644 --- a/apps/common/mixins.py +++ b/apps/common/mixins.py @@ -6,7 +6,6 @@ from django.utils import timezone from django.utils.translation import ugettext_lazy as _ - class NoDeleteQuerySet(models.query.QuerySet): def delete(self): diff --git a/apps/common/permissions.py b/apps/common/permissions.py index 85a10b228..5868429c3 100644 --- a/apps/common/permissions.py +++ b/apps/common/permissions.py @@ -23,29 +23,29 @@ class IsAppUser(IsValidUser): and request.user.is_app -class IsSuperUser(IsValidUser): +class IsOrgAdmin(IsValidUser): """Allows access only to superuser""" def has_permission(self, request, view): - return super(IsSuperUser, self).has_permission(request, view) \ - and request.user.is_superuser + return super(IsOrgAdmin, self).has_permission(request, view) \ + and current_org.can_admin_by(request.user) -class IsSuperUserOrAppUser(IsValidUser): +class IsOrgAdminOrAppUser(IsValidUser): """Allows access between superuser and app user""" def has_permission(self, request, view): - return super(IsSuperUserOrAppUser, self).has_permission(request, view) \ - and (request.user.is_superuser or request.user.is_app) + return super(IsOrgAdminOrAppUser, self).has_permission(request, view) \ + and (current_org.can_admin_by(request.user) or request.user.is_app) -class IsSuperUserOrAppUserOrUserReadonly(IsSuperUserOrAppUser): +class IsOrgAdminOrAppUserOrUserReadonly(IsOrgAdminOrAppUser): def has_permission(self, request, view): if IsValidUser.has_permission(self, request, view) \ and request.method in permissions.SAFE_METHODS: return True else: - return IsSuperUserOrAppUser.has_permission(self, request, view) + return IsOrgAdminOrAppUser.has_permission(self, request, view) class IsCurrentUserOrReadOnly(permissions.BasePermission): @@ -59,7 +59,7 @@ class AdminUserRequiredMixin(UserPassesTestMixin): def test_func(self): if not self.request.user.is_authenticated: return False - elif not self.request.user: + elif not current_org.can_admin_by(self.request.user): self.raise_exception = True return False return True diff --git a/apps/common/views.py b/apps/common/views.py index fd5acb502..2b1fbc8ee 100644 --- a/apps/common/views.py +++ b/apps/common/views.py @@ -1,7 +1,5 @@ - -from django.core.cache import cache -from django.views.generic import TemplateView, View, DetailView -from django.shortcuts import render, redirect, Http404, reverse +from django.views.generic import TemplateView +from django.shortcuts import render, redirect from django.contrib import messages from django.utils.translation import ugettext as _ from django.conf import settings diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index 77a37839d..37246fa16 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -291,7 +291,7 @@ REST_FRAMEWORK = { # Use Django's standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users. 'DEFAULT_PERMISSION_CLASSES': ( - 'users.permissions.IsSuperUser', + 'common.permissions.IsOrgAdmin', ), 'DEFAULT_AUTHENTICATION_CLASSES': ( 'users.authentication.AccessKeyAuthentication', diff --git a/apps/ops/api.py b/apps/ops/api.py index 35c9b8dc5..ff8e71795 100644 --- a/apps/ops/api.py +++ b/apps/ops/api.py @@ -8,7 +8,7 @@ from django.utils.translation import ugettext as _ from rest_framework import viewsets, generics from rest_framework.views import Response -from .hands import IsSuperUser +from common.permissions import IsOrgAdmin from .models import Task, AdHoc, AdHocRunHistory, CeleryTask from .serializers import TaskSerializer, AdHocSerializer, \ AdHocRunHistorySerializer @@ -18,13 +18,13 @@ from .tasks import run_ansible_task class TaskViewSet(viewsets.ModelViewSet): queryset = Task.objects.all() serializer_class = TaskSerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) class TaskRun(generics.RetrieveAPIView): queryset = Task.objects.all() serializer_class = TaskViewSet - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) def retrieve(self, request, *args, **kwargs): task = self.get_object() @@ -35,7 +35,7 @@ class TaskRun(generics.RetrieveAPIView): class AdHocViewSet(viewsets.ModelViewSet): queryset = AdHoc.objects.all() serializer_class = AdHocSerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) def get_queryset(self): task_id = self.request.query_params.get('task') @@ -48,7 +48,7 @@ class AdHocViewSet(viewsets.ModelViewSet): class AdHocRunHistorySet(viewsets.ModelViewSet): queryset = AdHocRunHistory.objects.all() serializer_class = AdHocRunHistorySerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) def get_queryset(self): task_id = self.request.query_params.get('task') @@ -65,7 +65,7 @@ class AdHocRunHistorySet(viewsets.ModelViewSet): class CeleryTaskLogApi(generics.RetrieveAPIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) buff_size = 1024 * 10 end = False queryset = CeleryTask.objects.all() diff --git a/apps/ops/hands.py b/apps/ops/hands.py index 5ecf40d43..3e0d2fd0f 100644 --- a/apps/ops/hands.py +++ b/apps/ops/hands.py @@ -1,4 +1,2 @@ # ~*~ coding: utf-8 ~*~ -from users.permissions import IsSuperUser -from common.permissions import AdminUserRequiredMixin \ No newline at end of file diff --git a/apps/perms/api.py b/apps/perms/api.py index 40366a19b..8b2e08fc5 100644 --- a/apps/perms/api.py +++ b/apps/perms/api.py @@ -7,7 +7,7 @@ from rest_framework.generics import ListAPIView, get_object_or_404, RetrieveUpda from rest_framework import viewsets from common.utils import set_or_append_attr_bulk, get_object_or_none -from users.permissions import IsValidUser, IsSuperUser, IsSuperUserOrAppUser +from common.permissions import IsValidUser, IsOrgAdmin, IsOrgAdminOrAppUser from .utils import AssetPermissionUtil from .models import AssetPermission from .hands import AssetGrantedSerializer, User, UserGroup, Asset, Node, \ @@ -21,7 +21,7 @@ class AssetPermissionViewSet(viewsets.ModelViewSet): """ queryset = AssetPermission.objects.all() serializer_class = serializers.AssetPermissionCreateUpdateSerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) def get_serializer_class(self): if self.action in ("list", 'retrieve'): @@ -58,7 +58,7 @@ class UserGrantedAssetsApi(ListAPIView): """ 用户授权的所有资产 """ - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) serializer_class = AssetGrantedSerializer def get_queryset(self): @@ -87,7 +87,7 @@ class UserGrantedAssetsApi(ListAPIView): class UserGrantedNodesApi(ListAPIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = NodeSerializer def get_queryset(self): @@ -107,7 +107,7 @@ class UserGrantedNodesApi(ListAPIView): class UserGrantedNodesWithAssetsApi(ListAPIView): - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) serializer_class = NodeGrantedSerializer def get_queryset(self): @@ -139,7 +139,7 @@ class UserGrantedNodesWithAssetsApi(ListAPIView): class UserGrantedNodeAssetsApi(ListAPIView): - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) serializer_class = AssetGrantedSerializer def get_queryset(self): @@ -165,7 +165,7 @@ class UserGrantedNodeAssetsApi(ListAPIView): class UserGroupGrantedAssetsApi(ListAPIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = AssetGrantedSerializer def get_queryset(self): @@ -185,7 +185,7 @@ class UserGroupGrantedAssetsApi(ListAPIView): class UserGroupGrantedNodesApi(ListAPIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = NodeSerializer def get_queryset(self): @@ -201,7 +201,7 @@ class UserGroupGrantedNodesApi(ListAPIView): class UserGroupGrantedNodesWithAssetsApi(ListAPIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = NodeGrantedSerializer def get_queryset(self): @@ -224,7 +224,7 @@ class UserGroupGrantedNodesWithAssetsApi(ListAPIView): class UserGroupGrantedNodeAssetsApi(ListAPIView): - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) serializer_class = AssetGrantedSerializer def get_queryset(self): @@ -242,7 +242,7 @@ class UserGroupGrantedNodeAssetsApi(ListAPIView): class ValidateUserAssetPermissionView(APIView): - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) @staticmethod def get(request): @@ -266,7 +266,7 @@ class AssetPermissionRemoveUserApi(RetrieveUpdateAPIView): """ 将用户从授权中移除,Detail页面会调用 """ - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = serializers.AssetPermissionUpdateUserSerializer queryset = AssetPermission.objects.all() @@ -283,7 +283,7 @@ class AssetPermissionRemoveUserApi(RetrieveUpdateAPIView): class AssetPermissionAddUserApi(RetrieveUpdateAPIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = serializers.AssetPermissionUpdateUserSerializer queryset = AssetPermission.objects.all() @@ -303,7 +303,7 @@ class AssetPermissionRemoveAssetApi(RetrieveUpdateAPIView): """ 将用户从授权中移除,Detail页面会调用 """ - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = serializers.AssetPermissionUpdateAssetSerializer queryset = AssetPermission.objects.all() @@ -320,7 +320,7 @@ class AssetPermissionRemoveAssetApi(RetrieveUpdateAPIView): class AssetPermissionAddAssetApi(RetrieveUpdateAPIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) serializer_class = serializers.AssetPermissionUpdateAssetSerializer queryset = AssetPermission.objects.all() diff --git a/apps/terminal/api.py b/apps/terminal/api.py index f5c76a73f..75d20702b 100644 --- a/apps/terminal/api.py +++ b/apps/terminal/api.py @@ -24,8 +24,8 @@ from common.utils import get_object_or_none from .models import Terminal, Status, Session, Task from .serializers import TerminalSerializer, StatusSerializer, \ SessionSerializer, TaskSerializer, ReplaySerializer -from .hands import IsSuperUserOrAppUser, IsAppUser, \ - IsSuperUserOrAppUserOrUserReadonly +from common.permissions import IsOrgAdmin, IsAppUser, IsOrgAdminOrAppUser, \ + IsOrgAdminOrAppUserOrUserReadonly from .backends import get_command_storage, get_multi_command_storage, \ SessionCommandSerializer @@ -35,7 +35,7 @@ logger = logging.getLogger(__file__) class TerminalViewSet(viewsets.ModelViewSet): queryset = Terminal.objects.filter(is_deleted=False) serializer_class = TerminalSerializer - permission_classes = (IsSuperUserOrAppUserOrUserReadonly,) + permission_classes = (IsOrgAdminOrAppUserOrUserReadonly,) def create(self, request, *args, **kwargs): name = request.data.get('name') @@ -104,7 +104,7 @@ class TerminalTokenApi(APIView): class StatusViewSet(viewsets.ModelViewSet): queryset = Status.objects.all() serializer_class = StatusSerializer - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) session_serializer_class = SessionSerializer task_serializer_class = TaskSerializer @@ -176,7 +176,7 @@ class StatusViewSet(viewsets.ModelViewSet): class SessionViewSet(viewsets.ModelViewSet): queryset = Session.objects.all() serializer_class = SessionSerializer - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) def get_queryset(self): terminal_id = self.kwargs.get("terminal", None) @@ -194,11 +194,11 @@ class SessionViewSet(viewsets.ModelViewSet): class TaskViewSet(BulkModelViewSet): queryset = Task.objects.all() serializer_class = TaskSerializer - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) class KillSessionAPI(APIView): - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) model = Task def post(self, request, *args, **kwargs): @@ -230,7 +230,7 @@ class CommandViewSet(viewsets.ViewSet): command_store = get_command_storage() multi_command_storage = get_multi_command_storage() serializer_class = SessionCommandSerializer - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) def get_queryset(self): self.command_store.filter(**dict(self.request.query_params)) @@ -256,7 +256,7 @@ class CommandViewSet(viewsets.ViewSet): class SessionReplayViewSet(viewsets.ViewSet): serializer_class = ReplaySerializer - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) session = None upload_to = 'replay' # 仅添加到本地存储中 @@ -341,7 +341,7 @@ class SessionReplayViewSet(viewsets.ViewSet): class SessionReplayV2ViewSet(SessionReplayViewSet): serializer_class = ReplaySerializer - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) session = None def retrieve(self, request, *args, **kwargs): diff --git a/apps/terminal/hands.py b/apps/terminal/hands.py index f936c9dc3..71167b09c 100644 --- a/apps/terminal/hands.py +++ b/apps/terminal/hands.py @@ -2,6 +2,3 @@ # from users.models import User -from users.permissions import IsSuperUserOrAppUser, IsAppUser, \ - IsSuperUserOrAppUserOrUserReadonly -from common.permissions import AdminUserRequiredMixin \ No newline at end of file diff --git a/apps/users/api.py b/apps/users/api.py index fce64e69c..f270f0161 100644 --- a/apps/users/api.py +++ b/apps/users/api.py @@ -16,12 +16,10 @@ from .serializers import UserSerializer, UserGroupSerializer, \ UserUpdateGroupSerializer, ChangeUserPasswordSerializer from .tasks import write_login_log_async from .models import User, UserGroup, LoginLog -from .permissions import IsSuperUser, IsValidUser, IsCurrentUserOrReadOnly, \ - IsSuperUserOrAppUser from .utils import check_user_valid, generate_token, get_login_ip, \ check_otp_code, set_user_login_failed_count_to_cache, is_block_login from orgs.utils import current_org -from orgs.mixins import OrgViewGenericMixin +from common.permissions import IsOrgAdmin, IsCurrentUserOrReadOnly, IsOrgAdminOrAppUser from common.mixins import IDInFilterMixin from common.utils import get_logger @@ -32,7 +30,7 @@ logger = get_logger(__name__) class UserViewSet(IDInFilterMixin, BulkModelViewSet): queryset = User.objects.exclude(role="App") serializer_class = UserSerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) filter_fields = ('username', 'email', 'name', 'id') def get_queryset(self): @@ -43,12 +41,12 @@ class UserViewSet(IDInFilterMixin, BulkModelViewSet): def get_permissions(self): if self.action == "retrieve": - self.permission_classes = (IsSuperUserOrAppUser,) + self.permission_classes = (IsOrgAdminOrAppUser,) return super().get_permissions() class ChangeUserPasswordApi(generics.RetrieveUpdateAPIView): - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) queryset = User.objects.all() serializer_class = ChangeUserPasswordSerializer @@ -61,7 +59,7 @@ class ChangeUserPasswordApi(generics.RetrieveUpdateAPIView): class UserUpdateGroupApi(generics.RetrieveUpdateAPIView): queryset = User.objects.all() serializer_class = UserUpdateGroupSerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) class UserResetPasswordApi(generics.UpdateAPIView): @@ -106,13 +104,13 @@ class UserUpdatePKApi(generics.UpdateAPIView): class UserGroupViewSet(BulkModelViewSet): queryset = UserGroup.objects.all() serializer_class = UserGroupSerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) class UserGroupUpdateUserApi(generics.RetrieveUpdateAPIView): queryset = UserGroup.objects.all() serializer_class = UserGroupUpdateMemeberSerializer - permission_classes = (IsSuperUser,) + permission_classes = (IsOrgAdmin,) class UserToken(APIView): @@ -288,7 +286,7 @@ class UserAuthApi(APIView): class UserConnectionTokenApi(APIView): - permission_classes = (IsSuperUserOrAppUser,) + permission_classes = (IsOrgAdminOrAppUser,) def post(self, request): user_id = request.data.get('user', '') diff --git a/apps/users/permissions.py b/apps/users/permissions.py deleted file mode 100644 index 1b38aa1a8..000000000 --- a/apps/users/permissions.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from rest_framework import permissions - - -class IsValidUser(permissions.IsAuthenticated, permissions.BasePermission): - """Allows access to valid user, is active and not expired""" - - def has_permission(self, request, view): - return super(IsValidUser, self).has_permission(request, view) \ - and request.user.is_valid - - -class IsAppUser(IsValidUser): - """Allows access only to app user """ - - def has_permission(self, request, view): - return super(IsAppUser, self).has_permission(request, view) \ - and request.user.is_app - - -class IsSuperUser(IsValidUser): - """Allows access only to superuser""" - - def has_permission(self, request, view): - return super(IsSuperUser, self).has_permission(request, view) \ - and request.user.is_superuser - - -class IsSuperUserOrAppUser(IsValidUser): - """Allows access between superuser and app user""" - - def has_permission(self, request, view): - return super(IsSuperUserOrAppUser, self).has_permission(request, view) \ - and (request.user.is_superuser or request.user.is_app) - - -class IsSuperUserOrAppUserOrUserReadonly(IsSuperUserOrAppUser): - def has_permission(self, request, view): - if IsValidUser.has_permission(self, request, view) \ - and request.method in permissions.SAFE_METHODS: - return True - else: - return IsSuperUserOrAppUser.has_permission(self, request, view) - - -class IsCurrentUserOrReadOnly(permissions.BasePermission): - def has_object_permission(self, request, view, obj): - if request.method in permissions.SAFE_METHODS: - return True - return obj == request.user